Answers.Body: <p>As far as I can tell by looking at the source code and searching <a href="https://craftcms.com/docs/3.x/extend/events.html#event-code-generator" rel="nofollow noreferrer">the Events reference</a>, Craft doesn't dispatch any relevant events that could be used to make the Webhooks plugin trigger a POST request if/when there are updates available.</p>
  <p>You could <a href="https://github.com/craftcms/cms/discussions/categories/ideas" rel="nofollow noreferrer">submit a feature request</a> for P&amp;T to add such an event.</p>
  <p>In lieu of a core event, it's probably possible to hack this in yourself by creating a <a href="https://craftcms.com/docs/3.x/extend/module-guide.html" rel="nofollow noreferrer">custom module</a>. The module will have to check if there are updates available, and trigger a custom event if there are. You could then listen for that custom event the Webhooks plugin, same as you would a core event.</p>
  <p>Since you can't really hook into the core updates logic and only fire it at the exact time Craft detects available updates, you'll probably need to add this logic so that it runs on every request, while avoiding that your custom event (and in turn, the webhook) fires on every request as well, in the case that there are updates available. A decent workaround to that problem is using the data cache to essentially cache the output from <code>Craft::$app-&gt;getUpdates()-&gt;getTotalAvailableUpdates()</code>, and only trigger the event whenever that cache doesn't exist or is expired.</p>
  <p>Building off of <a href="https://craftcms.com/docs/3.x/extend/module-guide.html" rel="nofollow noreferrer">the custom module example in the docs</a>, here's how a hack like that could look:</p>
  <pre class="lang-php prettyprint-override"><code>use craft\helpers\ConfigHelper;
  use craft\services\Plugins;
  use yii\base\Event;
  
  public function init()
  {
      // To avoid the custom event being triggered too soon, wrap everything in a Plugins::EVENT_AFTER_LOAD_PLUGINS event listener 
      Event::on(
          Plugins::class,
          Plugins::EVENT_AFTER_LOAD_PLUGINS,
          [$this, 'doUpdateCheck']
      );
  }
  
  // Note the use of Craft::$app-&gt;getCache()-&gt;getOrSet to avoid this logic being executed on every request
  public function doUpdateCheck()
  {
      
      Craft::$app-&gt;getCache()-&gt;getOrSet('available_updates', function () {
  
          if (!Craft::$app-&gt;getUpdates()-&gt;getIsUpdateInfoCached()) {
              // Craft hasn't cached any update info yet; return false to not cache the output (which will make the check run again on the next request)
              return false;
          }
      
          // Get the total number of available updates
          $numUpdates = Craft::$app-&gt;getUpdates()-&gt;getTotalAvailableUpdates();  
      
          if ($numUpdates) {
              // There are updates available; trigger a custom &quot;updatesAreAvailable&quot; event
              $this-&gt;trigger('updatesAreAvailable');
          }
  
          // Return the number of available updates so it can be cached
          return $numUpdates;
  
      }, ConfigHelper::durationInSeconds('P1D')); // Only do this once a day!
  }
  </code></pre>
  <p>For the Webhooks part, with the above you should be able to use the custom event event to trigger the POST request by adding your module's class (i.e. something like <code>modules\foobar\Module</code>) for the &quot;Sender class setting, and <code>updatesAreAvailable</code> for the &quot;Event name&quot;.</p>
  <p>The example caches the output from the <code>doUpdateCheck()</code> method for a day, but you can of course use a different cache duration (<code>'PT1H'</code> to cache it for an hour, for example). This will prevent the event from triggering on every single event, but obviously since this just uses the data cache, the callable will run whenever the entire data cache is cleared (some people like to do this in their deploy scripts). In other words, the event could fire more often than the cache duration set, and the logic on the other end of the webhook should probably account for that.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-03-24T07:48:01.900Z
Answers.Text: Thanks for this answer and I very much appreciate the time you took for this.
Answers.UserDisplayName: vanburen
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-03-21T12:51:02.343Z
Answers.LastActivityDate: 2022-03-22T08:25:23.390Z
Answers.LastEditDate: 2022-03-22T08:25:23.390Z
Answers.UserDisplayName: Mats Mikkel Rummelhoff
Body: <p>Is it possible with the <a href="https://github.com/craftcms/webhooks" rel="nofollow noreferrer">Webhooks</a> plugin to trigger a POST request anytime Craft has updates available? I thought the <strong>Updates</strong> <a href="https://docs.craftcms.com/api/v3/craft-services-updates.html" rel="nofollow noreferrer">Class</a> would be the place to start but that does not appear to be correct.</p>
  <p>Any insight into this is appreciated.</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-03-22T18:10:20.703Z
