Yuki's bnb blog

こんにちは!Yukiといいます。本業のかたわら大阪で2016年夏から民泊運営のお手伝いをしています。民泊業務に関する様々なことを自動化・効率化したいと思い日々活動しています。 お気軽にコメント・お問い合わせください :) TOEICスコア 985

【シリーズ第2話】Google Driveに画像を自動保存するLINE BotをGASで作ろう (実践編)

LINE Messaging API Google Drive

こんにちは!
Yuki (@yukibnb) です。

LINE Messaging APIとGoogle Apps Script(GAS)を使用してGoogle Driveの指定フォルダーに画像を自動保存するLINE Botを作成する方法シリーズ記事の第2話です。

line messaging api 画像 gas

今回の記事ではGoogle Apps Script(GAS)を書き、LINE Bot作成完了まで紹介します!コピペでそのまま使えるGASを紹介しますのでご安心ください。

前回の第1話はこちらをご覧ください。
www.yukibnb.com

 
では見ていきましょう!

 

コピペでOK!画像を自動保存するLINE BotのGAS

スクリプトエディタを開く

google drive

Google Driveを開き、画面右上の[新規]をクリックしてください。

 

Google Apps Scriptを開く

Google Drive

[その他] → [Google Apps Script]の順にクリックしてください。

するとGoogle Apps Scriptが開きます。

 

[Google Apps Script]が見当たらない場合

Google Drive

もし[その他]をクリックしても[Google Apps Script]が見当たらない場合、[アプリを追加]をクリックしてください。

 
G Suite Marketplace

G Suite Marketplaceというポップアップが表示されます。ポップアップ内の検索ボックスに[google apps script]と入力し検索すると、Google Apps Scriptのアプリが表示されます。

こちらをクリックしてインストールしてください。

 
Google Drive

インストールが完了すると[その他]の中に[Google Apps Script]が追加されるので、[Google Apps Script]をクリックしてください。

 

プロジェクト名とスクリプト名を記入する

f:id:yukibnb:20200224193318p:plain

プロジェクト名とスクリプト名を入力してください。

お好きな名前で大丈夫です。

 

Moment.jsライブラリを導入する

今回紹介するGoogle Apps ScriptではMoment.jsというライブラリを使用します。

以下記事を参考にMoment.jsライブラリを導入してください。記事内の手順に沿って頂くと簡単に導入できます。
www.yukibnb.com

 
Moment.jsを使うとGoogle Apps Script内で日付や時間を簡単に記述することができます。

今回Google Driveに画像を自動保存する際に画像ファイル名を「LINE画像_YYMMDD_HHmmss」(例: LINE画像_200916_210733)というように、自動保存した日時をファイル名に含めます。

その日時を簡単に記述するためにMoment.jsライブラリを使用しています。

 

GASをコピペする

Google Apps Script Project

上記画像の箇所に以下GASをコピペしてください。

元から入力されているfunction myFunction() { }は不要なので削除してください。

memo

チャネルアクセストークンこちらの記事で確認したものを入力ください。
フォルダーIDこちらの記事で確認したものを入力ください。

 

//★★LINE Messaging APIのチャネルアクセストークン★★
var LINE_ACCESS_TOKEN = "チャネルアクセストークンをここに入力";

//★★画像を保存するフォルダーID★★
var GOOGLE_DRIVE_FOLDER_ID = "フォルダーIDをここに入力";


//LINE Messaging APIからPOST送信を受けたときに起動する
// e はJSON文字列
function doPost(e){
  if (typeof e === "undefined"){
    //eがundefinedの場合動作を終了する
    return;
  } 

  //JSON文字列をパース(解析)し、変数jsonに格納する
  var json = JSON.parse(e.postData.contents);

  //受信したメッセージ情報を変数に格納する
  var reply_token = json.events[0].replyToken; //reply token
  var messageId = json.events[0].message.id; //メッセージID
  var messageType = json.events[0].message.type; //メッセージタイプ

  //LINEで送信されたものが画像以外の場合、LINEで返信し動作を終了する
  if(messageType !== "image"){
    var messageNotImage = "画像を送信してください"
    //変数reply_tokenとmessageNotImageを関数sendMessageに渡し、sendMessageを起動する
    sendMessage(reply_token, messageNotImage)
    return;
  }

  var LINE_END_POINT = "https://api.line.me/v2/bot/message/" + messageId + "/content";
  
  //変数LINE_END_POINTとreply_tokenを関数getImageに渡し、getImageを起動する
  getImage(LINE_END_POINT, reply_token);
  }


