#はじめに
LINEボットの基礎的なアレコレは以下の記事が詳しいです。
LINEボットを初めて作る方は、先にこちらを読んだ方が良いでしょう。手順やサンプルコードが簡潔にまとめられているので、LINEボット作成がどんなものかの理解に繋がると思います。
ただし上記記事をベースにコードを書く場合、サンプルコードの以下の部分:
var userMessage = JSON.parse(e.postData.contents).events[0].message.text;
こちらは、
var event = JSON.parse(e.postData.contents).events[0];
var userMessage = event.message.text || "";
var event = JSON.parse(e.postData.contents).events[0];
if(event.message.type == "text") {
var userMessage = event.message.text;
...
}
のように(あるいはもっと適した形に)書き直した方が良いです。本記事で示す通り、ボットが受け取るメッセージのtype
はtext
だけではないためです。…もっと詳しく言うと、event.message
オブジェクトの中身は、そのtypeごとに異なります。
{
type: 'text',
text: 'aaaaa'
}
{
type: 'image',
id: 1234567890,
...
}
typeがimage
のときは、event.message.text
は存在しませんね。そういうことです。
#本題(コード)
特に説明することはないです。
//LINEボットのアクセストークン
var ACCESS_TOKEN = 'ACCESS_TOKEN';
//Googleドライブに作ったフォルダのURLの末尾にある30文字くらいの文字列
var FOLDER_ID = 'FOLDER_ID';
//返信用エンドポイント
var REPLY_URL = 'https://api.line.me/v2/bot/message/reply';
function sendMsg(url, payload) {
UrlFetchApp.fetch(url, {
'headers': {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': 'Bearer ' + ACCESS_TOKEN,
},
'method': 'post',
'payload': JSON.stringify(payload),
});
}
function getImage(id) {
//画像取得用エンドポイント
var url = 'https://api-data.line.me/v2/bot/message/' + id + '/content';
var data = UrlFetchApp.fetch(url,{
'headers': {
'Authorization' : 'Bearer ' + ACCESS_TOKEN,
},
'method': 'get'
});
//ファイル名を被らせないように、今日のDateのミリ秒をファイル名にしています
var img = data.getBlob().getAs('image/png').setName(Number(new Date()) + '.png');
return img;
}
function saveImage(blob) {
try{
var folder = DriveApp.getFolderById(FOLDER_ID);
var file = folder.createFile(blob);
return file.getUrl();
}catch(e){
return false;
}
}
function doPost(e) {
var event = JSON.parse(e.postData.contents).events[0];
if(event.message.type == 'image') {
try {
var img = getImage(event.message.id);
var url = saveImage(img);
sendMsg(REPLY_URL, {
'replyToken': event.replyToken,
'messages': [{
'type': 'text',
'text': url ? "保存しました:\n" + url : "ダウンロードエラー",
}]
})
}catch(e) {
Logger.log(e);
}
}
return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}
受信した画像の取り扱いに非常に難儀しました。バイナリねえ…。
###雑記
本題から逸れますが、トークンやURLなどの変数やらは、GASのプロジェクトのプロパティ
(「ファイル」→「プロジェクトのプロパティ」)に環境変数みたいな形で保存できます。
保存した変数は以下のようにすることで取得できます。
function PROPERTY(key) {
return PropertiesService.getScriptProperties().getProperty(key);
}
var ACCESS_TOKEN = PROPERTY("ACCESS_TOKEN");
var FOLDER_ID = PROPERTY("FOLDER_ID");
ボットの機能を拡張する度に、DB用のスプレッドシートのIDや、PUSHメッセージ・ユーザープロフィール取得用のエンドポイントURLなどなど、必要な変数は一気に増えます。ヘンな文字列がいっぱいコード上にあると、コードの可読性は一気に低下します。是非ご活用ください。