Comments.Text: Do you need this information inside Craft, or is Craft just acting as a proxy for the information? Packagist provides RSS feeds for packages (i.e. `https://packagist.org/feeds/package.craftcms/cms.rss`), so this might be significantly easier with a service like IFTTT. 
Comments.UserDisplayName: August Miller
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-03-24T07:49:03.153Z
Comments.Text: @AugustMiller Thanks much for the very useful info, def wasn't aware this.
Comments.UserDisplayName: vanburen
Tags: <craft3><updating><plugin-webhooks>
Title: Trigger Webhook when Updates are Available
ThreadText: # Trigger Webhook when Updates are Available
  
  (Asked by: username_0 on 2022-03-16)
  
  Is it possible with the [Webhooks](https://github.com/craftcms/webhooks) plugin to trigger a POST request anytime Craft has updates available? I thought the **Updates** [Class](https://docs.craftcms.com/api/v3/craft-services-updates.html) would be the place to start but that does not appear to be correct.
  
  Any insight into this is appreciated.
  
  **Tags:** craft3, updating, plugin-webhooks
  
  > **Comments:**
  > **username_1**: Do you need this information inside Craft, or is Craft just acting as a proxy for the information? Packagist provides RSS feeds for packages (i.e. `https://packagist.org/feeds/package.craftcms/cms.rss`), so this might be significantly easier with a service like IFTTT.   
  > **username_0**: @username_1 Thanks much for the very useful info, def wasn't aware this.  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_2 on 2022-03-21. Score: 4 | Accepted answer
  
  As far as I can tell by looking at the source code and searching [the Events reference](https://craftcms.com/docs/3.x/extend/events.html#event-code-generator), Craft doesn't dispatch any relevant events that could be used to make the Webhooks plugin trigger a POST request if/when there are updates available.
  
  You could [submit a feature request](https://github.com/craftcms/cms/discussions/categories/ideas) for P&T to add such an event.
  
  In lieu of a core event, it's probably possible to hack this in yourself by creating a [custom module](https://craftcms.com/docs/3.x/extend/module-guide.html). The module will have to check if there are updates available, and trigger a custom event if there are. You could then listen for that custom event the Webhooks plugin, same as you would a core event.
  
  Since you can't really hook into the core updates logic and only fire it at the exact time Craft detects available updates, you'll probably need to add this logic so that it runs on every request, while avoiding that your custom event (and in turn, the webhook) fires on every request as well, in the case that there are updates available. A decent workaround to that problem is using the data cache to essentially cache the output from `Craft::$app->getUpdates()->getTotalAvailableUpdates()`, and only trigger the event whenever that cache doesn't exist or is expired.
  
  Building off of [the custom module example in the docs](https://craftcms.com/docs/3.x/extend/module-guide.html), here's how a hack like that could look:
  
  ```php
  use craft\helpers\ConfigHelper;
  use craft\services\Plugins;
  use yii\base\Event;
  
  public function init()
  {
      // To avoid the custom event being triggered too soon, wrap everything in a Plugins::EVENT_AFTER_LOAD_PLUGINS event listener 
      Event::on(
          Plugins::class,
          Plugins::EVENT_AFTER_LOAD_PLUGINS,
          [$this, 'doUpdateCheck']
      );
  }
  
  // Note the use of Craft::$app->getCache()->getOrSet to avoid this logic being executed on every request
  public function doUpdateCheck()
  {
      
      Craft::$app->getCache()->getOrSet('available_updates', function () {
  
          if (!Craft::$app->getUpdates()->getIsUpdateInfoCached()) {
              // Craft hasn't cached any update info yet; return false to not cache the output (which will make the check run again on the next request)
              return false;
          }
      
          // Get the total number of available updates
          $numUpdates = Craft::$app->getUpdates()->getTotalAvailableUpdates();  
      
          if ($numUpdates) {
              // There are updates available; trigger a custom "updatesAreAvailable" event
              $this->trigger('updatesAreAvailable');
          }
  
          // Return the number of available updates so it can be cached
          return $numUpdates;
  
      }, ConfigHelper::durationInSeconds('P1D')); // Only do this once a day!
  }
  
  ```
  
  For the Webhooks part, with the above you should be able to use the custom event event to trigger the POST request by adding your module's class (i.e. something like `modules\foobar\Module`) for the "Sender class setting, and `updatesAreAvailable` for the "Event name".
  
  The example caches the output from the `doUpdateCheck()` method for a day, but you can of course use a different cache duration (`'PT1H'` to cache it for an hour, for example). This will prevent the event from triggering on every single event, but obviously since this just uses the data cache, the callable will run whenever the entire data cache is cleared (some people like to do this in their deploy scripts). In other words, the event could fire more often than the cache duration set, and the logic on the other end of the webhook should probably account for that.
  
  > **Comments:**
  > **username_0**: Thanks for this answer and I very much appreciate the time you took for this.  
  
  ---
  
  