//Blob形式で画像を取得する
function getImage(LINE_END_POINT, reply_token){
  //ファイル名に使う現在日時をMomentライブラリーを使って取得
  var date = Moment.moment(); //現在日時を取得
  var formattedDate = date.format("YYYYMMDD_HHmmss");

  try {
    var url = LINE_END_POINT;

    var headers = {
      "Content-Type": "application/json; charset=UTF-8",
      "Authorization": "Bearer " + LINE_ACCESS_TOKEN
    };

    var options = {
      "method" : "get",
      "headers" : headers,
    };

  var res = UrlFetchApp.fetch(url, options);

  //Blob形式で画像を取得し、ファイル名を設定する
  //ファイル名: LINE画像_YYYYMMDD_HHmmss.png
  var imageBlob = res.getBlob().getAs("image/png").setName("LINE画像_" + formattedDate + ".png")

  //変数imageBlobとreply_tokenを関数saveImageに渡し、saveImageを起動する
  saveImage(imageBlob, reply_token)

  } catch(e) {
  //例外エラーが起きた時にログを残す
  Logger.log(e.message);
  }
}


//画像をGoogle Driveのフォルダーに保存する
function saveImage(imageBlob, reply_token){
  try{
    var folder = DriveApp.getFolderById(GOOGLE_DRIVE_FOLDER_ID);
    var file = folder.createFile(imageBlob);

    var message = "「" + folder.getName() + "」に画像を保存しました";
  
    //変数reply_tokenとmessageを関数sendMessageに渡し、sendMessageを起動する
    sendMessage(reply_token, message)

  } catch(e){
    //例外エラーが起きた時にログを残す
    Logger.log(e)
  }
}


//ユーザーにメッセージを送信する
function sendMessage(reply_token, text){
  //返信先URL
  var replyUrl = "https://api.line.me/v2/bot/message/reply";

  var headers = {
    "Content-Type": "application/json; charset=UTF-8",
    "Authorization": "Bearer " + LINE_ACCESS_TOKEN
  };
  
  var postData = {
    "replyToken": reply_token,
    "messages": [{
                  "type": "text",
                  "text": text
                  }]
  };

  var options = {
    "method" : "post",
    "headers" : headers,
    "payload" : JSON.stringify(postData)
  };

  //LINE Messaging APIにデータを送信する
  UrlFetchApp.fetch(replyUrl, options);
}

 
GASをコピペし、チャネルアクセストークン・フォルダーIDを置き換えると以下のような画面になります。
Google Apps Script

 
これでGASの記述は完了です。

次にこのGASとLINE Messaging APIを接続する作業を行います。

 

GASとLINE Messaging APIを接続しよう

[ウェブアプリケーションとして導入]をクリックする

Google Apps Script

スクリプトエディタ上部のメニューから[公開] → [ウェブアプリケーションとして導入]の順にクリックしてください。

クリックするとポップアップ画面が表示されます。

 

ウェブアプリケーションを設定する

f:id:yukibnb:20200425155157p:plain

スプレッドシートの設定を日本語にしていても、このポップアップは英語で表示される場合があります。

以下の通り設定ください。

1. Project version:
[New]を選択してください。その下の入力ボックスは空白のままで大丈夫です。

2. Execute the app as:
[me (自分のメールアドレス)]を選択してください。 ※日本語の場合[自分 (自分のメールアドレス)]

