Messaging APIとGASを使ってLine Botに画像を送ってGoogle Driveのフォルダに保存できるようにしました。
しかし、使ってみると一枚なら問題なくても同時に複数枚送ると数枚分しか保存されず、いくつか消えてしまっているケースがありました。
原因解決のための備忘録として残しておきます。
原因:
Postで取得したイベントの中に、複数のデータが入っているが、そのうちの一番目しか取得していなかったため。
対応策:
取得したイベントの中身をループで処理する
コード.gs
/********************************************
LINE Messaging APIのチャネルアクセストークン
*********************************************/
const LINE_ACCESS_TOKEN = "**********"; //自分のライントークンに変更
/********************************************
画像を保存するGoogleDriveのフォルダID
*********************************************/
const GOOGLE_DRIVE_FOLDER_ID = "**********"; //保存したいGoogle DriveのIDに変更
/********************************************
LINE Messaging APIからPOST送信を受けて起動
eはJSON文字列
*********************************************/
function doPost(e){
if (typeof e === "undefined"){
//eがundefinedの場合動作を終了
return;
}
//同時に画像が送られてきた場合、全イベント(画像やテキスト)をループしてタイプごとに分岐する
for (const event of JSON.parse(e.postData.contents).events) {
//受信したメッセージ情報を変数に格納する
const replyToken = event.replyToken; //reply token
const messageId = event.message.id; //メッセージID
const messageText = event.message.text; //メッセージ内容
const messageType = event.message.type; //メッセージタイプ
//LINEで送信されたものが画像・動画の場合、保存する
if(messageType == "image" || messageType == "video"){
const LINE_END_POINT = "https://api-data.line.me/v2/bot/message/" + messageId + "/content";
//LINE_END_POINTとreplyTokenを関数saveImageに渡して起動する
saveImage(LINE_END_POINT, replyToken);
}
}
}
/********************************************
画像を取得する
*********************************************/
function saveImage(LINE_END_POINT, replyToken){
//ファイル名に使う現在日時を取得
const date = Moment.moment(); //現在日時を取得
const formattedDate = date.format("YYYYMMDD_HHmmss");
const url = LINE_END_POINT;
const headers = getHeader();
const options = {
"method" : "get",
"headers" : headers,
};
const res = UrlFetchApp.fetch(url, options);
//画像を取得し、ファイル名を設定する
//ファイル名: LINE画像_YYYYMMDD_HHmmss
const imageBlob = res.getBlob().setName("LINE_" + formattedDate)
//画像をGoogle Driveのフォルダーに保存する
const folder = DriveApp.getFolderById(GOOGLE_DRIVE_FOLDER_ID);
const file = folder.createFile(imageBlob);
const message = "保存が完了しました";
//変数とmessageを関数sendMessageに渡し、sendMessageを起動する
sendMessage(replyToken, message)
}
/********************************************
ユーザーにメッセージを送信する
*********************************************/
function sendMessage(replyToken, text){
//返信先URL
const replyUrl = "https://api.line.me/v2/bot/message/reply";
const headers = getHeader();
const postData = {
"replyToken": replyToken,
"messages": [{
"type": "text",
"text": text
}]
};
const options = {
"method" : "post",
"headers" : headers,
"payload" : JSON.stringify(postData)
};
//LINE Messaging APIにデータを送信する
UrlFetchApp.fetch(replyUrl, options);
}
function getHeader(){
const headers = {
"Content-Type": "application/json; charset=UTF-8",
"Authorization": "Bearer " + LINE_ACCESS_TOKEN
};
return headers;
}
今回の変更点
const event = JSON.parse(e.postData.contents).event[0]
になっていたところを、
for (const event of JSON.parse(e.postData.contents).events)
のようにeventsからそれぞれのイベントを取得してループで実行しています。
これにより、一回のメッセージ内で複数の画像が含まれていても、すべてを保存することが可能です。
コメント