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 件のコメント:
コメントを投稿