MicProtocol / apps /api /dist /integrations /integrations-webhook.controller.js
Benaah's picture
Upload folder using huggingface_hub (part 2)
9f29339 verified
Raw History Blame Contribute Delete
33.5 kB
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
var IntegrationsWebhookController_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.IntegrationsWebhookController = void 0;
const common_1 = require("@nestjs/common");
const config_1 = require("@nestjs/config");
const prisma_service_1 = require("../prisma/prisma.service");
const crypto = __importStar(require("crypto"));
const webhook_idempotency_service_1 = require("./webhook-idempotency.service");
const self_hosted_clients_service_1 = require("./clients/self-hosted-clients.service");
const chatwoot_sync_service_1 = require("../support/chatwoot-sync.service");
const events_gateway_1 = require("../websocket/events.gateway");
function timingSafeCompare(provided, expected) {
if (!provided || !expected)
return false;
const bufProvided = Buffer.from(provided);
const bufExpected = Buffer.from(expected);
if (bufProvided.length !== bufExpected.length)
return false;
return crypto.timingSafeEqual(bufProvided, bufExpected);
}
function verifyRawBodyHmac(rawBody, signature, secret, timestamp, allowSha1 = false) {
if (!rawBody || !signature || !secret)
return false;
const provided = signature.replace(/^sha256=/i, "").replace(/^sha1=/i, "");
const messages = [rawBody];
if (timestamp) {
messages.push(Buffer.from(`${timestamp}.${rawBody.toString("utf8")}`, "utf8"));
}
const candidates = [];
for (const msg of messages) {
candidates.push(crypto.createHmac("sha256", secret).update(msg).digest("hex"));
if (allowSha1) {
candidates.push(crypto.createHmac("sha1", secret).update(msg).digest("hex"));
}
}
return candidates.some((expected) => timingSafeCompare(provided, expected));
}
function verifyStandardWebhooksSignature(rawBody, signatureHeader, idHeader, timestampHeader, secret) {
if (!rawBody || !signatureHeader || !idHeader || !timestampHeader || !secret) {
return false;
}
const nowSec = Math.floor(Date.now() / 1000);
const ts = Number(timestampHeader);
if (!Number.isFinite(ts) || Math.abs(nowSec - ts) > 300)
return false;
let secretBytes;
const stripped = secret.replace(/^whsec_/i, "");
try {
const decoded = Buffer.from(stripped, "base64");
if (decoded.toString("base64").replace(/=+$/, "") === stripped.replace(/=+$/, "")) {
secretBytes = decoded;
}
else {
secretBytes = Buffer.from(secret, "utf8");
}
}
catch {
secretBytes = Buffer.from(secret, "utf8");
}
const signedContent = `${idHeader}.${timestampHeader}.${rawBody.toString("utf8")}`;
const expected = crypto
.createHmac("sha256", secretBytes)
.update(signedContent)
.digest("base64");
return signatureHeader.split(/\s+/).some((entry) => {
const [version, sig] = entry.split(",", 2);
if (version !== "v1" || !sig)
return false;
return timingSafeCompare(sig, expected);
});
}
let IntegrationsWebhookController = IntegrationsWebhookController_1 = class IntegrationsWebhookController {
configService;
prisma;
idempotency;
selfHostedClients;
chatwootSync;
eventsGateway;
logger = new common_1.Logger(IntegrationsWebhookController_1.name);
constructor(configService, prisma, idempotency, selfHostedClients, chatwootSync, eventsGateway) {
this.configService = configService;
this.prisma = prisma;
this.idempotency = idempotency;
this.selfHostedClients = selfHostedClients;
this.chatwootSync = chatwootSync;
this.eventsGateway = eventsGateway;
}
requireSecret(envName, configured) {
if (!configured && process.env.NODE_ENV === "production") {
this.logger.error(`${envName} is not configured — rejecting webhook`);
throw new common_1.UnauthorizedException(`${envName} is not configured`);
}
}
async checkIdempotency(provider, body) {
const eventKey = this.idempotency.generateEventKey(provider, body);
const isDuplicate = await this.idempotency.checkAndMark(eventKey);
if (isDuplicate) {
this.logger.warn(`Duplicate webhook ignored: ${provider}:${eventKey}`);
}
return isDuplicate;
}
verifyLiveKitJwt(authorization, apiKey, apiSecret, rawBody) {
if (!authorization?.startsWith("Bearer "))
return false;
const token = authorization.slice("Bearer ".length).trim();
const parts = token.split(".");
if (parts.length !== 3)
return false;
const [headerB64, payloadB64, signatureB64] = parts;
try {
const payload = JSON.parse(Buffer.from(payloadB64, "base64url").toString("utf8"));
if (payload.iss !== apiKey)
return false;
const nowSec = Math.floor(Date.now() / 1000);
if (typeof payload.exp === "number" && payload.exp < nowSec)
return false;
if (typeof payload.nbf === "number" && payload.nbf > nowSec + 60)
return false;
const signingInput = `${headerB64}.${payloadB64}`;
const expected = crypto
.createHmac("sha256", apiSecret)
.update(signingInput)
.digest("base64url");
if (!timingSafeCompare(expected, signatureB64))
return false;
if (typeof payload.sha256 !== "string")
return false;
if (rawBody === undefined) {
return process.env.NODE_ENV !== "production";
}
const bodyBuf = typeof rawBody === "string" ? Buffer.from(rawBody, "utf8") : rawBody;
const bodyHash = crypto
.createHash("sha256")
.update(bodyBuf)
.digest("base64");
return timingSafeCompare(payload.sha256, bodyHash);
}
catch {
return false;
}
}
async handleCalComWebhook(body, secret) {
const expected = this.configService.get("CALCOM_WEBHOOK_SECRET", "");
this.requireSecret("CALCOM_WEBHOOK_SECRET", expected);
if (expected && !timingSafeCompare(secret, expected)) {
throw new common_1.UnauthorizedException("Invalid Cal.com webhook secret");
}
if (await this.checkIdempotency("calcom", body)) {
return { received: true, duplicate: true };
}
const eventType = String(body?.triggerEvent || body?.event || "unknown");
const payload = (body?.payload || body);
this.logger.log(`Cal.com webhook received: ${eventType}`);
await this.handleCalComEvent(eventType, payload);
return { received: true, event: eventType };
}
async handleCalComEvent(eventType, payload) {
const uid = String(payload?.uid || payload?.bookingId || "");
if (!uid)
return;
const booking = await this.prisma.booking.findFirst({
where: { OR: [{ calendarEventId: uid }, { meetLink: { contains: uid } }] },
include: {
episode: {
include: {
podcast: {
select: { workspaceId: true },
},
},
},
},
});
if (!booking) {
this.logger.warn(`No booking found for Cal.com UID: ${uid}`);
return;
}
switch (eventType) {
case "BOOKING_CREATED":
case "BOOKING_CONFIRMED":
await this.prisma.booking.update({
where: { id: booking.id },
data: { isConfirmed: true, updatedAt: new Date() },
});
this.logger.log(`Booking ${booking.id} confirmed via Cal.com`);
if (booking.episode?.podcast?.workspaceId) {
this.eventsGateway.notifyCalComBookingCreated(booking.episode.podcast.workspaceId, { id: booking.id, isConfirmed: true });
}
break;
case "BOOKING_CANCELLED":
case "BOOKING_REJECTED":
await this.prisma.booking.update({
where: { id: booking.id },
data: { isConfirmed: false, updatedAt: new Date() },
});
this.logger.log(`Booking ${booking.id} cancelled via Cal.com`);
if (booking.episode?.podcast?.workspaceId) {
this.eventsGateway.notifyCalComBookingCancelled(booking.episode.podcast.workspaceId, booking.id);
}
break;
case "BOOKING_RESCHEDULED":
const newStart = String(payload?.startTime || payload?.rescheduledStartTime || "");
const newEnd = String(payload?.endTime || payload?.rescheduledEndTime || "");
if (newStart && newEnd) {
await this.prisma.booking.update({
where: { id: booking.id },
data: {
startTime: new Date(newStart),
endTime: new Date(newEnd),
updatedAt: new Date(),
},
});
this.logger.log(`Booking ${booking.id} rescheduled to ${newStart}`);
if (booking.episode?.podcast?.workspaceId) {
this.eventsGateway.notifyCalComBookingRescheduled(booking.episode.podcast.workspaceId, booking.id);
}
}
break;
case "BOOKING_NO_SHOW":
this.logger.log(`Booking ${booking.id} no-show (no status field available)`);
break;
case "BOOKING_ATTENDEE_ADDED":
case "BOOKING_ATTENDEE_REMOVED":
this.logger.log(`Attendee change for booking ${booking.id}: ${eventType}`);
break;
default:
this.logger.debug(`Unhandled Cal.com event type: ${eventType}`);
}
}
async handleChatwootWebhook(accountId, req, body, signature, timestamp) {
const expected = this.configService.get("CHATWOOT_WEBHOOK_SECRET", "");
this.requireSecret("CHATWOOT_WEBHOOK_SECRET", expected);
if (expected &&
!verifyRawBodyHmac(req.rawBody, signature, expected, timestamp, true)) {
throw new common_1.UnauthorizedException("Invalid Chatwoot webhook signature");
}
if (await this.checkIdempotency("chatwoot", body)) {
return { received: true, duplicate: true };
}
const event = body?.event || "unknown";
this.logger.log(`Chatwoot webhook: ${event} for account ${accountId}`);
await this.handleChatwootEvent(event, body, accountId);
return { received: true, event, accountId };
}
async handleChatwootEvent(event, body, accountId) {
switch (event) {
case "message_created":
if (body?.message_type === "incoming" && body?.content) {
const conversationId = body?.conversation?.id;
const contactId = body?.conversation?.contact_inbox?.contact_id;
const messageId = body?.message?.id;
this.logger.log(`Incoming Chatwoot message in conversation ${conversationId} from contact ${contactId}`);
if (contactId) {
await this.syncChatwootContact(contactId, accountId);
}
if (conversationId && messageId && body.content) {
await this.chatwootSync.syncIncomingMessage(accountId, conversationId, messageId, body.content, "incoming");
}
}
break;
case "conversation_created":
this.logger.log(`New Chatwoot conversation: ${body?.conversation?.id}`);
break;
case "conversation_status_changed": {
const newStatus = body?.conversation?.status;
const conversationId = body?.conversation?.id;
this.logger.log(`Conversation ${conversationId} status changed to ${newStatus}`);
if (conversationId && newStatus) {
await this.chatwootSync.syncConversationStatus(accountId, conversationId, newStatus);
}
break;
}
case "conversation_assigned": {
const conversationId = body?.conversation?.id;
const assigneeId = body?.conversation?.assignee?.id;
this.logger.log(`Conversation ${conversationId} assigned to ${assigneeId}`);
if (conversationId) {
await this.chatwootSync.syncConversationAssignment(accountId, conversationId, assigneeId);
}
break;
}
case "contact_created":
case "contact_updated":
const contactId = body?.contact?.id;
if (contactId) {
await this.syncChatwootContact(contactId, accountId);
}
break;
default:
this.logger.debug(`Unhandled Chatwoot event: ${event}`);
}
}
async syncChatwootContact(contactId, accountId) {
try {
const integration = await this.prisma.workspaceIntegration.findFirst({
where: {
provider: "chatwoot",
status: "connected",
metadata: { path: ["accountId"], equals: accountId },
},
});
if (!integration) {
this.logger.warn(`No workspace integration found for Chatwoot account ${accountId}`);
return;
}
const apiKey = integration.accessToken;
if (!apiKey) {
this.logger.warn(`No API key found for Chatwoot integration ${integration.id}`);
return;
}
const contact = await this.selfHostedClients.getChatwootContact(apiKey, contactId);
if (!contact?.email) {
this.logger.warn(`Chatwoot contact ${contactId} has no email, skipping sync`);
return;
}
const workspace = await this.prisma.workspace.findUnique({
where: { id: integration.workspaceId },
include: { podcasts: { take: 1 } },
});
const podcastId = workspace?.podcasts?.[0]?.id;
if (!podcastId) {
this.logger.warn(`No podcast found for workspace ${integration.workspaceId}, cannot create guest`);
return;
}
const existingGuest = await this.prisma.guest.findFirst({
where: { podcastId, email: contact.email },
});
if (existingGuest) {
const currentCustomFields = existingGuest.customFields || {};
await this.prisma.guest.update({
where: { id: existingGuest.id },
data: {
fullName: contact.name || existingGuest.fullName,
lastContactAt: new Date(),
customFields: {
...currentCustomFields,
chatwootContactId: contactId,
chatwootAccountId: accountId,
chatwootPhone: contact.phone_number,
chatwootCustomAttributes: contact.custom_attributes,
},
},
});
this.logger.log(`Updated guest ${existingGuest.id} from Chatwoot contact ${contactId}`);
}
else {
await this.prisma.guest.create({
data: {
podcastId,
email: contact.email,
fullName: contact.name || contact.email.split("@")[0],
status: "prospect",
customFields: {
chatwootContactId: contactId,
chatwootAccountId: accountId,
chatwootPhone: contact.phone_number,
chatwootCustomAttributes: contact.custom_attributes,
source: "chatwoot",
},
},
});
this.logger.log(`Created guest from Chatwoot contact ${contactId} (${contact.email})`);
}
}
catch (error) {
const message = error instanceof Error ? error.message : String(error);
this.logger.error(`Failed to sync Chatwoot contact ${contactId}: ${message}`);
}
}
async handleDocumensoWebhook(body, secret) {
const expected = this.configService.get("DOCUMENSO_WEBHOOK_SECRET", "");
this.requireSecret("DOCUMENSO_WEBHOOK_SECRET", expected);
if (expected && !timingSafeCompare(secret, expected)) {
throw new common_1.UnauthorizedException("Invalid Documenso webhook secret");
}
if (await this.checkIdempotency("documenso", body)) {
return { received: true, duplicate: true };
}
const event = body?.event || "unknown";
const documentId = body?.documentId || body?.data?.id;
this.logger.log(`Documenso webhook: ${event} docId=${documentId ?? ""}`);
if (documentId && (event === "document_completed" || event === "document_declined")) {
this.logger.log(`Document ${documentId} status: ${event}`);
}
return { received: true, event, documentId };
}
async handleFormbricksWebhook(req, body, signature, webhookId, webhookTimestamp) {
const expected = this.configService.get("FORMBRICKS_WEBHOOK_SECRET", "");
this.requireSecret("FORMBRICKS_WEBHOOK_SECRET", expected);
if (expected &&
!verifyStandardWebhooksSignature(req.rawBody, signature, webhookId, webhookTimestamp, expected)) {
throw new common_1.UnauthorizedException("Invalid Formbricks webhook signature");
}
if (await this.checkIdempotency("formbricks", body)) {
return { received: true, duplicate: true };
}
const event = body?.event || body?.type || "unknown";
const surveyId = body?.surveyId || body?.data?.surveyId;
const responseId = body?.responseId || body?.data?.id;
this.logger.log(`Formbricks webhook: ${event} surveyId=${surveyId ?? ""} responseId=${responseId ?? ""}`);
if (body?.data?.userId) {
const guest = await this.prisma.guest.findFirst({
where: { id: body.data.userId },
});
if (guest) {
await this.prisma.guestJourneyEvent.create({
data: {
guestId: guest.id,
eventType: "follow_up",
title: "Completed Survey",
details: `Completed survey ${surveyId || ""}`,
metadata: JSON.parse(JSON.stringify(body?.data || {})),
},
});
this.logger.log(`Recorded survey completion journey event for guest ${guest.id}`);
}
}
return { received: true, event, surveyId, responseId };
}
async handleListmonkWebhook(body, secret) {
const expected = this.configService.get("LISTMONK_WEBHOOK_SECRET", "");
this.requireSecret("LISTMONK_WEBHOOK_SECRET", expected);
if (expected && !timingSafeCompare(secret, expected)) {
throw new common_1.UnauthorizedException("Invalid Listmonk webhook secret");
}
if (await this.checkIdempotency("listmonk", body)) {
return { received: true, duplicate: true };
}
const event = body?.event || "unknown";
const subscriberId = body?.data?.subscriber?.id || body?.subscriber_id;
this.logger.log(`Listmonk webhook: ${event} subscriberId=${subscriberId ?? ""}`);
await this.handleListmonkEvent(event, body);
return { received: true, event, subscriberId };
}
async handleListmonkEvent(event, body) {
const subscriber = body?.data?.subscriber || body?.subscriber;
if (!subscriber)
return;
const email = subscriber.email;
const name = subscriber.name || "";
const status = subscriber.status || "enabled";
const lists = subscriber.lists || [];
switch (event) {
case "subscriber.created":
case "subscriber.updated":
await this.syncListmonkSubscriber(subscriber);
break;
case "subscriber.deleted":
await this.unsubscribeListmonkSubscriber(email);
break;
case "subscriber.subscribed":
case "subscriber.unsubscribed":
await this.handleListmonkSubscriptionChange(email, lists, event);
break;
default:
this.logger.debug(`Unhandled Listmonk event: ${event}`);
}
}
async syncListmonkSubscriber(subscriber) {
const email = subscriber.email;
if (!email)
return;
try {
const guest = await this.prisma.guest.findFirst({
where: { email },
});
if (guest) {
await this.prisma.guest.update({
where: { id: guest.id },
data: {
customFields: {
listmonkSubscriberId: subscriber.id,
listmonkStatus: subscriber.status,
listmonkLists: subscriber.lists || [],
},
},
});
this.logger.log(`Synced Listmonk subscriber ${subscriber.id} to guest ${guest.id}`);
}
else {
this.logger.log(`Listmonk subscriber ${email} not found in guests, would create contact`);
}
}
catch (error) {
const message = error instanceof Error ? error.message : String(error);
this.logger.error(`Failed to sync Listmonk subscriber ${subscriber.id}: ${message}`);
}
}
async unsubscribeListmonkSubscriber(email) {
try {
const guest = await this.prisma.guest.findFirst({ where: { email } });
if (guest) {
await this.prisma.guest.update({
where: { id: guest.id },
data: {
customFields: {
listmonkUnsubscribedAt: new Date().toISOString(),
},
},
});
this.logger.log(`Marked guest ${guest.id} as unsubscribed via Listmonk webhook`);
}
}
catch (error) {
const message = error instanceof Error ? error.message : String(error);
this.logger.error(`Failed to unsubscribe guest for email ${email}: ${message}`);
}
}
async handleListmonkSubscriptionChange(email, lists, event) {
this.logger.log(`Listmonk subscription change for ${email}: ${event} on lists ${lists.map(l => l.id).join(", ")}`);
}
async handleLiveKitWebhook(req, body, authorization) {
const apiKey = this.configService.get("LIVEKIT_API_KEY", "");
const apiSecret = this.configService.get("LIVEKIT_API_SECRET", "");
const rawBody = req.rawBody;
if (process.env.NODE_ENV === "production") {
if (!apiKey ||
!apiSecret ||
!this.verifyLiveKitJwt(authorization, apiKey, apiSecret, rawBody)) {
throw new common_1.UnauthorizedException("Invalid LiveKit webhook authorization");
}
}
else if (apiKey && apiSecret && !this.verifyLiveKitJwt(authorization, apiKey, apiSecret, rawBody)) {
throw new common_1.UnauthorizedException("Invalid LiveKit webhook authorization");
}
else if (!apiKey || !apiSecret) {
this.logger.warn("LIVEKIT_API_KEY / LIVEKIT_API_SECRET not configured — LiveKit webhook verification skipped (dev)");
}
if (await this.checkIdempotency("livekit", body)) {
return { received: true, duplicate: true };
}
const event = String(body?.event || "unknown");
const roomName = body?.room?.name || body?.egressInfo?.roomName || String(body?.roomName || "");
this.logger.log(`LiveKit webhook: ${event} room=${roomName ?? ""}`);
if (event === "room_finished" && roomName) {
const episodeId = this.extractEpisodeIdFromRoom(roomName);
if (episodeId) {
const session = await this.prisma.recordingSession.findUnique({
where: { episodeId },
});
if (session && session.status === "active") {
await this.prisma.recordingSession.update({
where: { id: session.id },
data: { status: "completed", endedAt: new Date() },
});
this.logger.log(`Marked recording session ${session.id} as completed via LiveKit webhook`);
}
}
else {
this.logger.warn(`Could not extract episode ID from room name: ${roomName}`);
}
}
if (event === "egress_ended" ||
event === "egress_completed" ||
event === "recording.completed" ||
event === "recording_completed") {
await this.handleLiveKitRecordingFinished(body);
}
if (event === "participant_joined" || event === "participant_left") {
const participant = body?.participant;
this.logger.log(`Participant ${participant?.identity} ${event} in room ${roomName}`);
}
return { received: true, event, roomName };
}
extractEpisodeIdFromRoom(roomName) {
const match = roomName.match(/^episode-(.+)$/);
return match ? match[1] : null;
}
async handleLiveKitRecordingFinished(body) {
const egressInfo = body?.recording;
const roomName = egressInfo?.name || body?.room?.name;
if (!roomName) {
this.logger.warn("LiveKit recording/egress event missing room name");
return;
}
const episodeId = this.extractEpisodeIdFromRoom(roomName);
if (!episodeId) {
this.logger.warn(`Could not extract episode ID from room name: ${roomName}`);
return;
}
const session = await this.prisma.recordingSession.findUnique({
where: { episodeId },
});
if (!session) {
this.logger.warn(`No recording session found for episode ${episodeId}`);
return;
}
if (session.status === "completed" || session.status === "processing") {
this.logger.log(`Session ${session.id} already ${session.status}, skipping`);
return;
}
await this.prisma.recordingSession.update({
where: { id: session.id },
data: { status: "processing", endedAt: new Date() },
});
this.logger.log(`Session ${session.id} marked as processing after LiveKit recording finished (${egressInfo?.status ?? "unknown"})`);
}
};
exports.IntegrationsWebhookController = IntegrationsWebhookController;
__decorate([
(0, common_1.Post)("calcom"),
(0, common_1.HttpCode)(common_1.HttpStatus.OK),
__param(0, (0, common_1.Body)()),
__param(1, (0, common_1.Headers)("x-cal-secret-key")),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, String]),
__metadata("design:returntype", Promise)
], IntegrationsWebhookController.prototype, "handleCalComWebhook", null);
__decorate([
(0, common_1.Post)("chatwoot/:accountId"),
(0, common_1.HttpCode)(common_1.HttpStatus.OK),
__param(0, (0, common_1.Param)("accountId")),
__param(1, (0, common_1.Req)()),
__param(2, (0, common_1.Body)()),
__param(3, (0, common_1.Headers)("x-chatwoot-signature")),
__param(4, (0, common_1.Headers)("x-chatwoot-timestamp")),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String, Object, Object, String, String]),
__metadata("design:returntype", Promise)
], IntegrationsWebhookController.prototype, "handleChatwootWebhook", null);
__decorate([
(0, common_1.Post)("documenso"),
(0, common_1.HttpCode)(common_1.HttpStatus.OK),
__param(0, (0, common_1.Body)()),
__param(1, (0, common_1.Headers)("x-documenso-secret")),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, String]),
__metadata("design:returntype", Promise)
], IntegrationsWebhookController.prototype, "handleDocumensoWebhook", null);
__decorate([
(0, common_1.Post)("formbricks"),
(0, common_1.HttpCode)(common_1.HttpStatus.OK),
__param(0, (0, common_1.Req)()),
__param(1, (0, common_1.Body)()),
__param(2, (0, common_1.Headers)("webhook-signature")),
__param(3, (0, common_1.Headers)("webhook-id")),
__param(4, (0, common_1.Headers)("webhook-timestamp")),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, String, String]),
__metadata("design:returntype", Promise)
], IntegrationsWebhookController.prototype, "handleFormbricksWebhook", null);
__decorate([
(0, common_1.Post)("listmonk"),
(0, common_1.HttpCode)(common_1.HttpStatus.OK),
__param(0, (0, common_1.Body)()),
__param(1, (0, common_1.Headers)("x-listmonk-secret")),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, String]),
__metadata("design:returntype", Promise)
], IntegrationsWebhookController.prototype, "handleListmonkWebhook", null);
__decorate([
(0, common_1.Post)("livekit"),
(0, common_1.HttpCode)(common_1.HttpStatus.OK),
__param(0, (0, common_1.Req)()),
__param(1, (0, common_1.Body)()),
__param(2, (0, common_1.Headers)("authorization")),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String]),
__metadata("design:returntype", Promise)
], IntegrationsWebhookController.prototype, "handleLiveKitWebhook", null);
exports.IntegrationsWebhookController = IntegrationsWebhookController = IntegrationsWebhookController_1 = __decorate([
(0, common_1.Controller)("integrations/webhooks"),
__metadata("design:paramtypes", [config_1.ConfigService,
prisma_service_1.PrismaService,
webhook_idempotency_service_1.WebhookIdempotencyService,
self_hosted_clients_service_1.SelfHostedClientsService,
chatwoot_sync_service_1.ChatwootSyncService,
events_gateway_1.EventsGateway])
], IntegrationsWebhookController);
//# sourceMappingURL=integrations-webhook.controller.js.map