LANG SELRCT

コードを書く場所についてはこちら

2017年10月28日土曜日

LINE BOTで「カルーセル」テンプレートメッセージを表示する



テンプレートメッセージの「カルーセル」表示してみましょう
これはボタンテンプレートを横に並べるもので
最大5個まで並べられるようです
LINE BOT Carousel Template messages (max 5 columns)

公式リファレンスでここに書かれていることを実際にやってみます


LINE BOTをつくる方法はこちらの記事にまとめました

以下のコードは、carouselと入力すると、カルーセルテンプレートメッセージが返ってくる例です
uri以外はリファレンスのままです
別の例として下の方に「おまけ」のコードも書いてみました


コード.gs
var CHANNEL_ACCESS_TOKEN = "TOKEN"; 
 
function doPost(e) {
  var contents = e.postData.contents;
  var obj = JSON.parse(contents);
  var events = obj["events"];
  for (var i = 0; i < events.length; i++) {
    if (events[i].type == "message") {
      reply_message(events[i]);
    } else if (events[i].type == "postback") {
      post_back(events[i]);
    }
  }
}

function reply_message(e) {
  var input_text = e.message.text;
  if (input_text == "carousel") {
    var postData = {
      "replyToken": e.replyToken,
      "messages": [{
        "type": "template",
        "altText": "this is a carousel template",
        "template": {
          "type": "carousel",
          "columns": [{
              "thumbnailImageUrl": "https://~.png",
              "title": "this is menu",
              "text": "description",
              "actions": [{
                  "type": "postback",
                  "label": "Buy",
                  "data": "action=buy&itemid=111"
                },
                {
                  "type": "postback",
                  "label": "Add to cart",
                  "data": "action=add&itemid=111"
                },
                {
                  "type": "uri",
                  "label": "View detail",
                  "uri": "http://example.com/page/111"
                }
              ]
            },
            {
              "thumbnailImageUrl": "https://~.png",
              "title": "this is menu",
              "text": "description",
              "actions": [{
                  "type": "postback",
                  "label": "Buy",
                  "data": "action=buy&itemid=222"
                },
                {
                  "type": "postback",
                  "label": "Add to cart",
                  "data": "action=add&itemid=222"
                },
                {
                  "type": "uri",
                  "label": "View detail",
                  "uri": "http://example.com/page/222"
                }
              ]
            }
          ]
        }
      }]
    };
  }
  fetch_data(postData);
}

function fetch_data(postData) {
  var options = {
    "method": "post",
    "headers": {
      "Content-Type": "application/json",
      "Authorization": "Bearer " + CHANNEL_ACCESS_TOKEN
    },
    "payload": JSON.stringify(postData)
  };
  UrlFetchApp.fetch("https://api.line.me/v2/bot/message/reply", options);
}
意訳.gs
アクセストークンを設定する

この処理は以下を実行する
送信されたデータの内容を取得し
そのJSONをオブジェクトに変換し
eventsを取得する
eventsの数だけ以下を繰り返す
もしtypeが message なら
reply_messageに渡す
もしtypeが postback なら
post_backに渡す




この処理は以下を実行する
入力されたtextを取得して
もしそれが carousel なら
postDataに
replyTokenを設定し
messagesの
typeをtemplateに設定し
altTextを設定し
templateの
typeをcarouselに設定し
columnsを以下のように設定する
一つ目のcolumnのthumbnailImageUrlを設定する
titleを設定する
textを設定する
actionsの
1つ目のtypeを設定し
labelを設定し
dataを設定し


2つ目のtypeを設定し
labelを設定し
dataを設定し


3つ目のtypeを設定し
labelを設定し
dataを設定する




2つめのcolumnのthumbnailImageUrlを設定する
titleを設定する
textを設定する
actionsの
1つ目のtypeを設定し
labelを設定し
dataを設定し


2つ目のtypeを設定し
labelを設定し
dataを設定し


3つ目のtypeを設定し
labelを設定し
dataを設定する








fetch_dataにpostDataを渡す


この処理は以下を実行する
optionsに
methodを設定し
headersに
Content-Typeを設定し
Authorizationを設定し

payloadにはpostDataをJSONに変換したものを設定する

optionをつけてLINEのmessage reply APIをたたく


おまけ


少々無理やりですが
指定した日付けの中から
希望日時を選択するためのメッセージを作ってみます

日付ごとにcolumnを作り
第一候補 First choice
第二候補 Second choice
第三候補 Third choice
のボタンを用意して
時間を選択する仕組みです


〜choiceボタンを押すと
現在日時が表示され
任意の時間を選択できます

デフォルトで時間を設定したい場合は
↓このようにmodeの下にinitialを設定する
"mode": "time",
"initial": "2017-10-29T00:00"



選択すると以下のようにメッセージが返ってきます


columnを3つ作ったのでコードは長くなりましたが
やっていることは3つとも同じです


コード.gs
var CHANNEL_ACCESS_TOKEN = "TOKEN"; 
 
function doPost(e) {
  var contents = e.postData.contents;
  var obj = JSON.parse(contents);
  var events = obj["events"];
  for (var i = 0; i < events.length; i++) {
    if (events[i].type == "message") {
      reply_message(events[i]);
    } else if (events[i].type == "postback") {
      post_back(events[i]);
    }
  }
}

