【コード公開】webスクレイピングを使ったLine Bot作成手順

【コード公開】webスクレイピングを使ったLine Bot作成手順

以前の記事で書いた、Line Botの作り方とwebスクレイピングを応用して、TSUTAYAの新作リリース情報をスクレイピングで取得し、Line Botに返信させる手順を解説していきます。

webスクレイピングについて

以前の記事でスクレイピングについて解説しました。

スクレイピングを行った結果、下記のようにスプレッドシートに出力されます。

A列:新作タイトル
B列:新作リリース日
C列:サムネイル
D列:新作タイトルのURL

出力されているスプレッドシートの内容をLINE BOTで返信するようにコードを書いていきます。

Line Botについて

以前の記事で、すでにtextメッセージの返信まで解説しています。

次は、応用としてスプレッドシートの内容をtextではなく、画像付きで返信します。

doPost関数:ボットに対してメッセージが送信された時の処理

doPost関数は、main関数と同じようなもので、ボットに対してメッセージが送信されたことをトリガーとして実行されます。

①LINEから送信されたデータを取得(テキストメッセージそのものではない。)

②LINEから送信されてきたデータから、リプライトークン(返信するために必要)を取得

③送信されてきたテキストを取り出し


④取り出したテキストによって処理を振り分け

  • 先週のリリース情報の場合:先週のリリース情報を画像付きテキストで返信
  • 今週のリリース情報の場合:今週のリリース情報を画像付きテキストで返信
  • 来週のリリース情報の場合:来週のリリース情報を画像付きテキストで返信
  • それ以外の場合:「返答できないメッセージだよ!」を返信
// LINEの認証を突破するために必要なお作法
// botのChannel基本設定の画面で発行した鬼のように長い文字列を""の中にセット
var secret_token = "xxxxx"
var secret = "Bearer " + secret_token;

function doPost(e) {
  var json,token,requestText,releaseInfo,responseText;
  try{
    // ①LINEから送信されたデータを取得(テキストメッセージそのものではない。)
    json = e.postData.getDataAsString();
    
    // ②LINEから送信されてきたデータから、リプライトークン(返信するために必要)を取得
    token = JSON.parse(json).events[0].replyToken;
    
    // ③送信されてきたテキストを取り出し
    requestText = JSON.parse(json).events[0].message.text;
    
    // 新作情報取得
    responseText = "";
    
    // ④取り出したテキストによって処理を振り分け
    if(requestText == "先週のリリース情報"){
      responseText = readRows("先週");
      sendKercellMessage(responseText,token);
    } else if (requestText == "今週のリリース情報"){
      responseText = readRows("今週");
      sendKercellMessage(responseText,token);
    } else if (requestText == "来週のリリース情報"){
      responseText = readRows("来週");
      sendKercellMessage(responseText,token);
    } else {
      responseText = "返答できないメッセージだよ!"
      sendTextMessage(responseText,token);
    }
    
  }catch(e){
  }finally{
  }
}

readRows関数:スプレイピングによって出力されたスプレッドシートを読み込む

readRows関数では、スプレッドシートを一行ごとに読み込みます。

function readRows(sheetName) {
  // URLを利用してスプレットシートを読み込みます
  var id,sheet,row,values,rows,No,releaseInfo;
  
  id = "xxxx";  
  sheet = SpreadsheetApp.openById(id).getSheetByName(sheetName);  
  rows = sheet.getDataRange();
  values = rows.getValues();
  
  return values;
};

sendKercellMessage関数:Botから返信されるメッセージを設定

sendKercellMessage関数では、画像カルーセルテンプレートを使用して、
Botから返信されるメッセージをセットします。

LINEのAPIには、いくつかテンプレートがあります。
・カルーセル
・画像カルーセルテンプレート
・Flex Message
・確認テンプレート
・ボタンテンプレート

https://developers.line.biz/ja/docs/messaging-api/message-types/#template-messages

基本的には、テンプレート通りにreadRows関数で読み込んだ内容を設定していきます。
①HTTPヘッダーの設定(お作法的な設定)
②画像カルーセルテンプレート詳細作成
タイトルが12文字以上ある場合は、12文字目まで表示
③リクエストボディを設定(お作法的な設定)
④ ①~③で設定した内容をoptionにまとめる
⑤返信

