JavaScript
GoogleAppsScript
gas
初心者
linebot

【GAS修行③】レシピ救助LINE BOTを作成

・GAS熟練者への道。
・先人達のコードの「写経&コピー」の駆使の成果物のまとめ。
・第三弾
第一弾第二弾はこちら。

経緯

・「もう三回目か。」
・「コピー・写経ばかりだが、ちゃんと身についているのかな・・・。」
・「という心配は秒速完結して、今回も駆使するか。」
→そういうわけで、今回もサンプルアプリと仏様サイトを発見。
https://routecompass.net/post-4842/
→「また参考(※マルコピ)に作るか。」
→取り組み開始。

概要

  • 材料を投稿すれば、クックパッドから画像と料理名を持ってきて返す。(最新版の五個)
  • 詳細なレシピのURLも教えてくれる。

結果

・実際の画面はこちらです。(五件はスワイプして見る。)
image.png
image.png

作成環境

  1. Google App Script
  2. LINE Messaging API

手順(※「Google Apps Scriptの設定」「LINE MessagingAPIは第二弾と一緒」)

Google Apps Scriptの設定

  • Googleドライブからスクリプトエディタを起動。
    ※Googleアカウントを持っていない人は、作成する。
    • Googleドライブを起動
    • 「新規」→ 「その他」→「アプリを追加」の順にクリック。
    • アプリ検索欄に「script」と入力して検索。
    • 検索結果に「Google Apps Script」が表示されるので、そこの「接続」ボタンをクリック
    • 改めて「新規」→ 「その他」の順にクリックしていくと、「Google Apps Script」が表示されているので、クリック。
  • 起動したプロジェクトに名前をつける
    ※プロジェクト名が反映されるわけではないが、自分がわかる名前をつける。
    →保存。(最初の3行のままで良い。)
  • 保存後、タブメニューの「公開」から「ウェブアプリケーションとして導入」をクリック。下記の項目を設定。
    • プロジェクトバージョン:New(変更内容は任意)
    • 次のユーザーとしてアプリケーションを実行:自分(アドレス)
    • アプリケーションにアクセスできるユーザー:全員(匿名ユーザーを含む)
  • 設定後、「導入」ボタンをクリック。作成さるウェブアプリケーションURLをメモしておく。「OK」ボタンをクリック。
  • 一旦置いておく。

LINE Messaging APIの設定

  • LINE Messaging APIのトークンを発行。 (※基本的にはこちらを参考)
    • LINE Developersにアクセスして、自分のLINEアカウント情報でログイン。
    • ログイン後、初めての方は開発者情報を登録。
    • 「はじめる」をクリック。
    • コンソールページ内の「プロバイダ作成」ボタンをクリック
    • 「必要情報」を入力後、「確認」ボタンをクリック。(※自分の名前を入力。)
    • 設定後、「チャネル作成」ボタンで、Messaging APIのチャネルを作成し、下記の項目を設定。
      • アプリアイコン画像:任意
      • アプリ名: 任意
      • アプリ説明: 任意
      • プラン: 任意
      • 大業種: 任意
      • 小業種: 任意
      • メールアドレス: ご自身のメールアドレス
    • 設定後、確認ボタンで、チャネルが作成される。
    • コンソールページ内の作成したチャネルをクリック。
    • チャネル基本設定ページ内の「メッセージ送受信設定」「LINE@機能の利用」欄を下記の項目に設定
      • Webhook送信・・・「利用する」
      • Webhook URL・・・先程コピーしたGoogle Apps ScriptのURLを指定
      • 自動応答メッセージ・・・「利用しない」
      • 友達追加時あいさつ・・・「利用しない」
    • 設定後、同ページ内の「アクセストークン」を再発行して、そのトークンを控えておく。
  • トークン発行後、同ページ内のQRコードを読み込み、作成Botを友達として追加。

コード

  • 先程のスクリプトエディタに戻り、下記のコードをコピーして、保存。
