This repository has no description
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358// SPDX-License-Identifier: AGPL-3.0-or-later
import type {MessageResponse} from '@fluxer/schema/src/domains/message/MessageResponseSchemas';import type {GitHubWebhook} from '@fluxer/schema/src/domains/webhook/GitHubWebhookSchemas';import type { SlackWebhookRequest, WebhookCreateRequest, WebhookTokenUpdateRequest, WebhookUpdateRequest,} from '@fluxer/schema/src/domains/webhook/WebhookRequestSchemas';import type {WebhookResponse, WebhookTokenResponse} from '@fluxer/schema/src/domains/webhook/WebhookSchemas';import type {ChannelID, GuildID, MessageID, UserID, WebhookID, WebhookToken} from '../BrandedTypes';import {createUserID} from '../BrandedTypes';import {Config} from '../Config';import type {IChannelRepository} from '../channel/IChannelRepository';import type {MessageUpdateRequest} from '../channel/MessageTypes';import {createMessageResponseDataService} from '../channel/services/message/MessageResponseDataService';import type {LiveKitWebhookService} from '../infrastructure/LiveKitWebhookService';import type {UserCacheService} from '../infrastructure/UserCacheService';import type {RequestCache} from '../middleware/RequestCacheMiddleware';import type {Message} from '../models/Message';import type {SweegoWebhookService} from './SweegoWebhookService';import {transformSlackWebhookRequest} from './transformers/SlackTransformer';import {mapWebhooksToResponse, mapWebhookToResponseWithCache, mapWebhookToTokenResponse} from './WebhookModel';import type {WebhookExecuteMessageData, WebhookService} from './WebhookService';
type WebhookExecutionResponse = MessageResponse | null;
interface WebhookListGuildParams { userId: UserID; guildId: GuildID; requestCache: RequestCache;}
interface WebhookListChannelParams { userId: UserID; channelId: ChannelID; requestCache: RequestCache;}
interface WebhookCreateParams { userId: UserID; channelId: ChannelID; data: WebhookCreateRequest; requestCache: RequestCache; auditLogReason?: string | null;}
interface WebhookGetByUserParams { userId: UserID; webhookId: WebhookID; requestCache: RequestCache;}
interface WebhookGetByTokenParams { webhookId: WebhookID; token: WebhookToken; requestCache: RequestCache;}
type WebhookGetParams = WebhookGetByUserParams | WebhookGetByTokenParams;
interface WebhookUpdateByUserParams { userId: UserID; webhookId: WebhookID; data: WebhookUpdateRequest; requestCache: RequestCache; auditLogReason?: string | null;}
interface WebhookUpdateByTokenParams { webhookId: WebhookID; token: WebhookToken; data: WebhookTokenUpdateRequest; requestCache: RequestCache;}
type WebhookUpdateParams = WebhookUpdateByUserParams | WebhookUpdateByTokenParams;
interface WebhookDeleteByUserParams { userId: UserID; webhookId: WebhookID; auditLogReason?: string | null;}
interface WebhookDeleteByTokenParams { webhookId: WebhookID; token: WebhookToken;}
type WebhookDeleteParams = WebhookDeleteByUserParams | WebhookDeleteByTokenParams;
interface WebhookExecuteParams { webhookId: WebhookID; token: WebhookToken; data: WebhookExecuteMessageData; wait: boolean; requestCache: RequestCache;}
interface WebhookGetMessageParams { webhookId: WebhookID; token: WebhookToken; messageId: MessageID; requestCache: RequestCache;}
interface WebhookEditMessageParams { webhookId: WebhookID; token: WebhookToken; messageId: MessageID; data: MessageUpdateRequest; requestCache: RequestCache;}
interface WebhookDeleteMessageParams { webhookId: WebhookID; token: WebhookToken; messageId: MessageID; requestCache: RequestCache;}
interface WebhookExecuteGitHubParams { webhookId: WebhookID; token: WebhookToken; event: string; delivery: string; data: GitHubWebhook; requestCache: RequestCache;}
interface WebhookExecuteSlackParams { webhookId: WebhookID; token: WebhookToken; data: SlackWebhookRequest; requestCache: RequestCache;}
interface LiveKitWebhookParams { body: string; authHeader?: string;}
interface SweegoWebhookParams { body: string; webhookId?: string; timestamp?: string; signature?: string;}
export class WebhookRequestService { constructor( private readonly webhookService: WebhookService, private readonly channelRepository: IChannelRepository, private readonly userCacheService: UserCacheService, private readonly liveKitWebhookService: LiveKitWebhookService | null, private readonly sweegoWebhookService: SweegoWebhookService, ) {}
async listGuildWebhooks(params: WebhookListGuildParams): Promise<Array<WebhookResponse>> { const webhooks = await this.webhookService.getGuildWebhooks({ userId: params.userId, guildId: params.guildId, }); return mapWebhooksToResponse({ webhooks, userCacheService: this.userCacheService, requestCache: params.requestCache, }); }
async listChannelWebhooks(params: WebhookListChannelParams): Promise<Array<WebhookResponse>> { const webhooks = await this.webhookService.getChannelWebhooks({ userId: params.userId, channelId: params.channelId, }); return mapWebhooksToResponse({ webhooks, userCacheService: this.userCacheService, requestCache: params.requestCache, }); }
async createWebhook(params: WebhookCreateParams): Promise<WebhookResponse> { const webhook = await this.webhookService.createWebhook( { userId: params.userId, channelId: params.channelId, data: params.data, }, params.auditLogReason ?? null, ); return mapWebhookToResponseWithCache({ webhook, userCacheService: this.userCacheService, requestCache: params.requestCache, }); }
async getWebhook(params: WebhookGetByUserParams): Promise<WebhookResponse>; async getWebhook(params: WebhookGetByTokenParams): Promise<WebhookTokenResponse>; async getWebhook(params: WebhookGetParams): Promise<WebhookResponse | WebhookTokenResponse> { if ('token' in params) { const webhook = await this.webhookService.getWebhookByToken({webhookId: params.webhookId, token: params.token}); return mapWebhookToTokenResponse(webhook); } const webhook = await this.webhookService.getWebhook({userId: params.userId, webhookId: params.webhookId}); return mapWebhookToResponseWithCache({ webhook, userCacheService: this.userCacheService, requestCache: params.requestCache, }); }
async updateWebhook(params: WebhookUpdateByUserParams): Promise<WebhookResponse>; async updateWebhook(params: WebhookUpdateByTokenParams): Promise<WebhookTokenResponse>; async updateWebhook(params: WebhookUpdateParams): Promise<WebhookResponse | WebhookTokenResponse> { if ('token' in params) { const webhook = await this.webhookService.updateWebhookByToken({ webhookId: params.webhookId, token: params.token, data: params.data, }); return mapWebhookToTokenResponse(webhook); } const webhook = await this.webhookService.updateWebhook( { userId: params.userId, webhookId: params.webhookId, data: params.data, }, params.auditLogReason ?? null, ); return mapWebhookToResponseWithCache({ webhook, userCacheService: this.userCacheService, requestCache: params.requestCache, }); }
async deleteWebhook(params: WebhookDeleteParams): Promise<void> { if ('token' in params) { await this.webhookService.deleteWebhookByToken({webhookId: params.webhookId, token: params.token}); return; } await this.webhookService.deleteWebhook( { userId: params.userId, webhookId: params.webhookId, }, params.auditLogReason ?? null, ); }
async executeWebhook(params: WebhookExecuteParams): Promise<WebhookExecutionResponse> { const message = await this.webhookService.executeWebhook({ webhookId: params.webhookId, token: params.token, data: params.data, requestCache: params.requestCache, }); if (!params.wait) { return null; } return this.mapMessageResponse(message, params.requestCache); }
async getWebhookMessage(params: WebhookGetMessageParams): Promise<MessageResponse> { const message = await this.webhookService.getWebhookMessage({ webhookId: params.webhookId, token: params.token, messageId: params.messageId, }); return this.mapMessageResponse(message, params.requestCache); }
async editWebhookMessage(params: WebhookEditMessageParams): Promise<MessageResponse> { const message = await this.webhookService.editWebhookMessage({ webhookId: params.webhookId, token: params.token, messageId: params.messageId, data: params.data, requestCache: params.requestCache, }); return this.mapMessageResponse(message, params.requestCache); }
async deleteWebhookMessage(params: WebhookDeleteMessageParams): Promise<void> { await this.webhookService.deleteWebhookMessage({ webhookId: params.webhookId, token: params.token, messageId: params.messageId, requestCache: params.requestCache, }); }
async executeGitHubWebhook(params: WebhookExecuteGitHubParams): Promise<void> { await this.webhookService.executeGitHubWebhook({ webhookId: params.webhookId, token: params.token, event: params.event, delivery: params.delivery, data: params.data, requestCache: params.requestCache, }); }
async executeSlackWebhook(params: WebhookExecuteSlackParams): Promise<void> { await this.webhookService.executeWebhook({ webhookId: params.webhookId, token: params.token, data: transformSlackWebhookRequest(params.data), requestCache: params.requestCache, }); }
async handleLiveKitWebhook(params: LiveKitWebhookParams): Promise<Response> { if (!Config.voice.enabled) { return new Response('Voice not enabled', {status: 404}); } if (!this.liveKitWebhookService) { return new Response('LiveKit webhook service not available', {status: 503}); } const response = await this.liveKitWebhookService.handleWebhookRequest({ body: params.body, authHeader: params.authHeader, }); return new Response(response.body, {status: response.status}); }
async handleSweegoWebhook(params: SweegoWebhookParams): Promise<Response> { if (!Config.email.enabled) { return new Response('Email not enabled', {status: 404}); } const response = await this.sweegoWebhookService.handleWebhook({ body: params.body, webhookId: params.webhookId, timestamp: params.timestamp, signature: params.signature, secret: Config.email.webhookSecret, }); return new Response(response.body, {status: response.status}); }
private async mapMessageResponse(message: Message, _requestCache: RequestCache): Promise<MessageResponse> { const channel = await this.channelRepository.findUnique(message.channelId); return createMessageResponseDataService().buildMessage({ userId: createUserID(0n), message, access: { sourceGuildId: channel?.guildId ?? null, messageHistoryCutoff: null, canReadMessageHistory: true, }, }); }}