Retire Twitter and GA V3 webhooks.
This commit is contained in:
parent
6eeb864ac6
commit
fd4876e5aa
|
@ -11,6 +11,10 @@ release channel, you can take advantage of these new features and fixes.
|
|||
|
||||
## Code Quality/Technical Changes
|
||||
|
||||
- The Google Analytics V3 and Twitter (now X) web hooks have been retired and are no longer supported. Google Analytics
|
||||
has removed support for V3 properties entirely; we recommend switching to Analytics V4. Twitter has deprecated version
|
||||
1 of their API in favor of version 2, which is not readily accessible to applications like ours.
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
---
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
"gettext/gettext": "^5",
|
||||
"gettext/php-scanner": "^1.3",
|
||||
"guzzlehttp/guzzle": "^7.0",
|
||||
"guzzlehttp/oauth-subscriber": "^0.6.0",
|
||||
"intervention/image": "^2.6",
|
||||
"james-heinrich/getid3": "v2.0.0-beta5",
|
||||
"league/csv": "^9.6",
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "fe3a67cfc6f90897593aef83f8a54767",
|
||||
"content-hash": "cc878a9297f83d6f4b49cbf1f17ddd7f",
|
||||
"packages": [
|
||||
{
|
||||
"name": "aws/aws-crt-php",
|
||||
|
@ -2546,65 +2546,6 @@
|
|||
],
|
||||
"time": "2023-05-21T14:04:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/oauth-subscriber",
|
||||
"version": "0.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/oauth-subscriber.git",
|
||||
"reference": "8d6cab29f8397e5712d00a383eeead36108a3c1f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/oauth-subscriber/zipball/8d6cab29f8397e5712d00a383eeead36108a3c1f",
|
||||
"reference": "8d6cab29f8397e5712d00a383eeead36108a3c1f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"guzzlehttp/guzzle": "^6.5|^7.2",
|
||||
"guzzlehttp/psr7": "^1.7|^2.0",
|
||||
"php": ">=5.5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.0|^9.3.3"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-openssl": "Required to sign using RSA-SHA1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "0.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"GuzzleHttp\\Subscriber\\Oauth\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Michael Dowling",
|
||||
"email": "mtdowling@gmail.com",
|
||||
"homepage": "https://github.com/mtdowling"
|
||||
}
|
||||
],
|
||||
"description": "Guzzle OAuth 1.0 subscriber",
|
||||
"homepage": "http://guzzlephp.org/",
|
||||
"keywords": [
|
||||
"Guzzle",
|
||||
"oauth"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/guzzle/oauth-subscriber/issues",
|
||||
"source": "https://github.com/guzzle/oauth-subscriber/tree/0.6.0"
|
||||
},
|
||||
"time": "2021-07-13T12:01:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/promises",
|
||||
"version": "2.0.1",
|
||||
|
|
|
@ -77,9 +77,7 @@ export enum WebhookType {
|
|||
RadioDe = 'radiode',
|
||||
Discord = 'discord',
|
||||
Telegram = 'telegram',
|
||||
Twitter = 'twitter',
|
||||
Mastodon = 'mastodon',
|
||||
GoogleAnalyticsV3 = 'google_analytics',
|
||||
GoogleAnalyticsV4 = 'google_analytics_v4',
|
||||
MatomoAnalytics = 'matomo_analytics'
|
||||
}
|
||||
|
@ -112,18 +110,10 @@ export function useTypeDetails() {
|
|||
title: $gettext('Telegram Chat Message'),
|
||||
description: $gettext('Use the Telegram Bot API to send a message to a channel.')
|
||||
},
|
||||
[WebhookType.Twitter]: {
|
||||
title: $gettext('Twitter Post'),
|
||||
description: $gettext('Automatically send a tweet.')
|
||||
},
|
||||
[WebhookType.Mastodon]: {
|
||||
title: $gettext('Mastodon Post'),
|
||||
description: $gettext('Automatically publish to a Mastodon instance.')
|
||||
},
|
||||
[WebhookType.GoogleAnalyticsV3]: {
|
||||
title: $gettext('Google Analytics V3 Integration'),
|
||||
description: $gettext('Send stream listener details to Google Analytics.')
|
||||
},
|
||||
[WebhookType.GoogleAnalyticsV4]: {
|
||||
title: $gettext('Google Analytics V4 Integration'),
|
||||
description: $gettext('Send stream listener details to Google Analytics.')
|
||||
|
@ -139,7 +129,6 @@ export function getTriggers(type: WebhookType) {
|
|||
switch(type) {
|
||||
case WebhookType.TuneIn:
|
||||
case WebhookType.RadioDe:
|
||||
case WebhookType.GoogleAnalyticsV3:
|
||||
case WebhookType.GoogleAnalyticsV4:
|
||||
case WebhookType.MatomoAnalytics:
|
||||
return [];
|
||||
|
@ -150,7 +139,6 @@ export function getTriggers(type: WebhookType) {
|
|||
|
||||
case WebhookType.Discord:
|
||||
case WebhookType.Telegram:
|
||||
case WebhookType.Twitter:
|
||||
case WebhookType.Mastodon:
|
||||
default:
|
||||
return allTriggersExceptListeners;
|
||||
|
|
|
@ -20,24 +20,31 @@
|
|||
:fields="fields"
|
||||
:api-url="listUrl"
|
||||
>
|
||||
<template #cell(name)="row">
|
||||
<template #cell(name)="{item}">
|
||||
<div class="typography-subheading">
|
||||
{{ row.item.name }}
|
||||
{{ item.name }}
|
||||
</div>
|
||||
{{ getWebhookName(row.item.type) }}
|
||||
|
||||
<div
|
||||
v-if="!row.item.is_enabled"
|
||||
class="badge bg-danger"
|
||||
>
|
||||
{{ $gettext('Disabled') }}
|
||||
</div>
|
||||
</template>
|
||||
<template #cell(triggers)="row">
|
||||
<template v-if="row.item.triggers.length > 0">
|
||||
<template v-if="isWebhookSupported(item.type)">
|
||||
{{ getWebhookName(item.type) }}
|
||||
<div
|
||||
v-for="(name, index) in getTriggerNames(row.item.triggers)"
|
||||
:key="row.item.id+'_'+index"
|
||||
v-if="!item.is_enabled"
|
||||
class="badge bg-danger"
|
||||
>
|
||||
{{ $gettext('Disabled') }}
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{
|
||||
$gettext('This web hook is no longer supported. Removing it is recommended.')
|
||||
}}
|
||||
</template>
|
||||
</template>
|
||||
<template #cell(triggers)="{item}">
|
||||
<template v-if="isWebhookSupported(item.type) && item.triggers.length > 0">
|
||||
<div
|
||||
v-for="(name, index) in getTriggerNames(item.triggers)"
|
||||
:key="item.id+'_'+index"
|
||||
class="small"
|
||||
>
|
||||
{{ name }}
|
||||
|
@ -47,34 +54,36 @@
|
|||
|
||||
</template>
|
||||
</template>
|
||||
<template #cell(actions)="row">
|
||||
<template #cell(actions)="{item}">
|
||||
<div class="btn-group btn-group-sm">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary"
|
||||
@click="doEdit(row.item.links.self)"
|
||||
>
|
||||
{{ $gettext('Edit') }}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn"
|
||||
:class="getToggleVariant(row.item)"
|
||||
@click="doToggle(row.item.links.toggle)"
|
||||
>
|
||||
{{ langToggleButton(row.item) }}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-secondary"
|
||||
@click="doTest(row.item.links.test)"
|
||||
>
|
||||
{{ $gettext('Test') }}
|
||||
</button>
|
||||
<template v-if="isWebhookSupported(item.type)">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary"
|
||||
@click="doEdit(item.links.self)"
|
||||
>
|
||||
{{ $gettext('Edit') }}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn"
|
||||
:class="getToggleVariant(item)"
|
||||
@click="doToggle(item.links.toggle)"
|
||||
>
|
||||
{{ langToggleButton(item) }}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-secondary"
|
||||
@click="doTest(item.links.test)"
|
||||
>
|
||||
{{ $gettext('Test') }}
|
||||
</button>
|
||||
</template>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-danger"
|
||||
@click="doDelete(row.item.links.self)"
|
||||
@click="doDelete(item.links.self)"
|
||||
>
|
||||
{{ $gettext('Delete') }}
|
||||
</button>
|
||||
|
@ -140,6 +149,10 @@ const getToggleVariant = (record) => {
|
|||
: 'btn-success';
|
||||
};
|
||||
|
||||
const isWebhookSupported = (key) => {
|
||||
return (key in langTypeDetails);
|
||||
}
|
||||
|
||||
const getWebhookName = (key) => {
|
||||
return get(langTypeDetails, [key, 'title'], '');
|
||||
};
|
||||
|
|
|
@ -39,8 +39,6 @@ import Email from "./Form/Email.vue";
|
|||
import Tunein from "./Form/Tunein.vue";
|
||||
import Discord from "./Form/Discord.vue";
|
||||
import Telegram from "./Form/Telegram.vue";
|
||||
import Twitter from "./Form/Twitter.vue";
|
||||
import GoogleAnalyticsV3 from "./Form/GoogleAnalyticsV3.vue";
|
||||
import GoogleAnalyticsV4 from "./Form/GoogleAnalyticsV4.vue";
|
||||
import MatomoAnalytics from "./Form/MatomoAnalytics.vue";
|
||||
import Mastodon from "./Form/Mastodon.vue";
|
||||
|
@ -83,9 +81,7 @@ const webhookComponents = {
|
|||
[WebhookType.RadioDe]: RadioDe,
|
||||
[WebhookType.Discord]: Discord,
|
||||
[WebhookType.Telegram]: Telegram,
|
||||
[WebhookType.Twitter]: Twitter,
|
||||
[WebhookType.Mastodon]: Mastodon,
|
||||
[WebhookType.GoogleAnalyticsV3]: GoogleAnalyticsV3,
|
||||
[WebhookType.GoogleAnalyticsV4]: GoogleAnalyticsV4,
|
||||
[WebhookType.MatomoAnalytics]: MatomoAnalytics,
|
||||
};
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
<template>
|
||||
<tab
|
||||
:label="title"
|
||||
:item-header-class="tabClass"
|
||||
>
|
||||
<div class="row g-3">
|
||||
<form-group-field
|
||||
id="form_config_tracking_id"
|
||||
class="col-md-12"
|
||||
:field="v$.config.tracking_id"
|
||||
:label="$gettext('GA Property Tracking ID')"
|
||||
:description="$gettext('The property ID used to track live listeners.')"
|
||||
/>
|
||||
</div>
|
||||
</tab>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import FormGroupField from "~/components/Form/FormGroupField.vue";
|
||||
import {useVModel} from "@vueuse/core";
|
||||
import {useVuelidateOnFormTab} from "~/functions/useVuelidateOnFormTab";
|
||||
import {required} from "@vuelidate/validators";
|
||||
import Tab from "~/components/Common/Tab.vue";
|
||||
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
form: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:form']);
|
||||
const form = useVModel(props, 'form', emit);
|
||||
|
||||
const {v$, tabClass} = useVuelidateOnFormTab(
|
||||
{
|
||||
config: {
|
||||
tracking_id: {required}
|
||||
}
|
||||
},
|
||||
form,
|
||||
{
|
||||
config: {
|
||||
tracking_id: ''
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
|
@ -1,120 +0,0 @@
|
|||
<template>
|
||||
<tab
|
||||
:label="title"
|
||||
:item-header-class="tabClass"
|
||||
>
|
||||
<form-markup id="twitter_account_details">
|
||||
<template #label>
|
||||
{{ $gettext('Twitter Account Details') }}
|
||||
</template>
|
||||
|
||||
<p class="card-text">
|
||||
{{ $gettext('Steps for configuring a Twitter application:') }}
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
{{
|
||||
$gettext('Create a new app on the Twitter Applications site. Use this installation\'s base URL as the application URL.')
|
||||
}}
|
||||
<br>
|
||||
<a
|
||||
href="https://developer.twitter.com/en/apps"
|
||||
target="_blank"
|
||||
>
|
||||
{{ $gettext('Twitter Applications') }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
{{ $gettext('In the newly created application, click the "Keys and Access Tokens" tab.') }}
|
||||
</li>
|
||||
<li>
|
||||
{{ $gettext('At the bottom of the page, click "Create my access token".') }}
|
||||
</li>
|
||||
</ul>
|
||||
<p class="card-text">
|
||||
{{
|
||||
$gettext('Once these steps are completed, enter the information from the "Keys and Access Tokens" page into the fields below.')
|
||||
}}
|
||||
</p>
|
||||
</form-markup>
|
||||
|
||||
<div class="row g-3 mb-3">
|
||||
<form-group-field
|
||||
id="form_config_consumer_key"
|
||||
class="col-md-6"
|
||||
:field="v$.config.consumer_key"
|
||||
:label="$gettext('Consumer Key (API Key)')"
|
||||
/>
|
||||
|
||||
<form-group-field
|
||||
id="form_config_consumer_secret"
|
||||
class="col-md-6"
|
||||
:field="v$.config.consumer_secret"
|
||||
:label="$gettext('Consumer Secret (API Secret)')"
|
||||
/>
|
||||
|
||||
<form-group-field
|
||||
id="form_config_token"
|
||||
class="col-md-6"
|
||||
:field="v$.config.token"
|
||||
:label="$gettext('Access Token')"
|
||||
/>
|
||||
|
||||
<form-group-field
|
||||
id="form_config_token_secret"
|
||||
class="col-md-6"
|
||||
:field="v$.config.token_secret"
|
||||
:label="$gettext('Access Token Secret')"
|
||||
/>
|
||||
|
||||
<common-rate-limit-fields v-model:form="form" />
|
||||
</div>
|
||||
|
||||
<common-social-post-fields v-model:form="form" />
|
||||
</tab>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import FormGroupField from "~/components/Form/FormGroupField.vue";
|
||||
import CommonRateLimitFields from "./Common/RateLimitFields.vue";
|
||||
import CommonSocialPostFields from "./Common/SocialPostFields.vue";
|
||||
import FormMarkup from "~/components/Form/FormMarkup.vue";
|
||||
import {useVModel} from "@vueuse/core";
|
||||
import {useVuelidateOnFormTab} from "~/functions/useVuelidateOnFormTab";
|
||||
import {required} from "@vuelidate/validators";
|
||||
import Tab from "~/components/Common/Tab.vue";
|
||||
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
form: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:form']);
|
||||
const form = useVModel(props, 'form', emit);
|
||||
|
||||
const {v$, tabClass} = useVuelidateOnFormTab(
|
||||
{
|
||||
config: {
|
||||
consumer_key: {required},
|
||||
consumer_secret: {required},
|
||||
token: {required},
|
||||
token_secret: {required},
|
||||
}
|
||||
},
|
||||
form,
|
||||
{
|
||||
config: {
|
||||
consumer_key: '',
|
||||
consumer_secret: '',
|
||||
token: '',
|
||||
token_secret: '',
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
|
@ -15,8 +15,7 @@
|
|||
:types="buildTypeInfo([
|
||||
WebhookType.Discord,
|
||||
WebhookType.Telegram,
|
||||
WebhookType.Mastodon,
|
||||
WebhookType.Twitter
|
||||
WebhookType.Mastodon
|
||||
])"
|
||||
@select="selectType"
|
||||
/>
|
||||
|
@ -34,7 +33,6 @@
|
|||
<type-select-section
|
||||
:title="$gettext('Analytics')"
|
||||
:types="buildTypeInfo([
|
||||
WebhookType.GoogleAnalyticsV3,
|
||||
WebhookType.GoogleAnalyticsV4,
|
||||
WebhookType.MatomoAnalytics
|
||||
])"
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Webhook\Connector;
|
||||
|
||||
use App\Entity\Api\NowPlaying\NowPlaying;
|
||||
use App\Entity\Station;
|
||||
use App\Entity\StationWebhook;
|
||||
use TheIconic\Tracking\GoogleAnalytics\Analytics;
|
||||
use TheIconic\Tracking\GoogleAnalytics\Network\HttpClient;
|
||||
|
||||
final class GoogleAnalyticsV3 extends AbstractGoogleAnalyticsConnector
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function dispatch(
|
||||
Station $station,
|
||||
StationWebhook $webhook,
|
||||
NowPlaying $np,
|
||||
array $triggers
|
||||
): void {
|
||||
$config = $webhook->getConfig();
|
||||
if (empty($config['tracking_id'])) {
|
||||
throw $this->incompleteConfigException($webhook);
|
||||
}
|
||||
|
||||
// Get listen URLs for each mount point.
|
||||
$listenUrls = $this->buildListenUrls($station);
|
||||
|
||||
// Build analytics
|
||||
$httpClient = new HttpClient();
|
||||
$httpClient->setClient($this->httpClient);
|
||||
|
||||
$analytics = new Analytics(true);
|
||||
$analytics->setHttpClient($httpClient);
|
||||
|
||||
$analytics->setProtocolVersion('1')
|
||||
->setTrackingId($config['tracking_id']);
|
||||
|
||||
// Get all current listeners
|
||||
$liveListeners = $this->listenerRepo->iterateLiveListenersArray($station);
|
||||
|
||||
$i = 0;
|
||||
foreach ($liveListeners as $listener) {
|
||||
$listenerUrl = $this->getListenUrl($listener, $listenUrls);
|
||||
if (null === $listenerUrl) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$analytics->setClientId($listener['listener_uid']);
|
||||
$analytics->setUserAgentOverride($listener['listener_user_agent']);
|
||||
$analytics->setIpOverride($listener['listener_ip']);
|
||||
$analytics->setDocumentPath($listenerUrl);
|
||||
$analytics->__call('enqueuePageView', []);
|
||||
$i++;
|
||||
|
||||
if (20 === $i) {
|
||||
$analytics->sendEnqueuedHits();
|
||||
$i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$analytics->sendEnqueuedHits();
|
||||
}
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Webhook\Connector;
|
||||
|
||||
use App\Entity\Api\NowPlaying\NowPlaying;
|
||||
use App\Entity\Station;
|
||||
use App\Entity\StationWebhook;
|
||||
use App\Service\GuzzleFactory;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Subscriber\Oauth\Oauth1;
|
||||
|
||||
final class Twitter extends AbstractSocialConnector
|
||||
{
|
||||
public function __construct(
|
||||
Client $httpClient,
|
||||
private readonly GuzzleFactory $guzzleFactory,
|
||||
) {
|
||||
parent::__construct($httpClient);
|
||||
}
|
||||
|
||||
protected function getRateLimitTime(StationWebhook $webhook): ?int
|
||||
{
|
||||
$config = $webhook->getConfig();
|
||||
$rateLimitSeconds = (int)($config['rate_limit'] ?? 0);
|
||||
|
||||
return max(10, $rateLimitSeconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function dispatch(
|
||||
Station $station,
|
||||
StationWebhook $webhook,
|
||||
NowPlaying $np,
|
||||
array $triggers
|
||||
): void {
|
||||
$config = $webhook->getConfig();
|
||||
|
||||
if (
|
||||
empty($config['consumer_key'])
|
||||
|| empty($config['consumer_secret'])
|
||||
|| empty($config['token'])
|
||||
|| empty($config['token_secret'])
|
||||
) {
|
||||
throw $this->incompleteConfigException($webhook);
|
||||
}
|
||||
|
||||
// Set up Twitter OAuth
|
||||
$stack = clone $this->guzzleFactory->getHandlerStack();
|
||||
|
||||
$middleware = new Oauth1(
|
||||
[
|
||||
'consumer_key' => trim($config['consumer_key']),
|
||||
'consumer_secret' => trim($config['consumer_secret']),
|
||||
'token' => trim($config['token']),
|
||||
'token_secret' => trim($config['token_secret']),
|
||||
]
|
||||
);
|
||||
$stack->push($middleware);
|
||||
|
||||
// Dispatch webhook
|
||||
$this->logger->debug('Posting to Twitter...');
|
||||
|
||||
foreach ($this->getMessages($webhook, $np, $triggers) as $message) {
|
||||
$messageBody = [
|
||||
'status' => $message,
|
||||
];
|
||||
|
||||
$response = $this->httpClient->request(
|
||||
'POST',
|
||||
'https://api.twitter.com/1.1/statuses/update.json',
|
||||
[
|
||||
'auth' => 'oauth',
|
||||
'handler' => $stack,
|
||||
'form_params' => $messageBody,
|
||||
]
|
||||
);
|
||||
|
||||
$this->logHttpResponse(
|
||||
$webhook,
|
||||
$response,
|
||||
$messageBody
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@ use App\Webhook\Connector\AbstractConnector;
|
|||
use App\Webhook\Enums\WebhookTriggers;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Monolog\Level;
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
final class Dispatcher
|
||||
|
@ -87,6 +88,16 @@ final class Dispatcher
|
|||
$webhookType = $webhook->getType();
|
||||
$webhookClass = $webhookType->getClass();
|
||||
|
||||
if (null === $webhookClass) {
|
||||
$this->logger->error(
|
||||
sprintf(
|
||||
'Webhook type "%s" is no longer supported. Removing this webhook is recommended.',
|
||||
$webhookType->value
|
||||
)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->logger->debug(
|
||||
sprintf('Dispatching connector "%s".', $webhookType->value)
|
||||
);
|
||||
|
@ -155,6 +166,12 @@ final class Dispatcher
|
|||
$webhookType = $webhook->getType();
|
||||
$webhookClass = $webhookType->getClass();
|
||||
|
||||
if (null === $webhookClass) {
|
||||
throw new RuntimeException(
|
||||
'Webhook type is no longer supported. Removing this webhook is recommended.'
|
||||
);
|
||||
}
|
||||
|
||||
/** @var AbstractConnector $webhookObj */
|
||||
$webhookObj = $this->di->get($webhookClass);
|
||||
$webhookObj->dispatch($station, $webhook, $np, [
|
||||
|
|
|
@ -7,14 +7,12 @@ namespace App\Webhook\Enums;
|
|||
use App\Webhook\Connector\Discord;
|
||||
use App\Webhook\Connector\Email;
|
||||
use App\Webhook\Connector\Generic;
|
||||
use App\Webhook\Connector\GoogleAnalyticsV3;
|
||||
use App\Webhook\Connector\GoogleAnalyticsV4;
|
||||
use App\Webhook\Connector\Mastodon;
|
||||
use App\Webhook\Connector\MatomoAnalytics;
|
||||
use App\Webhook\Connector\RadioDe;
|
||||
use App\Webhook\Connector\Telegram;
|
||||
use App\Webhook\Connector\TuneIn;
|
||||
use App\Webhook\Connector\Twitter;
|
||||
|
||||
enum WebhookTypes: string
|
||||
{
|
||||
|
@ -26,17 +24,19 @@ enum WebhookTypes: string
|
|||
|
||||
case Discord = 'discord';
|
||||
case Telegram = 'telegram';
|
||||
case Twitter = 'twitter';
|
||||
case Mastodon = 'mastodon';
|
||||
|
||||
case GoogleAnalyticsV3 = 'google_analytics';
|
||||
case GoogleAnalyticsV4 = 'google_analytics_v4';
|
||||
case MatomoAnalytics = 'matomo_analytics';
|
||||
|
||||
// Retired connectors
|
||||
case Twitter = 'twitter';
|
||||
case GoogleAnalyticsV3 = 'google_analytics';
|
||||
|
||||
/**
|
||||
* @return class-string
|
||||
* @return class-string|null
|
||||
*/
|
||||
public function getClass(): string
|
||||
public function getClass(): ?string
|
||||
{
|
||||
return match ($this) {
|
||||
self::Generic => Generic::class,
|
||||
|
@ -45,11 +45,10 @@ enum WebhookTypes: string
|
|||
self::RadioDe => RadioDe::class,
|
||||
self::Discord => Discord::class,
|
||||
self::Telegram => Telegram::class,
|
||||
self::Twitter => Twitter::class,
|
||||
self::Mastodon => Mastodon::class,
|
||||
self::GoogleAnalyticsV3 => GoogleAnalyticsV3::class,
|
||||
self::GoogleAnalyticsV4 => GoogleAnalyticsV4::class,
|
||||
self::MatomoAnalytics => MatomoAnalytics::class
|
||||
self::MatomoAnalytics => MatomoAnalytics::class,
|
||||
default => null
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue