LINEのWebhook URLをGAS (Google Apps Script)で作成する場合のテンプレートを以下に示す。
// channel access token (long lived) LINE Developers const ACCESS_TOKEN = '{アクセストークン}'; /** * POSTメッセージ受付処理 */ function doPost(e) { // イベントの取得 var events = JSON.parse(e.postData.contents).events; // イベントループ events.forEach(function(event){ // WebHookで受信した応答用Token var replyToken = event.replyToken; // ユーザID var userId = event.source.userId; var responseMessage = []; // イベントタイプによって処理を分岐 switch(event.type) { // テキストイベント case 'message': const userMessage = event.message.text; responseMessage = respondUser(userMessage, userId); break; // ポストバックイベント case 'postback': const data = event.postback.data responseMessage = respondPostback(data, userId); break; default: responseMessage.push({'type':'text','text':'unknown type=' + event.type}); } // 応答メッセージ用のAPI URL var url = 'https://api.line.me/v2/bot/message/reply'; UrlFetchApp.fetch(url, { 'headers': { 'Content-Type': 'application/json; charset=UTF-8', 'Authorization': 'Bearer ' + ACCESS_TOKEN, }, 'method': 'post', 'payload': JSON.stringify({ 'replyToken': replyToken, 'messages': responseMessage, }), }); }); return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON); } /** * ユーザが入力したメッセージに応じた処理を行って応答メッセージを返す */ function respondUser(userMessage,userId) { let res = new Response(); const userSheet = getUserSheet(userId); // ユーザメッセージに応じてレスポンスを変える if(userMessage == 'こんにちは'){ res.pushLineText('はい、こんにちは。ようこそ服薬管理デモへ!'); res.pushLineSticker('11537','52002738'); } else if(userMessage == '私は誰'){ res.pushLineText(userId); } else { res.pushLineText(userMessage + 'ですか?'); } return res.getMessage(); } /** * ポストバックイベントハンドラ */ function respondPostback(data, userId) { let res = new Response(); const userSheet = getUserSheet(userId); res.pushLineText('data=' + data); return res.getMessage(); } /** * userIdからユーザシートを取得する */ function getUserSheet(userId) { var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(userId); if (sheet == null) { // シートがない場合は作成する sheet = SpreadsheetApp.getActiveSpreadsheet().insertSheet(); sheet.setName(userId); sheet.getRange(1, 1).setValue('登録日時'); sheet.getRange(1, 2).setValue(new Date()); sheet.getRange(2, 1).setValue('状態'); sheet.getRange(2, 2).setValue(0); } const status = sheet.getRange(2, 2).getValue(); return {"status": status, "sheet": sheet}; }
LINEからのWebhookリクエストに対してdoPost関数が呼び出され、引数eからイベントオブジェクト配列が取り出され、各々のイベントオブジェクトに対してイベントループ処理が実行される。
イベントループ内では、イベントオブジェクト event からユーザID event.source.userId とイベントタイプevent.typeが取り出され、この値に応じて処理を分岐する。たとえば、イベントタイプがテキストイベント(event.type == 'message')であれば、入力されたメッセージ event.message.text が取り出され、メッセージ処理関数 respondUserに渡される。また、イベントタイプがポストバックイベント(event.type == 'postback')であれば、渡されたデータ event.postback.data が取り出され、ポストバックデータ処理関数 respondPostbackに渡される。
respondUser関数は、ユーザが入力したメッセージに応じた処理を行い、レスポンスメッセージ配列を返す。なお、レスポンスメッセージはLINE Messaging APIのレスポンスメッセージを管理するクラス Response を利用して作成している。これを使えば、例えばテキストメッセージはメソッドpushLineTextを使って、スタンプメッセージはpushLineStickerを使って簡単に作成できる。クラス Responseのソースを以下に示す。
/** * LINE Messaging API Response class */ class Response { // コンストラクタ― constructor() { this.messages = []; } // LINEテキストメッセージを追加する pushLineText(text) { this.pushMessage({ "type": "text", "text": text, }); } // LINEスタンプメッセージを追加する pushLineSticker(packageId, stickerId) { this.pushMessage({ "type": "sticker", "packageId": '' + packageId, "stickerId": '' + stickerId }); } // LINE画像メッセージを追加する pushLineImage(originalContentUrl, previewImageUrl) { this.pushMessage({ "type": "image", "originalContentUrl": originalContentUrl, "previewImageUrl": previewImageUrl }); } // LINEテンプレートメッセージ(ボタン)を追加する pushLineTemplateButton(altText, thumbnailImageUrl, title, text, defaultAction, actions) { this.pushMessage({ "type": "template", "altText": altText, "template": { "type": "buttons", "thumbnailImageUrl": thumbnailImageUrl, "imageAspectRatio": "rectangle", "imageSize": "contain", "imageBackgroundColor": "#FFFFFF", "title": title, "text": text, "defaultAction": defaultAction, "actions": actions } }); } // LINEテンプレートメッセージ(カルーセルテンプレート)を追加する pushLineTemplateCarousel(altText, columns) { this.pushMessage({ "type": "template", "altText": altText, "template": { "type": "carousel", "columns": columns, "imageAspectRatio": "rectangle", "imageSize": "contain" } }); } // カスタムペイロードメッセージを追加する pushMessage(line_message) { this.messages.push(line_message); } // レスポンスメッセージを取得する getMessage() { return this.messages; } } /** * LINE カルーセルのカラムクラス */ class CarouselColumn { constructor() { this.columns = []; } // カラムを追加する add(thumbnailImageUrl, title, text, defaultAction, actions){ this.columns.push({ "thumbnailImageUrl": thumbnailImageUrl, "imageBackgroundColor": "#FFFFFF", "title": title, "text": text, "defaultAction": defaultAction, "actions": actions }); } }
このクラスを利用すれば、例えば画像メッセージは次のようにして作成できる。
const res = new Response(); const imageUrl = "{画像のURL}"; res.pushLineImage(imageUrl, imageUrl);
さらにテンプレートボタンメッセージは次のようにして作成できる。
const defaultAction = { "type": "uri", "label": "詳しく見る", "uri": "https://semi2020kumw.blogspot.com/" }; const actions = []; actions.push({ "type": "postback", "label": "購入", "data": "action=buy&itemid=123" }); actions.push({ "type": "message", "label": "カートに入れる", "text": "1週間後に北海道を予約" }); actions.push(defaultAction); res.pushLineTemplateButton('テンプレートメッセージ(ボタン)', imageUrl, 'メニュー', '選択してください。', defaultAction, actions);
さらにテンプレートカルーセルメッセージはカルーセルのカラムクラスを用いて次のように作成できる。
const cCols = new CarouselColumn(); cCols.add(imageUrl, 'メニュー', 'これは1つ目のカラムです', defaultAction, actions); cCols.add(imageUrl, 'メニュー', 'これは2つ目のカラムです', defaultAction, actions); res.pushLineTemplateCarousel('テンプレートメッセージ(カルーセルテンプレート)', cCols.columns);
0 件のコメント:
コメントを投稿