From d71f6afb7f7bb5c9a3c3be0b56111ea4a45ac7b2 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 14 Feb 2026 13:35:04 +0000 Subject: [PATCH] refactor(line): centralize action helpers --- src/line/actions.ts | 61 +++++++++++++++++++++++++++++++ src/line/rich-menu.ts | 59 ++---------------------------- src/line/template-messages.ts | 68 +++++------------------------------ 3 files changed, 72 insertions(+), 116 deletions(-) create mode 100644 src/line/actions.ts diff --git a/src/line/actions.ts b/src/line/actions.ts new file mode 100644 index 000000000..198645110 --- /dev/null +++ b/src/line/actions.ts @@ -0,0 +1,61 @@ +import type { messagingApi } from "@line/bot-sdk"; + +export type Action = messagingApi.Action; + +/** + * Create a message action (sends text when tapped) + */ +export function messageAction(label: string, text?: string): Action { + return { + type: "message", + label: label.slice(0, 20), + text: text ?? label, + }; +} + +/** + * Create a URI action (opens a URL when tapped) + */ +export function uriAction(label: string, uri: string): Action { + return { + type: "uri", + label: label.slice(0, 20), + uri, + }; +} + +/** + * Create a postback action (sends data to webhook when tapped) + */ +export function postbackAction(label: string, data: string, displayText?: string): Action { + return { + type: "postback", + label: label.slice(0, 20), + data: data.slice(0, 300), + displayText: displayText?.slice(0, 300), + }; +} + +/** + * Create a datetime picker action + */ +export function datetimePickerAction( + label: string, + data: string, + mode: "date" | "time" | "datetime", + options?: { + initial?: string; + max?: string; + min?: string; + }, +): Action { + return { + type: "datetimepicker", + label: label.slice(0, 20), + data: data.slice(0, 300), + mode, + initial: options?.initial, + max: options?.max, + min: options?.min, + }; +} diff --git a/src/line/rich-menu.ts b/src/line/rich-menu.ts index 670ac9b76..f1a083a49 100644 --- a/src/line/rich-menu.ts +++ b/src/line/rich-menu.ts @@ -3,6 +3,7 @@ import { readFile } from "node:fs/promises"; import { loadConfig } from "../config/config.js"; import { logVerbose } from "../globals.js"; import { resolveLineAccount } from "./accounts.js"; +import { datetimePickerAction, messageAction, postbackAction, uriAction } from "./actions.js"; type RichMenuRequest = messagingApi.RichMenuRequest; type RichMenuResponse = messagingApi.RichMenuResponse; @@ -382,63 +383,7 @@ export function createGridLayout( ]; } -/** - * Create a message action (sends text when tapped) - */ -export function messageAction(label: string, text?: string): Action { - return { - type: "message", - label: label.slice(0, 20), - text: text ?? label, - }; -} - -/** - * Create a URI action (opens a URL when tapped) - */ -export function uriAction(label: string, uri: string): Action { - return { - type: "uri", - label: label.slice(0, 20), - uri, - }; -} - -/** - * Create a postback action (sends data to webhook when tapped) - */ -export function postbackAction(label: string, data: string, displayText?: string): Action { - return { - type: "postback", - label: label.slice(0, 20), - data: data.slice(0, 300), - displayText: displayText?.slice(0, 300), - }; -} - -/** - * Create a datetime picker action - */ -export function datetimePickerAction( - label: string, - data: string, - mode: "date" | "time" | "datetime", - options?: { - initial?: string; - max?: string; - min?: string; - }, -): Action { - return { - type: "datetimepicker", - label: label.slice(0, 20), - data: data.slice(0, 300), - mode, - initial: options?.initial, - max: options?.max, - min: options?.min, - }; -} +export { datetimePickerAction, messageAction, postbackAction, uriAction }; /** * Create a default help/status/settings menu diff --git a/src/line/template-messages.ts b/src/line/template-messages.ts index 686dc8337..b6e9bd2fc 100644 --- a/src/line/template-messages.ts +++ b/src/line/template-messages.ts @@ -1,4 +1,13 @@ import type { messagingApi } from "@line/bot-sdk"; +import { + datetimePickerAction, + messageAction, + postbackAction, + uriAction, + type Action, +} from "./actions.js"; + +export { datetimePickerAction, messageAction, postbackAction, uriAction }; type TemplateMessage = messagingApi.TemplateMessage; type ConfirmTemplate = messagingApi.ConfirmTemplate; @@ -7,7 +16,6 @@ type CarouselTemplate = messagingApi.CarouselTemplate; type CarouselColumn = messagingApi.CarouselColumn; type ImageCarouselTemplate = messagingApi.ImageCarouselTemplate; type ImageCarouselColumn = messagingApi.ImageCarouselColumn; -type Action = messagingApi.Action; /** * Create a confirm template (yes/no style dialog) @@ -147,64 +155,6 @@ export function createImageCarouselColumn(imageUrl: string, action: Action): Ima // Action Helpers (same as rich-menu but re-exported for convenience) // ============================================================================ -/** - * Create a message action (sends text when tapped) - */ -export function messageAction(label: string, text?: string): Action { - return { - type: "message", - label: label.slice(0, 20), - text: text ?? label, - }; -} - -/** - * Create a URI action (opens a URL when tapped) - */ -export function uriAction(label: string, uri: string): Action { - return { - type: "uri", - label: label.slice(0, 20), - uri, - }; -} - -/** - * Create a postback action (sends data to webhook when tapped) - */ -export function postbackAction(label: string, data: string, displayText?: string): Action { - return { - type: "postback", - label: label.slice(0, 20), - data: data.slice(0, 300), - displayText: displayText?.slice(0, 300), - }; -} - -/** - * Create a datetime picker action - */ -export function datetimePickerAction( - label: string, - data: string, - mode: "date" | "time" | "datetime", - options?: { - initial?: string; - max?: string; - min?: string; - }, -): Action { - return { - type: "datetimepicker", - label: label.slice(0, 20), - data: data.slice(0, 300), - mode, - initial: options?.initial, - max: options?.max, - min: options?.min, - }; -} - // ============================================================================ // Convenience Builders // ============================================================================