cal.pub0.org/packages/app-store/larkcalendar/api/events.ts

124 lines
3.4 KiB
TypeScript

import type { NextApiRequest, NextApiResponse } from "next";
import { z } from "zod";
import logger from "@calcom/lib/logger";
import { defaultHandler, defaultResponder } from "@calcom/lib/server";
import prisma from "@calcom/prisma";
import { getAppKeys } from "../common";
import { sendPostMsg } from "../lib/BotService";
const log = logger.getChildLogger({ prefix: [`[lark/api/events]`] });
const larkKeysSchema = z.object({
open_verification_token: z.string(),
});
const appTicketEventsReqSchema = z.object({
body: z.object({
event: z.object({
app_ticket: z.string().min(1),
}),
}),
});
const imMessageReceivedEventsReqSchema = z.object({
body: z.object({
header: z.object({
tenant_key: z.string().min(1),
}),
event: z.object({
sender: z.object({
sender_id: z.object({
open_id: z.string().min(1),
}),
}),
}),
}),
});
const p2pChatCreateEventsReqSchema = z.object({
body: z.object({
tenant_key: z.string().min(1),
event: z.object({
user: z.object({
open_id: z.string().min(1),
}),
}),
}),
});
async function postHandler(req: NextApiRequest, res: NextApiResponse) {
log.debug("receive events", req.body);
const appKeys = await getAppKeys();
const { open_verification_token } = larkKeysSchema.parse(appKeys);
// used for events handler binding in lark open platform, see
// https://open.larksuite.com/document/ukTMukTMukTM/uUTNz4SN1MjL1UzM?lang=en-US
if (req.body.type === "url_verification" && req.body.token === open_verification_token) {
log.debug("update token", req.body);
return res.status(200).json({ challenge: req.body.challenge });
}
// used for receiving app_ticket, see
// https://open.larksuite.com/document/uAjLw4CM/ukTMukTMukTM/application-v6/event/app_ticket-events
if (req.body.event?.type === "app_ticket" && open_verification_token === req.body.token) {
const {
body: {
event: { app_ticket: appTicket },
},
} = appTicketEventsReqSchema.parse(req);
await prisma.app.update({
where: { slug: "lark-calendar" },
data: {
keys: {
...appKeys,
app_ticket: appTicket,
},
},
});
return res.status(200).json({ code: 0, msg: "success" });
}
// used for handle user at bot in lark chat with cal.com connector bot, see
// https://open.larksuite.com/document/uAjLw4CM/ukTMukTMukTM/reference/im-v1/message/events/receive
if (req.body.header?.event_type === "im.message.receive_v1") {
const {
body: {
header: { tenant_key: tenantKey },
event: {
sender: {
sender_id: { open_id: senderOpenId },
},
},
},
} = imMessageReceivedEventsReqSchema.parse(req);
sendPostMsg(tenantKey, senderOpenId);
return res.status(200).json({ code: 0, msg: "success" });
}
// used for handle user first talk with cal.com connector bot, see
// https://open.larksuite.com/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/bot-events
if (req.body.event?.type === "p2p_chat_create") {
const {
body: {
tenant_key: tenantKey,
event: {
user: { open_id: senderOpenId },
},
},
} = p2pChatCreateEventsReqSchema.parse(req);
sendPostMsg(tenantKey, senderOpenId);
return res.status(200).json({ code: 0, msg: "success" });
}
}
export default defaultHandler({
POST: Promise.resolve({ default: defaultResponder(postHandler) }),
});