mirror of
https://github.com/documenso/documenso.git
synced 2025-11-10 04:22:32 +10:00
zapier webhooks
This commit is contained in:
3
apps/web/src/pages/api/v1/me/index.ts
Normal file
3
apps/web/src/pages/api/v1/me/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { testCredentialsHandler } from '@documenso/lib/server-only/public-api/test-credentials';
|
||||
|
||||
export default testCredentialsHandler;
|
||||
3
apps/web/src/pages/api/v1/zapier/list-documents/index.ts
Normal file
3
apps/web/src/pages/api/v1/zapier/list-documents/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { listDocumentsHandler } from '@documenso/lib/server-only/webhooks/zapier/list-documents';
|
||||
|
||||
export default listDocumentsHandler;
|
||||
@ -0,0 +1,3 @@
|
||||
import { signedDocumentHandler } from '@documenso/lib/server-only/webhooks/zapier/signed-document';
|
||||
|
||||
export default signedDocumentHandler;
|
||||
3
apps/web/src/pages/api/v1/zapier/subscribe/index.ts
Normal file
3
apps/web/src/pages/api/v1/zapier/subscribe/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { subscribeHandler } from '@documenso/lib/server-only/webhooks/zapier/subscribe';
|
||||
|
||||
export default subscribeHandler;
|
||||
3
apps/web/src/pages/api/v1/zapier/unsubscribe/index.ts
Normal file
3
apps/web/src/pages/api/v1/zapier/unsubscribe/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { unsubscribeHandler } from '@documenso/lib/server-only/webhooks/zapier/unsubscribe';
|
||||
|
||||
export default unsubscribeHandler;
|
||||
31
packages/lib/server-only/public-api/test-credentials.ts
Normal file
31
packages/lib/server-only/public-api/test-credentials.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
|
||||
import { getUserByApiToken } from './get-user-by-token';
|
||||
|
||||
export const testCredentialsHandler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
try {
|
||||
const { authorization } = req.headers;
|
||||
|
||||
// Support for both "Authorization: Bearer api_xxx" and "Authorization: api_xxx"
|
||||
const [token] = (authorization || '').split('Bearer ').filter((s) => s.length > 0);
|
||||
|
||||
if (!token) {
|
||||
return res.status(500).json({
|
||||
body: {
|
||||
message: 'API token was not provided',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const user = await getUserByApiToken({ token });
|
||||
|
||||
return res.status(200).json({
|
||||
username: user.name,
|
||||
email: user.email,
|
||||
});
|
||||
} catch (err) {
|
||||
return res.status(500).json({
|
||||
message: 'Internal Server Error',
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -5,7 +5,7 @@ export type GetAllWebhooksOptions = {
|
||||
eventTrigger: WebhookTriggerEvents;
|
||||
};
|
||||
|
||||
export const getAllWebhooks = async ({ eventTrigger }: GetAllWebhooksOptions) => {
|
||||
export const getAllWebhooksByEventTrigger = async ({ eventTrigger }: GetAllWebhooksOptions) => {
|
||||
return prisma.webhook.findMany({
|
||||
where: {
|
||||
eventTriggers: {
|
||||
45
packages/lib/server-only/webhooks/zapier/list-documents.ts
Normal file
45
packages/lib/server-only/webhooks/zapier/list-documents.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
|
||||
import { findDocuments } from '@documenso/lib/server-only/document/find-documents';
|
||||
|
||||
import { getWebhooksByUserId } from '../get-webhooks-by-user-id';
|
||||
import { validateApiToken } from './validateApiToken';
|
||||
|
||||
export const listDocumentsHandler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
try {
|
||||
const { authorization } = req.headers;
|
||||
const user = await validateApiToken({ authorization });
|
||||
|
||||
const documents = await findDocuments({ userId: user.id });
|
||||
const allWebhooks = await getWebhooksByUserId(user.id);
|
||||
|
||||
if (documents.data.length > 0 && allWebhooks.length > 0) {
|
||||
const testWebhook = {
|
||||
event: allWebhooks[0].eventTriggers.toString(),
|
||||
createdAt: allWebhooks[0].createdAt,
|
||||
webhookEndpoint: allWebhooks[0].webhookUrl,
|
||||
payload: {
|
||||
id: documents.data[0].id,
|
||||
userId: documents.data[0].userId,
|
||||
title: documents.data[0].title,
|
||||
status: documents.data[0].status,
|
||||
documentDataId: documents.data[0].documentDataId,
|
||||
createdAt: documents.data[0].createdAt,
|
||||
updatedAt: documents.data[0].updatedAt,
|
||||
completedAt: documents.data[0].completedAt,
|
||||
deletedAt: documents.data[0].deletedAt,
|
||||
teamId: documents.data[0].teamId,
|
||||
},
|
||||
};
|
||||
|
||||
return res.status(200).json([testWebhook]);
|
||||
}
|
||||
|
||||
return res.status(200).json([]);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return res.status(500).json({
|
||||
message: 'Internal Server Error',
|
||||
});
|
||||
}
|
||||
};
|
||||
67
packages/lib/server-only/webhooks/zapier/signed-document.ts
Normal file
67
packages/lib/server-only/webhooks/zapier/signed-document.ts
Normal file
@ -0,0 +1,67 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
|
||||
import { findDocuments } from '@documenso/lib/server-only/document/find-documents';
|
||||
import { getRecipientsForDocument } from '@documenso/lib/server-only/recipient/get-recipients-for-document';
|
||||
|
||||
import { getWebhooksByUserId } from '../get-webhooks-by-user-id';
|
||||
import { validateApiToken } from './validateApiToken';
|
||||
|
||||
export const signedDocumentHandler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
try {
|
||||
const { authorization } = req.headers;
|
||||
const user = await validateApiToken({ authorization });
|
||||
|
||||
const documents = await findDocuments({ userId: user.id });
|
||||
|
||||
const allWebhooks = await getWebhooksByUserId(user.id);
|
||||
const recipients = await getRecipientsForDocument({
|
||||
documentId: documents.data[0].id,
|
||||
userId: user.id,
|
||||
});
|
||||
|
||||
if (documents.data.length > 0 && allWebhooks.length > 0 && recipients.length > 0) {
|
||||
const testWebhook = {
|
||||
event: allWebhooks[0].eventTriggers.toString(),
|
||||
createdAt: allWebhooks[0].createdAt,
|
||||
webhookEndpoint: allWebhooks[0].webhookUrl,
|
||||
payload: {
|
||||
id: documents.data[0].id,
|
||||
userId: documents.data[0].userId,
|
||||
title: documents.data[0].title,
|
||||
status: documents.data[0].status,
|
||||
documentDataId: documents.data[0].documentDataId,
|
||||
createdAt: documents.data[0].createdAt,
|
||||
updatedAt: documents.data[0].updatedAt,
|
||||
completedAt: documents.data[0].completedAt,
|
||||
deletedAt: documents.data[0].deletedAt,
|
||||
teamId: documents.data[0].teamId,
|
||||
Recipient: [
|
||||
{
|
||||
id: recipients[0].id,
|
||||
documentId: recipients[0].documentId,
|
||||
templateId: recipients[0].templateId,
|
||||
email: recipients[0].email,
|
||||
name: recipients[0].name,
|
||||
token: recipients[0].token,
|
||||
expired: recipients[0].expired,
|
||||
signedAt: recipients[0].signedAt,
|
||||
role: recipients[0].role,
|
||||
readStatus: recipients[0].readStatus,
|
||||
signingStatus: recipients[0].signingStatus,
|
||||
sendStatus: recipients[0].sendStatus,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
return res.status(200).json([testWebhook]);
|
||||
}
|
||||
|
||||
return res.status(200).json([]);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return res.status(500).json({
|
||||
message: 'Internal Server Error',
|
||||
});
|
||||
}
|
||||
};
|
||||
29
packages/lib/server-only/webhooks/zapier/subscribe.ts
Normal file
29
packages/lib/server-only/webhooks/zapier/subscribe.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import { validateApiToken } from './validateApiToken';
|
||||
|
||||
export const subscribeHandler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
try {
|
||||
const { authorization } = req.headers;
|
||||
const { webhookUrl, eventTrigger } = req.body;
|
||||
const user = await validateApiToken({ authorization });
|
||||
|
||||
const createdWebhook = await prisma.webhook.create({
|
||||
data: {
|
||||
webhookUrl,
|
||||
eventTriggers: [eventTrigger],
|
||||
secret: null,
|
||||
enabled: true,
|
||||
userId: user.id,
|
||||
},
|
||||
});
|
||||
|
||||
return res.status(200).json(createdWebhook);
|
||||
} catch (err) {
|
||||
return res.status(500).json({
|
||||
message: 'Internal Server Error',
|
||||
});
|
||||
}
|
||||
};
|
||||
26
packages/lib/server-only/webhooks/zapier/unsubscribe.ts
Normal file
26
packages/lib/server-only/webhooks/zapier/unsubscribe.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import { validateApiToken } from './validateApiToken';
|
||||
|
||||
export const unsubscribeHandler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
try {
|
||||
const { authorization } = req.headers;
|
||||
const { webhookId } = req.body;
|
||||
const user = await validateApiToken({ authorization });
|
||||
|
||||
const deletedWebhook = await prisma.webhook.delete({
|
||||
where: {
|
||||
id: webhookId,
|
||||
userId: user.id,
|
||||
},
|
||||
});
|
||||
|
||||
return res.status(200).json(deletedWebhook);
|
||||
} catch (err) {
|
||||
return res.status(500).json({
|
||||
message: 'Internal Server Error',
|
||||
});
|
||||
}
|
||||
};
|
||||
16
packages/lib/server-only/webhooks/zapier/validateApiToken.ts
Normal file
16
packages/lib/server-only/webhooks/zapier/validateApiToken.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { getUserByApiToken } from '../../public-api/get-user-by-token';
|
||||
|
||||
type ValidateApiTokenOptions = {
|
||||
authorization: string | undefined;
|
||||
};
|
||||
|
||||
export const validateApiToken = async ({ authorization }: ValidateApiTokenOptions) => {
|
||||
try {
|
||||
// Support for both "Authorization: Bearer api_xxx" and "Authorization: api_xxx"
|
||||
const [token] = (authorization || '').split('Bearer ').filter((s) => s.length > 0);
|
||||
|
||||
return await getUserByApiToken({ token });
|
||||
} catch (err) {
|
||||
throw new Error(`Failed to validate API token`);
|
||||
}
|
||||
};
|
||||
@ -1,6 +1,6 @@
|
||||
import type { Document, WebhookTriggerEvents } from '@documenso/prisma/client';
|
||||
|
||||
import { getAllWebhooks } from '../server-only/webhooks/get-all-webhooks';
|
||||
import { getAllWebhooksByEventTrigger } from '../server-only/webhooks/get-all-webhooks-by-event-trigger';
|
||||
import { postWebhookPayload } from './post-webhook-payload';
|
||||
|
||||
export type TriggerWebhookOptions = {
|
||||
@ -10,7 +10,7 @@ export type TriggerWebhookOptions = {
|
||||
|
||||
export const triggerWebhook = async ({ eventTrigger, documentData }: TriggerWebhookOptions) => {
|
||||
try {
|
||||
const allWebhooks = await getAllWebhooks({ eventTrigger });
|
||||
const allWebhooks = await getAllWebhooksByEventTrigger({ eventTrigger });
|
||||
|
||||
const webhookPromises = allWebhooks.map((webhook) => {
|
||||
const { webhookUrl, secret } = webhook;
|
||||
|
||||
Reference in New Issue
Block a user