line-cookpad.gs
var CHANNEL_ACCESS_TOKEN =   "LINEトークンを書く。";
//line-apiからの送信処理
function doPost(e) {
  var reply_token= JSON.parse(e.postData.contents).events[0].replyToken;
  //メッセージを取得
  var user_message = JSON.parse(e.postData.contents).events[0].message.text;
  var mes = search(user_message);
  if (mes == "null") {//検索結果がなけれな、終了
    return;
  }
  var line_json = [];
  for (i = 0; i < mes[0].length; i++){
    //メニュー作成処理
    var fuck = (
      {
        "thumbnailImageUrl": mes[2][i],
        "title": mes[0][i],
        "text": mes[3][i],
        "actions": [
          {
            "type": "uri",
            "label": "詳細はここだよ(*'ω'*)",
            "uri": mes[1][i]
          }
        ]
      }
    );
    line_json.push(fuck);
  }
  var url = 'https://api.line.me/v2/bot/message/reply';//リプライのurl
  UrlFetchApp.fetch(url, {
    'headers': {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
    },
    'method': 'post',
    'payload': JSON.stringify({
      'replyToken': reply_token,
      'messages': [{       
        "type": "template",
        "altText": "this is a carousel template",
        "template": {
          "type": "carousel",
          "columns": line_json
        }
      }],
    }),
  });
  return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}
// 材料検索処理
function search(mes){
  //エラー処理
  try{
    var response = UrlFetchApp.fetch("https://cookpad.com/search/" + mes);
  }
  catch(e){
    return "null";
  }
  var title_list = [];
  var url_list = [];
  var img_url_list = [];
  var description_list = [];

  //urlとタイトルが入ってるDOMを取得
  var myRegexp = /<a class=\"recipe-title font13([\s\S]*?)<\/a>/gi;
  var url_and_title = response.getContentText().match(myRegexp);
  if (url_and_title != null) { //検索結果があれば
    number = url_and_title.length; //検索結果数を取得
    if (number >=5) number = 5; //検索結果は上から5個までに   
  }
  else{//なかったら
    return "null";
  }
  for (i = 0; i < number; i++){ //最大5個までurl,title,img_urlを取得
  //url取得
    myRegexp = /href=\"([\s\S]*?)\"/g;
    var url = url_and_title[i].match(myRegexp);
    url = url[0].substr(5);
    url = url.replace(/\"/g,"");
    url = 'https://cookpad.com' + url;
    //Logger.log(url);
    url_list.push(url);
    //タイトル取得
    myRegexp = /\">([\s\S]*?)<\/a>/g;
    var title = url_and_title[i].match(myRegexp);
    title = title[0];
    title = title.substr(2);
    title = title.substr( 0, title.length-4 );
    //Logger.log(title);
    title_list.push(title);
    //imgのurlを取得する正規表現
    //アクセス制限処理
    //var myRegexp2 = /https:\/\/img.cpcdn.com\/recipes\/(\d+)\/100x141c\/([\s\S]*?).jpg/gi;
    //var img_url = response.getContentText().match(myRegexp2);
    //Logger.log(img_url[i]);
    //アクセス制限不要処理
    var response2 = UrlFetchApp.fetch(url);
    var myRegexp2 = /https:\/\/img.cpcdn.com\/recipes\/(\d+)\/m\/([\s\S]*?).jpg/gi;
    var img_url = response2.getContentText().match(myRegexp2);
    img_url_list.push(img_url[0]);
    //投稿者名
    var myRegexp3 = /recipe_author_name([\s\S]*?)<\/a>/gi;
    var description = response2.getContentText().match(myRegexp3);
    var myRegexp4 = />([\s\S]*?)</gi;
    description = description[0].match(myRegexp4);
    description = description[0];
    description = description.substr( 1, description.length - 2 );
    description_list.push("by " + description);
  }
  //情報を返す
  var mes = [];
  mes[0] = title_list;
  mes[1] = url_list;
  mes[2] = img_url_list;
  mes[3] = description_list;
  return mes;  
}

※以下の項目を自分のものに変えるのを忘れない。
   ・LINE Messaging APIのトークン(先程メモしたもの。)

  • 自分のコードに書き換えて保存。
  • 保存後、先程の要領で、「ウェブアプリケーションとして導入」をクリック。
  • プロジェクトバージョンを最新のものにして、更新をクリック。
    ※更新をしないと、反映されない。
  • 実際にLINEへ行き、動作確認。(例:「アンチョビ」)
  • 正常に動けば、完了。(※スマホでしか見られない)

まとめ

  • 今回は参考サイトの手順が詳細であったため、スムーズに実装できた。
  • メニューのカスタマイズ可能なため、好きな色合いとかにも応用できる。
  • マルコピ駆使の日々の割に、徐々にだが、処理が読めるようになってきた。
  • これを見てくださるエンジニアの皆様、「こうしたら簡単にかけるよ」とか「こういう処理を追加してみたら」等の意見を何卒お待ちしております。

参考