Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | 1x | import { EncryptedValue, generateJwt, issueChannelAccessToken, } from "@messaging-gateway/lib"; import { PrismaClient } from "@prisma/client"; import { messagingApi, HTTPFetchError } from "@line/bot-sdk"; import { v4 as uuidv4 } from "uuid"; import { Env } from "@/Env"; import { Logger } from "@/Logger"; import { ErrorObject } from "@/types/api"; import express from "express"; export async function POST( env: Env, parentLogger: Logger, req: express.Request, res: express.Response ) { const requestId = uuidv4(); const logger = parentLogger.child({ requestId }); const channelId = req.get("X-MessagingGateway-Line-Channel-Id"); const body = req.body as messagingApi.PushMessageRequest; logger.info("received request", { channelId, body }); if (!channelId) { const errObj: ErrorObject = { message: "X-MessagingGateway-Line-Channel-Id is empty or not exists", }; res.status(400).json(errObj); return; } const childLogger = logger.child({ channelId }); const resObj = await sendMessage(env, channelId, body, childLogger); if (typeof resObj === "string") { const errObj: ErrorObject = { message: resObj }; res.status(400).json(errObj); } else { childLogger.info("success to send message"); res.status(200).json(resObj); } } async function sendMessage( env: Env, channelId: string, body: messagingApi.PushMessageRequest, logger: Logger ): Promise<messagingApi.PushMessageResponse | string> { const prisma = new PrismaClient(); const lineChannel = await prisma.line_channels.findUnique({ where: { id: channelId, }, }); if (!lineChannel) { logger.error("failed to find lineChannel, channel is not found"); return `channel(id=${channelId}) is not found`; } logger.debug("found lineChannel record"); const encryptedSecretKey = EncryptedValue.makeFromSerializedText( lineChannel.encrypted_secret_key ); const secretKey = encryptedSecretKey.decrypt(env.encryptionPassword); logger.debug("decrypted secret key"); const kid = lineChannel.kid; const tokenExpSec = 60 * 1; const jwt = await generateJwt(channelId, secretKey.value(), kid, tokenExpSec); logger.debug("generated jwt"); let accessToken: string; try { const result = await issueChannelAccessToken(jwt); accessToken = result.accessToken; } catch (err) { let msg = "failed to issue channel access token"; if (err instanceof HTTPFetchError) { try { const body = JSON.parse(err.body); msg += `, ${body.error}(${body.error_description})`; } catch (err) { logger.warn("failed to parse response", { message: err }); } } logger.error(msg, { message: err }); return msg; } logger.debug("issued channel access token"); const client = new messagingApi.MessagingApiClient({ channelAccessToken: accessToken, }); try { return await client.pushMessage(body); } catch (err) { let msg = "failed to push message"; try { if (err instanceof HTTPFetchError) { const body = JSON.parse(err.body) as messagingApi.ErrorResponse; for (const detail of body.details) { msg += `, ${detail.message}(${detail.property})`; } } } catch (err) { logger.warn("failed to parse response", { message: err }); } logger.error(msg, { message: err }); return msg; } } |