3. Who has access to the app:
[Anyone, even anonymous]を選択してください。 ※日本語の場合[全員 (匿名ユーザーを含む)

4. Deploy:
(1)~(3)を選択後にクリックしてください。

 

memo

(3)の[Who has access to the app]とは、このアプリケーションに誰がアクセスできるかを設定します。

今回のGASはLINE Botとして公開するため[Anyone, even anonymous]を選択しますが、全く別のアプリケーションを公開する時はその使用目的に応じてこの箇所は調整してください。

 

GASを承認する

Google Apps Script

[Deploy]をクリックすると上記画像のようなポップアップが表示されます。

[許可を確認]をクリックするとさらに別のポップアップが表示されます。以下記事内の手順に従って承認してください。
www.yukibnb.com

 

Webhook URLを発行する

f:id:yukibnb:20200425161235p:plain

承認が完了すると上記画像のようなポップアップが表示されます。

このhttps://script.google.com/macros/s/.............をWebhook URLと呼び、GASとLINE BOTを接続するために重要なものです。

このWebhook URLをコピーしてください。

※この画面を閉じても後でいつでも確認できます。

 

LINE Developersコンソールにログインし、Webhook URLを登録する

f:id:yukibnb:20200425161936p:plain

こちらの記事で紹介した、LINE Developersコンソール内のWebhook設定画面の[編集]をクリックし、先ほどコピーしたWebhook URLを登録してください。

そして[Webhookの利用]をオンにしてください。

正しく登録が完了すると以下画像のようになります。

f:id:yukibnb:20200425162234p:plain

これですべての設定が完了しました!

 

使ってみよう!

LINE Botを友だち追加する

f:id:yukibnb:20200416223318p:plain

こちらの記事で紹介した、LINE Developersコンソール内でLINE BOTのIDとQRコードを確認できます。

いずれかを使用し、友だち追加してください。

 

画像を送信しよう

LINE Bot

LINE Bot宛てに1対1で画像を送信、もしくはLINE BotをLINEグループに入れてLINEグループに画像を送信してください。

すると予め設定したGoogle Driveのフォルダーに画像が自動保存されます。

Google Apps Script

 

【補足その1】GASを編集した場合

Webhook URLを発行後にGASを編集した場合、GASを保存しただけではウェブアプリケーションは更新されません。

以下手順でウェブアプリケーションのバージョンを更新する必要があります。

 

ウェブアプリケーションの設定画面を開く

Google Apps Script

スクリプトエディタを開き、上部のメニューから[公開] → [ウェブアプリケーションとして導入]の順にクリックしてください。

 

[New]を選択する

f:id:yukibnb:20200425163629p:plain

[Project version]には数字が表示されています。ここをクリックし[New]を選択してください。

そして[更新]をクリックしてください。

これでウェブアプリケーションの更新が完了です。

 

【補足その2】自動返信が不要な場合

LINE Bot

LINE Botからの自動返信が不要な場合、GASの一部箇所を削除します。

※削除後に必ずウェブアプリケーションのバージョンを更新してください。

 

画像保存時の自動返信が不要な場合

LINE Bot

『「{フォルダー名}」に画像を保存しました』という自動返信が不要な場合、GASの以下箇所を削除してください。

削除前
try{
  var folder = DriveApp.getFolderById(GOOGLE_DRIVE_FOLDER_ID);
  var file = folder.createFile(imageBlob);

  var message = "「" + folder.getName() + "」に画像を保存しました";
  
  //変数reply_tokenとmessageを関数sendMessageに渡し、sendMessageを起動する
  sendMessage(reply_token, message)

} catch(e){
  //例外エラーが起きた時にログを残す
  Logger.log(e)
}

 

削除後
try{
  var folder = DriveApp.getFolderById(GOOGLE_DRIVE_FOLDER_ID);
  var file = folder.createFile(imageBlob);
} catch(e){
  //例外エラーが起きた時にログを残す
  Logger.log(e)
}

 

画像以外送信時の自動返信が不要な場合

LINE Bot

『画像を送信してください』という自動返信が不要な場合、GASの以下箇所を削除してください。

削除前
if(messageType !== "image"){
  var messageNotImage = "画像を送信してください"
  //変数reply_tokenとmessageNotImageを関数sendMessageに渡し、sendMessageを起動する
  sendMessage(reply_token, messageNotImage)
  return;
}

 

削除後
if(messageType !== "image"){
  return;
}

 

まとめ

今回はGoogle Driveの指定フォルダーに画像を自動保存するLINE Botの作成方法を紹介しました!

様々な場面で活用頂けると嬉しいです!