function reply_message(e) {
  var input_text = e.message.text;
  if (input_text == "carousel") {
    var postData = {
      "replyToken": e.replyToken,
      "messages": [{
        "type": "template",
        "altText": "this is a carousel template",
        "template": {
          "type": "carousel",
          "columns": [{
              "thumbnailImageUrl": "https://lh3.googleusercontent.com/l-ZZOFGyeKYz3stUbxTECHYnXcRD66C9g0tjiWA_okVIxZyb0E7_esU8LRpq_0LFCu8Y=w300",
              "title": "When are you available?",
              "text": "2017/10/29",
              "actions": [{
                  "type": "datetimepicker",
                  "label": "First choice",
                  "data": "2017/10/29 First choice",
                  "mode": "time"
                },
                {
                  "type": "datetimepicker",
                  "label": "Second choice",
                  "data": "2017/10/29 Second choice",
                  "mode": "time"
                },
                {
                  "type": "datetimepicker",
                  "label": "Third choice",
                  "data": "2017/10/29 Third choice",
                  "mode": "time"
                },
              ]
            },
            {
              "thumbnailImageUrl": "https://lh3.googleusercontent.com/l-ZZOFGyeKYz3stUbxTECHYnXcRD66C9g0tjiWA_okVIxZyb0E7_esU8LRpq_0LFCu8Y=w300",
              "title": "When are you available?",
              "text": "2017/10/30",
              "actions": [{
                  "type": "datetimepicker",
                  "label": "First choice",
                  "data": "2017/10/30 First choice",
                  "mode": "time"
                },
                {
                  "type": "datetimepicker",
                  "label": "Second choice",
                  "data": "2017/10/30 Second choice",
                  "mode": "time"
                },
                {
                  "type": "datetimepicker",
                  "label": "Third choice",
                  "data": "2017/10/30 Third choice",
                  "mode": "time"
                },
              ]
            },
            {
              "thumbnailImageUrl": "https://lh3.googleusercontent.com/l-ZZOFGyeKYz3stUbxTECHYnXcRD66C9g0tjiWA_okVIxZyb0E7_esU8LRpq_0LFCu8Y=w300",
              "title": "When are you available?",
              "text": "2017/10/31",
              "actions": [{
                  "type": "datetimepicker",
                  "label": "First choice",
                  "data": "2017/10/31 First choice",
                  "mode": "time"
                },
                {
                  "type": "datetimepicker",
                  "label": "Second choice",
                  "data": "2017/10/31 Second choice",
                  "mode": "time"
                },
                {
                  "type": "datetimepicker",
                  "label": "Third choice",
                  "data": "2017/10/31 Third choice",
                  "mode": "time"
                },
              ]
            }
          ]
        }
      }]
    };
  }
  fetch_data(postData);
}

function post_back(e) {
  var data = e.postback.data;
  var selected_time = e.postback.params['time'];
  var replay_text = data + "\n" + selected_time;

  var postData = {
    "replyToken": e.replyToken,
    "messages": [{
      "type": "text",
      "text": replay_text
    }]
  };
  fetch_data(postData);
}

function fetch_data(postData) {
  var options = {
    "method": "post",
    "headers": {
      "Content-Type": "application/json",
      "Authorization": "Bearer " + CHANNEL_ACCESS_TOKEN
    },
    "payload": JSON.stringify(postData)
  };
  UrlFetchApp.fetch("https://api.line.me/v2/bot/message/reply", options);
}
意訳.gs
アクセストークンを設定する

この処理は以下を実行する
送信されたデータの内容を取得し
そのJSONをオブジェクトに変換し
eventsを取得する
eventsの数だけ以下を繰り返す
もしtypeが message なら
reply_messageに渡す
もしtypeが postback なら
post_backに渡す




この処理は以下を実行する
入力されたtextを取得して
もしそれが carousel なら
postDataに
replyTokenを設定し
messagesの
typeをtemplateに設定し
altTextを設定し
templateの
typeをcarouselに設定し
columnsを以下のように設定する
一つ目のcolumnのthumbnailImageUrlを設定する
titleを設定する
textを設定する
actionsの
1つ目のtypeを設定し
labelを設定し
dataを設定し
modeを設定する


2つ目のtypeを設定し
labelを設定し
dataを設定し
modeを設定する



3つ目のtypeを設定し
labelを設定し
dataを設定する
modeを設定する



2つめのcolumnのthumbnailImageUrlを設定する
titleを設定する
textを設定する
actionsの
1つ目のtypeを設定し
labelを設定し
dataを設定し
modeを設定する


2つ目のtypeを設定し
labelを設定し
dataを設定し
modeを設定する


3つ目のtypeを設定し
labelを設定し
dataを設定する
modeを設定する




3つめのcolumnのthumbnailImageUrlを設定する
titleを設定する
textを設定する
actionsの
1つ目のtypeを設定し
labelを設定し
dataを設定し
modeを設定する


2つ目のtypeを設定し
labelを設定し
dataを設定し
modeを設定する


3つ目のtypeを設定し
labelを設定し
dataを設定する
modeを設定する








fetch_dataにpostDataを渡す


この処理は以下を実行する
受け取ったpostbackからdataを取得し
選択された時間を取得し
replay_textにdataと改行と時間を入れる

postDataに
replyTokenを設定し
messagesの
typeをtextに設定し
textにreplay_textと改行とJSON文字列に変換した値を設定する


fetch_dataにpostDataを渡す


この処理は以下を実行する
optionsに
methodを設定し
headersに
Content-Typeを設定し
Authorizationを設定し

payloadにはpostDataをJSONに変換したものを設定する

optionをつけてLINEのmessage reply APIをたたく