[PLUGIN][WebHooks] Add WebHooks plugin, which allows for sending a POST request to an external resource when a notification or a follow occurs
This commit is contained in:
94
plugins/WebHooks/WebHooks.php
Normal file
94
plugins/WebHooks/WebHooks.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
// {{{ License
|
||||
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||
//
|
||||
// GNU social is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// GNU social is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||
// }}}
|
||||
|
||||
namespace Plugin\WebHooks;
|
||||
|
||||
use App\Core\DB\DB;
|
||||
use App\Core\Event;
|
||||
use App\Core\HTTPClient;
|
||||
use App\Core\Log;
|
||||
use App\Core\Modules\Plugin;
|
||||
use App\Core\Queue\Queue;
|
||||
use App\Core\Router\RouteLoader;
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\Actor;
|
||||
use App\Util\Exception\ServerException;
|
||||
use Functional as F;
|
||||
use Plugin\WebHooks\Controller as C;
|
||||
use Plugin\WebHooks\Entity as E;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class WebHooks extends Plugin
|
||||
{
|
||||
public const controller_route = 'webhook';
|
||||
|
||||
public function onAddRoute(RouteLoader $r)
|
||||
{
|
||||
$r->connect(self::controller_route, '/webhook-settings', C\WebHooks::class);
|
||||
}
|
||||
|
||||
public function onPopulateSettingsTabs(Request $request, string $section, array &$tabs): bool
|
||||
{
|
||||
if ($section === 'others') {
|
||||
$tabs[] = [
|
||||
'title' => 'Web Hooks',
|
||||
'desc' => 'Add hooks that run when an internal event occurs, allowing your third party resource to react',
|
||||
'id' => 'settings-webhooks',
|
||||
'controller' => C\WebHooks::setup(),
|
||||
];
|
||||
}
|
||||
return Event::next;
|
||||
}
|
||||
|
||||
public function onNewNotificationEnd(Actor $sender, Activity $activity, array $effective_targets, ?string $reason)
|
||||
{
|
||||
foreach ($effective_targets as $actor) {
|
||||
$target = DB::findOneBy(E\WebHook::class, ['actor_id' => $actor->getId(), 'event' => 'notifications'], return_null: true)?->getTarget();
|
||||
if (!\is_null($target)) {
|
||||
Queue::enqueue(['notifications', $target, $actor, [$sender, $activity, $effective_targets, $reason]], queue: 'webhook');
|
||||
}
|
||||
}
|
||||
return Event::next;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<Actor $sender, Activity $activity, array $effective_targets, ?string $reason> $args
|
||||
*/
|
||||
public function onQueueWebhook(string $type, string $target, Actor $actor, array $args)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'notifications':
|
||||
[$sender, $activity, $targets, $reason] = $args;
|
||||
$data = [
|
||||
'type' => 'notification',
|
||||
'actor' => ['id' => $sender->getId(), 'nickname' => $sender->getNickname()],
|
||||
'activity' => ['id' => $activity->getId(), 'object_type' => $activity->getObjectType(), 'object_id' => $activity->getObjectId(), 'verb' => $activity->getVerb()],
|
||||
'targets' => F\map(array_values($targets), fn (Actor $actor) => ['id' => $actor->getId(), 'nickname' => $actor->getNickname()]),
|
||||
'reason' => $reason,
|
||||
];
|
||||
Log::debug("WebHook: POST {$target} on behalf of actor {$actor->getId()} ({$actor->getNickname()})", [$data, ['json' => json_encode($data)]]);
|
||||
HTTPClient::post($target, ['json' => json_encode($data)]);
|
||||
return Event::stop;
|
||||
default:
|
||||
throw new ServerException("Webhook notification handler for event {$type} not implemented");
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user