summaryrefslogtreecommitdiff
path: root/packages/backend/src/core/UserWebhookService.ts
diff options
context:
space:
mode:
authormisskey-release-bot[bot] <157398866+misskey-release-bot[bot]@users.noreply.github.com>2024-07-31 11:20:31 +0000
committerGitHub <noreply@github.com>2024-07-31 11:20:31 +0000
commite98f66db51aabef925ea1a8faee6c37f67071107 (patch)
tree168fcc9219f7511bbf9bc198568406bd49fc31bb /packages/backend/src/core/UserWebhookService.ts
parentfix: remove unreleased section (#14246) (diff)
parentRelease: 2024.7.0 (diff)
downloadsharkey-e98f66db51aabef925ea1a8faee6c37f67071107.tar.gz
sharkey-e98f66db51aabef925ea1a8faee6c37f67071107.tar.bz2
sharkey-e98f66db51aabef925ea1a8faee6c37f67071107.zip
Merge pull request #14233 from misskey-dev/develop
Release: 2024.7.0
Diffstat (limited to 'packages/backend/src/core/UserWebhookService.ts')
-rw-r--r--packages/backend/src/core/UserWebhookService.ts99
1 files changed, 99 insertions, 0 deletions
diff --git a/packages/backend/src/core/UserWebhookService.ts b/packages/backend/src/core/UserWebhookService.ts
new file mode 100644
index 0000000000..e96bfeea95
--- /dev/null
+++ b/packages/backend/src/core/UserWebhookService.ts
@@ -0,0 +1,99 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import { Inject, Injectable } from '@nestjs/common';
+import * as Redis from 'ioredis';
+import type { WebhooksRepository } from '@/models/_.js';
+import type { MiWebhook } from '@/models/Webhook.js';
+import { DI } from '@/di-symbols.js';
+import { bindThis } from '@/decorators.js';
+import { GlobalEvents } from '@/core/GlobalEventService.js';
+import type { OnApplicationShutdown } from '@nestjs/common';
+
+@Injectable()
+export class UserWebhookService implements OnApplicationShutdown {
+ private activeWebhooksFetched = false;
+ private activeWebhooks: MiWebhook[] = [];
+
+ constructor(
+ @Inject(DI.redisForSub)
+ private redisForSub: Redis.Redis,
+ @Inject(DI.webhooksRepository)
+ private webhooksRepository: WebhooksRepository,
+ ) {
+ this.redisForSub.on('message', this.onMessage);
+ }
+
+ @bindThis
+ public async getActiveWebhooks() {
+ if (!this.activeWebhooksFetched) {
+ this.activeWebhooks = await this.webhooksRepository.findBy({
+ active: true,
+ });
+ this.activeWebhooksFetched = true;
+ }
+
+ return this.activeWebhooks;
+ }
+
+ @bindThis
+ private async onMessage(_: string, data: string): Promise<void> {
+ const obj = JSON.parse(data);
+ if (obj.channel !== 'internal') {
+ return;
+ }
+
+ const { type, body } = obj.message as GlobalEvents['internal']['payload'];
+ switch (type) {
+ case 'webhookCreated': {
+ if (body.active) {
+ this.activeWebhooks.push({ // TODO: このあたりのデシリアライズ処理は各modelファイル内に関数としてexportしたい
+ ...body,
+ latestSentAt: body.latestSentAt ? new Date(body.latestSentAt) : null,
+ user: null, // joinなカラムは通常取ってこないので
+ });
+ }
+ break;
+ }
+ case 'webhookUpdated': {
+ if (body.active) {
+ const i = this.activeWebhooks.findIndex(a => a.id === body.id);
+ if (i > -1) {
+ this.activeWebhooks[i] = { // TODO: このあたりのデシリアライズ処理は各modelファイル内に関数としてexportしたい
+ ...body,
+ latestSentAt: body.latestSentAt ? new Date(body.latestSentAt) : null,
+ user: null, // joinなカラムは通常取ってこないので
+ };
+ } else {
+ this.activeWebhooks.push({ // TODO: このあたりのデシリアライズ処理は各modelファイル内に関数としてexportしたい
+ ...body,
+ latestSentAt: body.latestSentAt ? new Date(body.latestSentAt) : null,
+ user: null, // joinなカラムは通常取ってこないので
+ });
+ }
+ } else {
+ this.activeWebhooks = this.activeWebhooks.filter(a => a.id !== body.id);
+ }
+ break;
+ }
+ case 'webhookDeleted': {
+ this.activeWebhooks = this.activeWebhooks.filter(a => a.id !== body.id);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ @bindThis
+ public dispose(): void {
+ this.redisForSub.off('message', this.onMessage);
+ }
+
+ @bindThis
+ public onApplicationShutdown(signal?: string | undefined): void {
+ this.dispose();
+ }
+}