sharkey/packages/backend/src/core/WebhookService.ts

71 lines
1.7 KiB
TypeScript
Raw Normal View History

2022-09-18 03:27:08 +09:00
import { Inject, Injectable } from '@nestjs/common';
import Redis from 'ioredis';
import { WebhooksRepository } from '@/models/index.js';
import type { Webhook } from '@/models/entities/Webhook.js';
import { DI } from '@/di-symbols.js';
import type { OnApplicationShutdown } from '@nestjs/common';
@Injectable()
export class WebhookService implements OnApplicationShutdown {
#webhooksFetched = false;
#webhooks: Webhook[] = [];
constructor(
@Inject(DI.redisSubscriber)
private redisSubscriber: Redis.Redis,
@Inject(DI.webhooksRepository)
private webhooksRepository: WebhooksRepository,
) {
this.onMessage = this.onMessage.bind(this);
this.redisSubscriber.on('message', this.onMessage);
}
public async getActiveWebhooks() {
if (!this.#webhooksFetched) {
this.#webhooks = await this.webhooksRepository.findBy({
active: true,
});
this.#webhooksFetched = true;
}
return this.#webhooks;
}
private async onMessage(_, data) {
const obj = JSON.parse(data);
if (obj.channel === 'internal') {
const { type, body } = obj.message;
switch (type) {
case 'webhookCreated':
if (body.active) {
this.#webhooks.push(body);
}
break;
case 'webhookUpdated':
if (body.active) {
const i = this.#webhooks.findIndex(a => a.id === body.id);
if (i > -1) {
this.#webhooks[i] = body;
} else {
this.#webhooks.push(body);
}
} else {
this.#webhooks = this.#webhooks.filter(a => a.id !== body.id);
}
break;
case 'webhookDeleted':
this.#webhooks = this.#webhooks.filter(a => a.id !== body.id);
break;
default:
break;
}
}
}
public onApplicationShutdown(signal?: string | undefined) {
this.redisSubscriber.off('message', this.onMessage);
}
}