<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>

CC BY-SA 4.0
2022-03-24T07:48:01.900Z
Thanks for this answer and I very much appreciate the time you took for this.
vanburen
CC BY-SA 4.0
2022-03-21T12:51:02.343Z
2022-03-22T08:25:23.390Z
2022-03-22T08:25:23.390Z
Mats Mikkel Rummelhoff
<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>

CC BY-SA 4.0
2022-03-22T18:10:20.703Z
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. 
August Miller
CC BY-SA 4.0
2022-03-24T07:49:03.153Z
@AugustMiller Thanks much for the very useful info, def wasn't aware this.
vanburen
<craft3><updating><plugin-webhooks>
Trigger Webhook when Updates are Available
# 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**: @AugustMiller 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, 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 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. 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, here's how a hack like that could look:
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.  

---