function sendKercellMessage(responseText,token){
  // リプライを返すAPIのURI
  var url = "https://api.line.me/v2/bot/message/reply";
  
  // ①HTTPヘッダーの設定
  var headers = {
    "Content-Type" : "application/json",
    "Authorization":secret
  };
  
  // ②画像カルーセルテンプレート詳細作成
  var line_json = [];
  var row,title;
  for (i = 0; i < responseText.length; i++){
    row = responseText[i];
    // タイトルが12文字以上の場合
    if(row[0].length >= 12){
      title = row[0].slice(0,12);
    } else {
      title = row[0];
    }
    //メニュー作成処理
    var fuck = (
      {
        "imageUrl": row[2],
        "action":
        {
          "type": "uri",
          "label": title,
          "uri": row[3]
        }
      }
    );
    line_json.push(fuck);
  }
  
  // ③下記の構造でリクエストボディにデータを持つ
  var data = {
    "replyToken" : token, 
    "messages" : [{
      "type": "template",
      "altText": "新作リリース情報",
      "template": {
        "type": "image_carousel",
        "columns": line_json
      }
    }]
  };
  
 // ④ ①~③で設定した内容をoptionにまとめる
  var options = {
    "method" : "POST",
    "headers" : headers,
    "payload" : JSON.stringify(data),
  };
  // ⑤返信
  return UrlFetchApp.fetch(url, options);
}

全体コード公開

// LINEの認証を突破するために必要なお作法
// botのChannel基本設定の画面で発行した鬼のように長い文字列を""の中にセット
var secret_token = "xxxxx"
var secret = "Bearer " + secret_token;

function doPost(e) {
  var json,token,requestText,releaseInfo,responseText;
  try{
    // LINEから送信されたデータを取得(テキストメッセージそのものではない。)
    json = e.postData.getDataAsString();
    
    // LINEから送信されてきたデータから、リプライトークン(返信するために必要)を取得
    token = JSON.parse(json).events[0].replyToken;
    
    // 送信されてきたテキストを取り出し
    requestText = JSON.parse(json).events[0].message.text;
    
    // 新作情報取得
    responseText = "";
    
    if(requestText == "先週のリリース情報"){
      responseText = readRows("先週");
      sendKercellMessage(responseText,token);
    } else if (requestText == "今週のリリース情報"){
      responseText = readRows("今週");
      sendKercellMessage(responseText,token);
    } else if (requestText == "来週のリリース情報"){
      responseText = readRows("来週");
      sendKercellMessage(responseText,token);
    } else {
      responseText = "返答できないメッセージだよ!"
      sendTextMessage(responseText,token);
    }
    
  }catch(e){
  }finally{
  }
}

function sendTextMessage(responseText,token){
  // リプライを返すAPIのURI
  var url = "https://api.line.me/v2/bot/message/reply";
  
  // お作法① HTTPヘッダーの設定
  var headers = {
    "Content-Type" : "application/json",
    "Authorization":secret
  };
  
  // お作法② 下記の構造でリクエストボディにデータを持つ
  var data = {
    "replyToken" : token, 
    "messages" : [{
      "type" : "text",
      "text" : responseText
    }]
  };
  
  var options = {
    "method" : "POST",
    "headers" : headers,
    "payload" : JSON.stringify(data)
  };
  
  // 返信!
  return UrlFetchApp.fetch(url, options);
}

function sendKercellMessage(responseText,token){
  // リプライを返すAPIのURI
  var url = "https://api.line.me/v2/bot/message/reply";
  
  // お作法① HTTPヘッダーの設定
  var headers = {
    "Content-Type" : "application/json",
    "Authorization":secret
  };
  
  // カーセルテンプレート詳細作成
  var line_json = [];
  var row,title;
  for (i = 0; i < responseText.length; i++){
    row = responseText[i];
    // タイトルが12文字以上の場合
    if(row[0].length >= 12){
      title = row[0].slice(0,12);
    } else {
      title = row[0];
    }
    //メニュー作成処理
    var fuck = (
      {
        "imageUrl": row[2],
        "action":
        {
          "type": "uri",
          "label": title,
          "uri": row[3]
        }
      }
    );
    line_json.push(fuck);
  }
  
  // お作法② 下記の構造でリクエストボディにデータを持つ
  var data = {
    "replyToken" : token, 
    "messages" : [{
      "type": "template",
      "altText": "新作リリース情報",
      "template": {
        "type": "image_carousel",
        "columns": line_json
      }
    }]
  };
  
  var options = {
    "method" : "POST",
    "headers" : headers,
    "payload" : JSON.stringify(data),
  };
  // 返信!
  return UrlFetchApp.fetch(url, options);
}

function readRows(sheetName) {
  // URLを利用してスプレットシートを読み込みます
  var id,sheet,row,values,rows,No,releaseInfo;
  
  id = "xxxx";  
  sheet = SpreadsheetApp.openById(id).getSheetByName(sheetName);  
  rows = sheet.getDataRange();
  values = rows.getValues();
  releaseInfo = "";
  
  return values;
};

//logファイルにログを書き出す
function outputLog(txt) {
  var id,spreadSheet,sheetName;
  
  id = "xxxx";  
  spreadSheet = SpreadsheetApp.openById(id);  
  sheetName = "Linebot_log";
  
  spreadSheet.getSheetByName(sheetName).appendRow(
    [new Date(), txt]
  );
}

完成画面

ラインの画面でボタンを配置し、以下の3つを選択できるようにし、それぞれの情報が画像付きで表示されます。
・先週のリリース情報
・今週のリリース情報
・来週のリリース情報