| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  | import { v4 } from "uuid"; | 
					
						
							| 
									
										
										
										
											2021-10-25 16:15:52 +00:00
										 |  |  | import { z } from "zod"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import { getErrorFromUnknown } from "@lib/errors"; | 
					
						
							| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  | import { WEBHOOK_TRIGGER_EVENTS } from "@lib/webhooks/constants"; | 
					
						
							| 
									
										
										
										
											2021-11-22 11:37:07 +00:00
										 |  |  | import sendPayload from "@lib/webhooks/sendPayload"; | 
					
						
							| 
									
										
										
										
											2021-10-25 16:15:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | import { createProtectedRouter } from "@server/createRouter"; | 
					
						
							| 
									
										
										
										
											2022-02-10 10:44:46 +00:00
										 |  |  | import { getTranslation } from "@server/lib/i18n"; | 
					
						
							| 
									
										
										
										
											2021-10-25 16:15:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  | export const webhookRouter = createProtectedRouter() | 
					
						
							|  |  |  |   .query("list", { | 
					
						
							| 
									
										
										
										
											2022-03-02 16:24:57 +00:00
										 |  |  |     input: z | 
					
						
							|  |  |  |       .object({ | 
					
						
							|  |  |  |         eventTypeId: z.number().optional(), | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |       .optional(), | 
					
						
							|  |  |  |     async resolve({ ctx, input }) { | 
					
						
							|  |  |  |       if (input?.eventTypeId) { | 
					
						
							|  |  |  |         return await ctx.prisma.webhook.findMany({ | 
					
						
							|  |  |  |           where: { | 
					
						
							|  |  |  |             eventTypeId: input.eventTypeId, | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  |       return await ctx.prisma.webhook.findMany({ | 
					
						
							|  |  |  |         where: { | 
					
						
							|  |  |  |           userId: ctx.user.id, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  |   .mutation("create", { | 
					
						
							|  |  |  |     input: z.object({ | 
					
						
							|  |  |  |       subscriberUrl: z.string().url(), | 
					
						
							|  |  |  |       eventTriggers: z.enum(WEBHOOK_TRIGGER_EVENTS).array(), | 
					
						
							|  |  |  |       active: z.boolean(), | 
					
						
							| 
									
										
										
										
											2022-02-18 17:49:39 +00:00
										 |  |  |       payloadTemplate: z.string().nullable(), | 
					
						
							| 
									
										
										
										
											2022-03-02 16:24:57 +00:00
										 |  |  |       eventTypeId: z.number().optional(), | 
					
						
							| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  |     }), | 
					
						
							|  |  |  |     async resolve({ ctx, input }) { | 
					
						
							| 
									
										
										
										
											2022-03-02 16:24:57 +00:00
										 |  |  |       if (input.eventTypeId) { | 
					
						
							|  |  |  |         return await ctx.prisma.webhook.create({ | 
					
						
							|  |  |  |           data: { | 
					
						
							|  |  |  |             id: v4(), | 
					
						
							|  |  |  |             ...input, | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  |       return await ctx.prisma.webhook.create({ | 
					
						
							|  |  |  |         data: { | 
					
						
							|  |  |  |           id: v4(), | 
					
						
							|  |  |  |           userId: ctx.user.id, | 
					
						
							|  |  |  |           ...input, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  |   .mutation("edit", { | 
					
						
							|  |  |  |     input: z.object({ | 
					
						
							|  |  |  |       id: z.string(), | 
					
						
							|  |  |  |       subscriberUrl: z.string().url().optional(), | 
					
						
							|  |  |  |       eventTriggers: z.enum(WEBHOOK_TRIGGER_EVENTS).array().optional(), | 
					
						
							|  |  |  |       active: z.boolean().optional(), | 
					
						
							| 
									
										
										
										
											2021-11-22 11:37:07 +00:00
										 |  |  |       payloadTemplate: z.string().nullable(), | 
					
						
							| 
									
										
										
										
											2022-03-02 16:24:57 +00:00
										 |  |  |       eventTypeId: z.number().optional(), | 
					
						
							| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  |     }), | 
					
						
							|  |  |  |     async resolve({ ctx, input }) { | 
					
						
							|  |  |  |       const { id, ...data } = input; | 
					
						
							| 
									
										
										
										
											2022-03-02 16:24:57 +00:00
										 |  |  |       const webhook = input.eventTypeId | 
					
						
							|  |  |  |         ? await ctx.prisma.webhook.findFirst({ | 
					
						
							|  |  |  |             where: { | 
					
						
							|  |  |  |               eventTypeId: input.eventTypeId, | 
					
						
							|  |  |  |               id, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |           }) | 
					
						
							|  |  |  |         : await ctx.prisma.webhook.findFirst({ | 
					
						
							|  |  |  |             where: { | 
					
						
							|  |  |  |               userId: ctx.user.id, | 
					
						
							|  |  |  |               id, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  |       if (!webhook) { | 
					
						
							|  |  |  |         // user does not own this webhook
 | 
					
						
							| 
									
										
										
										
											2022-03-02 16:24:57 +00:00
										 |  |  |         // team event doesn't own this webhook
 | 
					
						
							| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  |         return null; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return await ctx.prisma.webhook.update({ | 
					
						
							|  |  |  |         where: { | 
					
						
							|  |  |  |           id, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         data, | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  |   .mutation("delete", { | 
					
						
							|  |  |  |     input: z.object({ | 
					
						
							|  |  |  |       id: z.string(), | 
					
						
							| 
									
										
										
										
											2022-03-02 16:24:57 +00:00
										 |  |  |       eventTypeId: z.number().optional(), | 
					
						
							| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  |     }), | 
					
						
							|  |  |  |     async resolve({ ctx, input }) { | 
					
						
							|  |  |  |       const { id } = input; | 
					
						
							| 
									
										
										
										
											2021-10-29 14:13:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-02 16:24:57 +00:00
										 |  |  |       input.eventTypeId | 
					
						
							|  |  |  |         ? await ctx.prisma.eventType.update({ | 
					
						
							|  |  |  |             where: { | 
					
						
							|  |  |  |               id: input.eventTypeId, | 
					
						
							| 
									
										
										
										
											2022-03-02 15:30:13 +00:00
										 |  |  |             }, | 
					
						
							| 
									
										
										
										
											2022-03-02 16:24:57 +00:00
										 |  |  |             data: { | 
					
						
							|  |  |  |               webhooks: { | 
					
						
							|  |  |  |                 delete: { | 
					
						
							|  |  |  |                   id, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |               }, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |           }) | 
					
						
							|  |  |  |         : await ctx.prisma.user.update({ | 
					
						
							|  |  |  |             where: { | 
					
						
							|  |  |  |               id: ctx.user.id, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             data: { | 
					
						
							|  |  |  |               webhooks: { | 
					
						
							|  |  |  |                 delete: { | 
					
						
							|  |  |  |                   id, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |               }, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2021-10-25 16:15:52 +00:00
										 |  |  |       return { | 
					
						
							| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  |         id, | 
					
						
							| 
									
										
										
										
											2021-10-25 16:15:52 +00:00
										 |  |  |       }; | 
					
						
							| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  |     }, | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  |   .mutation("testTrigger", { | 
					
						
							|  |  |  |     input: z.object({ | 
					
						
							|  |  |  |       url: z.string().url(), | 
					
						
							|  |  |  |       type: z.string(), | 
					
						
							| 
									
										
										
										
											2021-11-22 11:37:07 +00:00
										 |  |  |       payloadTemplate: z.string().optional().nullable(), | 
					
						
							| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  |     }), | 
					
						
							|  |  |  |     async resolve({ input }) { | 
					
						
							| 
									
										
										
										
											2021-11-22 11:37:07 +00:00
										 |  |  |       const { url, type, payloadTemplate } = input; | 
					
						
							| 
									
										
										
										
											2022-02-10 10:44:46 +00:00
										 |  |  |       const translation = await getTranslation("en", "common"); | 
					
						
							|  |  |  |       const language = { | 
					
						
							|  |  |  |         locale: "en", | 
					
						
							|  |  |  |         translate: translation, | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-22 11:37:07 +00:00
										 |  |  |       const data = { | 
					
						
							|  |  |  |         type: "Test", | 
					
						
							|  |  |  |         title: "Test trigger event", | 
					
						
							|  |  |  |         description: "", | 
					
						
							|  |  |  |         startTime: new Date().toISOString(), | 
					
						
							|  |  |  |         endTime: new Date().toISOString(), | 
					
						
							|  |  |  |         attendees: [ | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |             email: "jdoe@example.com", | 
					
						
							|  |  |  |             name: "John Doe", | 
					
						
							|  |  |  |             timeZone: "Europe/London", | 
					
						
							| 
									
										
										
										
											2022-02-10 10:44:46 +00:00
										 |  |  |             language, | 
					
						
							| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  |           }, | 
					
						
							| 
									
										
										
										
											2021-11-22 11:37:07 +00:00
										 |  |  |         ], | 
					
						
							|  |  |  |         organizer: { | 
					
						
							|  |  |  |           name: "Cal", | 
					
						
							|  |  |  |           email: "", | 
					
						
							|  |  |  |           timeZone: "Europe/London", | 
					
						
							| 
									
										
										
										
											2022-02-10 10:44:46 +00:00
										 |  |  |           language, | 
					
						
							| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  |         }, | 
					
						
							| 
									
										
										
										
											2021-10-25 16:15:52 +00:00
										 |  |  |       }; | 
					
						
							| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       try { | 
					
						
							| 
									
										
										
										
											2021-11-22 11:37:07 +00:00
										 |  |  |         return await sendPayload(type, new Date().toISOString(), url, data, payloadTemplate); | 
					
						
							| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  |       } catch (_err) { | 
					
						
							| 
									
										
										
										
											2021-11-22 11:37:07 +00:00
										 |  |  |         const error = getErrorFromUnknown(_err); | 
					
						
							| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  |         return { | 
					
						
							| 
									
										
										
										
											2021-11-22 11:37:07 +00:00
										 |  |  |           ok: false, | 
					
						
							| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  |           status: 500, | 
					
						
							| 
									
										
										
										
											2021-11-22 11:37:07 +00:00
										 |  |  |           message: error.message, | 
					
						
							| 
									
										
										
										
											2021-10-28 22:52:39 +00:00
										 |  |  |         }; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   }); |