From cbd40647cf482c57dd96f327ee5b3b6d7906c927 Mon Sep 17 00:00:00 2001 From: MrOrz Date: Tue, 17 Oct 2023 01:25:18 +0800 Subject: [PATCH] refactor(context): typing postback action - Default as string - Enable different type of postback action - Simplify handlePostback() argument with SDK types --- src/types/chatbotState.ts | 21 ++++++--------------- src/webhook/handlePostback.ts | 13 +++---------- src/webhook/handlers/utils.ts | 6 +++--- src/webhook/index.ts | 9 ++------- 4 files changed, 14 insertions(+), 35 deletions(-) diff --git a/src/types/chatbotState.ts b/src/types/chatbotState.ts index 0e3401be..81cfc44d 100644 --- a/src/types/chatbotState.ts +++ b/src/types/chatbotState.ts @@ -1,4 +1,4 @@ -import type { Message, MessageEvent } from '@line/bot-sdk'; +import type { Message, MessageEvent, PostbackEvent } from '@line/bot-sdk'; export type ChatbotState = | '__INIT__' @@ -28,18 +28,9 @@ type ArgumentedEventParams = { input: string; }; -export type ChatbotEvent = ( - | MessageEvent - | ServerChooseEvent - /** - * A special format of postback that Chatbot actually uses: postback + input (provided in `ArgumentedEventParams`) - * @FIXME Replace with original PostbackEvent and parse its action to support passing more thing than a string - */ - | { - type: 'postback'; - } -) & - ArgumentedEventParams; +export type ChatbotEvent = + | ((MessageEvent | ServerChooseEvent) & ArgumentedEventParams) + | PostbackEvent; export type Context = { /** Used to differientiate different search sessions (searched text or media) */ @@ -82,8 +73,8 @@ export type ChatbotStateHandler = ( * * @FIXME Replace input: string with something that is more structured */ -export type PostbackActionData = { - input: string; +export type PostbackActionData = { + input: T; sessionId: number; state: ChatbotState; }; diff --git a/src/webhook/handlePostback.ts b/src/webhook/handlePostback.ts index 3afed1c9..9af2f876 100644 --- a/src/webhook/handlePostback.ts +++ b/src/webhook/handlePostback.ts @@ -11,6 +11,7 @@ import { ChatbotState, ChatbotStateHandlerParams, ChatbotStateHandlerReturnType, + PostbackActionData, } from 'src/types/chatbotState'; import { Message } from '@line/bot-sdk'; @@ -24,23 +25,15 @@ import { Message } from '@line/bot-sdk'; */ export default async function handlePostback( { data = {} }, - state: ChatbotState, + postbackData: PostbackActionData, event: ChatbotEvent, userId: string ) { let replies: Message[] = []; - if (event.input === undefined) { - throw new Error('input undefined'); - } - - if (event.type !== 'postback') { - throw new Error('wrong event type'); - } - let params: ChatbotStateHandlerParams | ChatbotStateHandlerReturnType = { data, - state, + state: postbackData.state, event, userId, replies, diff --git a/src/webhook/handlers/utils.ts b/src/webhook/handlers/utils.ts index e27412f8..ed7d0ae2 100644 --- a/src/webhook/handlers/utils.ts +++ b/src/webhook/handlers/utils.ts @@ -34,15 +34,15 @@ const splitter = new GraphemeSplitter(); * @param sessionId - Current session ID * @param state - the state that processes the postback */ -export function createPostbackAction( +export function createPostbackAction( label: string, - input: string, + input: INPUT, displayText: string, sessionId: number, state: ChatbotState ): Action { // Ensure the data type before stringification - const data: PostbackActionData = { + const data: PostbackActionData = { input, sessionId, state, diff --git a/src/webhook/index.ts b/src/webhook/index.ts index d9f4cf21..24443770 100644 --- a/src/webhook/index.ts +++ b/src/webhook/index.ts @@ -152,12 +152,9 @@ const singleUserHandler = async ( }) .send(); } else if (webhookEvent.type === 'postback') { - /** - * @FIXME Replace with runtime type check to be future-proof - */ const postbackData = JSON.parse( webhookEvent.postback.data - ) as PostbackActionData; + ) as PostbackActionData; // Handle the case when user context in redis is expired if (!context.data) { @@ -195,9 +192,7 @@ const singleUserHandler = async ( return; } - const input = postbackData.input; - const event: ChatbotEvent = { type: webhookEvent.type, input }; - result = await handlePostback(context, postbackData.state, event, userId); + result = await handlePostback(context, postbackData, webhookEvent, userId); } if (isReplied) {