From d7228daf60be97aee9bf65b544d07d140d2b7ca7 Mon Sep 17 00:00:00 2001 From: NAKAMURA Masayuki Date: Wed, 17 Mar 2021 06:39:34 +0900 Subject: [PATCH] =?UTF-8?q?SingleChoice=E3=80=81Image=E3=80=81Card/Carouse?= =?UTF-8?q?l=E3=81=AE=E3=82=B3=E3=83=B3=E3=83=86=E3=83=B3=E3=83=88?= =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=97=E3=81=AE=E8=A1=A8=E7=A4=BA=E3=81=A8?= =?UTF-8?q?=E3=80=81=E3=82=A2=E3=82=AF=E3=82=B7=E3=83=A7=E3=83=B3=E3=83=9C?= =?UTF-8?q?=E3=82=BF=E3=83=B3=E3=81=8B=E3=82=89=E3=81=AE=E5=85=A5=E5=8A=9B?= =?UTF-8?q?=E3=81=AB=E5=AF=BE=E5=BF=9C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/client.ts | 99 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 89 insertions(+), 10 deletions(-) diff --git a/src/backend/client.ts b/src/backend/client.ts index 815405c..97ad2e4 100644 --- a/src/backend/client.ts +++ b/src/backend/client.ts @@ -12,6 +12,8 @@ const debugOutgoing = debug.sub('outgoing') export const MIDDLEWARE_NAME = 'line.sendMessage' +const outgoingTypes = ['typing', 'text', 'file', 'carousel'] + export class LineClient { private logger: sdk.Logger private lineClient: line.Client @@ -62,6 +64,10 @@ export class LineClient { } else { // TODO: implement handlers for other types of message } + } else if (event.type === 'postback') { + const postback: line.Postback = event.postback + const payload = JSON.parse(postback.data) + await this.sendIncomingEvent(bot.botId, 'text', payload, event.source.userId) } else { // TODO: implement handlers for other types of event } @@ -82,25 +88,98 @@ export class LineClient { } async handleOutgoingEvent(event: sdk.IO.Event, next: sdk.IO.MiddlewareNextCallback) { - const payload = event.payload - - if (payload.type === 'text') { - await this.sendMessage(event, { - type: 'text', - text: payload.text - }) + const messageType = event.type === 'default' ? 'text' : event.type + if (!_.includes(outgoingTypes, messageType)) { + return next(new Error('Unsupported event type: ' + event.type)) + } + if (messageType === 'typing') { + // nothing to do + } else if (event.payload.quick_replies) { + await this.sendSingleChoiceMessage(event) + } else if (messageType === 'text') { + await this.sendTextMessage(event) + } else if (messageType === 'file') { + await this.sendImageMessage(event) + } else if (messageType === 'carousel') { + await this.sendCarouselMessage(event) + } else { + // unsupported other types of event } next(undefined, false) } - async sendMessage(event: sdk.IO.Event, args: any) { + async sendSingleChoiceMessage(event) { + await this.sendMessage(event, { + type: 'text', + text: event.payload.text, + quickReply: { + items: event.payload.quick_replies.map(choice => { + return { + type: 'action', + action: { + type: 'postback', + label: choice.title, + data: JSON.stringify({ + type: 'quick_reply', + text: choice.title, + payload: choice.payload + }), + displayText: choice.title + } + } + }) + } + }) + } + + async sendTextMessage(event) { + await this.sendMessage(event, { + type: 'text', + text: event.payload.text + }) + } + async sendImageMessage(event) { + await this.sendMessage(event, { + type: 'image', + text: event.payload.text, + originalContentUrl: event.payload.url, + previewImageUrl: event.payload.url // TODO: generate preview image by resizing original one + }) + } + + async sendCarouselMessage(event) { + await this.sendMessage(event, { + type: 'template', + altText: 'this is a carousel template', + template: { + type: 'carousel', + columns: event.payload.elements.map(element => { + return { + thumbnailImageUrl: element.picture, + imageBackgroundColor: '#FFFFFF', + title: element.title, + text: element.subtitle, + actions: element.buttons.map(button => { + return { + type: 'message', + label: button.title, + text: button.title + } + }) + } + }), + imageAspectRatio: 'rectangle', + imageSize: 'cover' + } + }) + } + + async sendMessage(event: sdk.IO.Event, args: any) { const message: any = { ...args } - debugOutgoing('Sending message', message) - return this.lineClient.pushMessage(event.target, message) } }