Amazonギフト券で2%ポイントバック

【LINE Botの作り方】Python × Messaging APIでプッシュ通知を行うボットを作ろう

この記事を読むのに必要な時間は約 21 分です。

この記事を読むのに必要な時間は約 21 分です。

LINEのMessaging APIがお手軽に使えると聞いて何か作ってみたくて作成しました。よくあるのがボットに対してメッセージを送るとおうむ返しだとかリアクションを取るボットですが、今回はプッシュ通知を行うボットを作成しました。
【LINE Botの作り方】Messaging API × GAS(Google Apps Script)でおうむ返しボットを作成する

プッシュ通知とは

LINEボット側からメッセージを送信することを指します。前回作成したボットはボットに対してメッセージを送信することでリアクションが返ってきましたが、そうではなくボットから通知を行います。
Messaging APIで作成できるLINEボットのメッセージの種類はこの「リプライメッセージ」と「プッシュメッセージ」の2種類になります。そのため、今回のプッシュメッセージを覚えてしまえば前回の内容と合わせてだいたいのボットは作れるようになるわけです。

プッシュ通知を行うボットの活用方法

活用方法はアイディア次第でいくらでもありますが、このサイトで扱っているジャンルで言うと、

  • 動画配信サイトに新作が追加されたタイミングで通知する
  • 仮想通貨の取引所に新規銘柄が上場したら通知する

とかがありますね。実際に後者のボットは作成してソースやボットなどはnoteと言うサービスで公開しています。
仮想通貨の新規上場銘柄をLINE通知するボットを公開
プッシュメッセージ型のLINE Botはプログラムで何かを監視しておいて、変化があった場合に通知を行うといった使い方がメインになるかと思っています。
 

Messaging APIのフリープランではプッシュ通知の友達追加は50人まで

これはちょっと注意点というか、一応知っておくべきポイントでMessaging APIは無料で使用可能ですが、ある程度の制限がかかります。プッシュ通知が行える「For Developer」プランのボットは友達追加が50人までしか行うことができません。
なのであくまでも身内というか少人数でこっそりと楽しむ内容が中心になります。もちろん課金して有料プランに切り替えれば上限はもちろん増やせるので、本格的にサービスとしてやられる方はその点だけ注意が必要です。
 

プッシュ通知型LINEボットの実装方法

必要なものと手順を以下に記載しておきます。

必要なものと手順
必要なもの

  • Cloud9
  • Google Apps Script
  • Google Spreadsheet
  • Messaging API

実装手順

  1. Messaging APIの作成
  2. GASとSpreadsheetでユーザーID管理を実装する
  3. プッシュメッセージの送信処理を実装する
  4. PythonからGASの処理を実行する
PythonはCloud9上で動かすのでそこから準備しておいてください。

※Pythonを常時動かしていられればCloud9である必要はありません。ラズパイやHerokuなどを利用しても作成は可能です。

「Cloud9ってなに?」という方は以下の記事の最初の方に記載があるので軽く読んでおいてください。
今回の全体像は以下のような感じになります。前回のリプライボットと比べると少し使用するものが多いですが、どれも役割自体は単純なのでだいたいの雰囲気を掴んでください。また、矢印も一方通行に変わっているものが多いです。

 

1.Messaging APIの作成

LINEのMessaging APIはプランが2つあります。「フリー」と「For Developer」プランです。

Messaging APIの2つのプラン
  • フリー:友達追加の制限は無いが、プッシュメッセージは使えない
  • For Developer:友達追加は50人までだが、プッシュメッセージが使える
今回はプッシュメッセージを実装していくので「For Developer」プランで開発を進めていきます。
 

2.GASとSpreadsheetでユーザーIDを管理する

プッシュメッセージ型ボットでいちばん重要なのがこの部分です。Messaging APIでプッシュメッセージを送信する際にはユーザーIDを指定する必要があります。リプライ型とかだと、ユーザーから送られてきたメッセージに返信用のアドレスが含まれており、そこに返すだけでよかったのですが、プッシュメッセージはそれができません。
なので、どこかしらに現在友達追加されているユーザーIDの一覧を保管しておく必要があります。
GASの場合だと同様にGoogleのサービスの一つである「Google Spreadsheet」を使用するのが簡単です。
Spreadsheetを知らない方向けに簡単に説明しておくと、SpreadsheetはGoogle版Excelのようなものになります。それがオンライン上で無料で使えるようになったサービスと考えるとイメージしやすいかと思います。
GASとの連携も簡単で、たったの数行でSpreadsheetに対してのデータの読み書きが行えます。

2-1.友達追加のタイミングでユーザーIDを記録する

友達追加のタイミングは前回の記事でも記載していますが、もう一度記載しておきます。以下のソースはMessaging APIをGASで受け取る場合の基本形になるので覚えておいてください。

var access_token = "Messaging APIのアクセストークンを指定"
// ボットにメッセージ送信/フォロー/アンフォローした時の処理
function doPost(e) {
  var events = JSON.parse(e.postData.contents).events;
  events.forEach(function(event) {
    if(event.type == "message") {
      reply(event);
    } else if(event.type == "follow") {
      follow(event);
    } else if(event.type == "unfollow") {
      unFollow(event);
    }
 });
}
/* 友達追加されたらユーザーIDを登録する */
function follow(e) {
}

event.typeが”follow”の時が友達追加が行われたタイミングとなるので、この「function follow(e)」でユーザーIDを記録する処理を記載すれば良さそうです。
一旦先に解答となるソースも貼っておきますが、ここでSpreadsheetと連携を行います。

/* 友達追加されたらユーザーIDを登録する */
function follow() {
  var spreadsheet = SpreadsheetApp.openById('SpreadsheetのIDを指定');  //スプレッドシートの指定
  var sheet = spreadsheet.getActiveSheet(); //シートを取得する
  sheet.appendRow(['ユーザーID']); //ユーザーIDをシートに追加する
}

たったのこんだけです。3行あればスプレッドシートへ値を書き込むことができるわけです。めちゃめちゃ簡単ですね。
「SpreadsheetのID」はSpreadsheetを開いている時のURL欄を見るとわかります。途中で途切れていますが、この赤枠の部分です。適当にSpreadsheetを作成して保存したら、赤枠部分をコピーして先ほどのソース部分に貼り付けてください。

試しにこのfollow関数を単体で実行して見るとスプレッドシートに「ユーザーID」という文字が書き込まれるかと思います。(followの引数のeを消す必要あるかも)
初回実行時はアクセスを許可するかを聞かれるので許可するで進めてください。




GASとSpreadsheetの連携がうまく行くことが確認できたらソース上のユーザーIDの部分にfollowしたユーザーIDが入るように以下のように書き換えておいてください。

/* 友達追加されたらユーザーIDを登録する */
function follow(e) {
  var spreadsheet = SpreadsheetApp.openById('SpreadsheetのIDを指定');  //スプレッドシートの指定
  var sheet = spreadsheet.getActiveSheet(); //シートを取得する
  sheet.appendRow([e.source.userId]); //ユーザーIDをシートに追加する
}

2-2.友達解除のタイミングでユーザーIDを削除する

プッシュ通知はSpreadsheetのユーザーIDに対して実行するので、既に友達から外されているユーザーには送る必要がありません。
そのため、削除されたり、アンフォローされたタイミングで対象のユーザーIDを削除する必要があります。この処理を書く場所はわかりますよね。
ソースコードは以下になります。アンフォローされたら、ユーザーIDを管理しているスプレッドシートから対象のユーザーIDを探して、その行を削除するというものです。行検索は自分で「findRow」という関数を定義して実装しています。

/* アンフォローされたら削除する */
function unFollow(e){
  var spreadsheet = SpreadsheetApp.openById('SpreadsheetのIDを指定');
  var sheet = spreadsheet.getActiveSheet();
  var result = findRow(sheet, e.source.userId, 1);
  if(result > 0){
    sheet.deleteRows(result);
  }
}
function findRow(sheet,val,col){
  var data = sheet.getDataRange().getValues();
  for(var i=0; i < data.length; i++){
    if(data[i][col-1] === val){
      return i+1;
    }
  }
  return 0;
}

2-3.動作を確認しよう

ここまでのソースで友達追加時にスプレッドシートにユーザーIDを記録、友達解除時にスプレッドシートからユーザーIDを削除という処理が行えるようになっているはずです。
前回の記事と同様に「公開 > ウェブアプリケーションとして公開」を行い、Messaging APIのWebhookに指定してください。
【LINE Botの作り方】Messaging API × GAS(Google Apps Script)でおうむ返しボットを作成する LINEボットの友達追加と解除でスプレッドシートの更新が行われているか確認してください。うまくいかない場合は何かしら間違えているので前回と今回の記事を見直してチェックしてください。

function doPost(e) {
  var events = JSON.parse(e.postData.contents).events;
  events.forEach(function(event) {
    if(event.type == "message") {
      reply(event);
    } else if(event.type == "follow") {
      follow(event);
    } else if(event.type == "unfollow") {
      unFollow(event);
    }
 });
}
function follow(e) {
  var spreadsheet = SpreadsheetApp.openById('SpreadsheetのIDを指定');  //スプレッドシートの指定
  var sheet = spreadsheet.getActiveSheet(); //シートを取得する
  sheet.appendRow([e.source.userId]); //ユーザーIDをシートに追加する
}
function unFollow(e){
  var spreadsheet = SpreadsheetApp.openById('SpreadsheetのIDを指定');
  var sheet = spreadsheet.getActiveSheet();
  var result = findRow(sheet, e.source.userId, 1);
  if(result > 0){
    sheet.deleteRows(result);
  }
}
function findRow(sheet,val,col){
  var data = sheet.getDataRange().getValues();
  for(var i=0; i < data.length; i++){
    if(data[i][col-1] === val){
      return i+1;
    }
  }
  return 0;
}

 

3.プッシュメッセージの送信処理を実装する

いよいよ本題のところ。Messaging APIのリファレンスによると、プッシュメッセージは単一ユーザーと複数ユーザーに送るとでエンドポイントが別れています。今回は複数ユーザーに送るということで、まず公式リファレンスから確認していきます。



「https://api.line.me/v2/bot/message/multicast」に対してPOST通信を行えば良いことがわかります。ヘッダーやメッセージなどはリプライの時と同様でTOの指定方法だけ異なるようです。
そのため、これまた前回の記事で記載した処理が流用できそうです。変更点は最初のスプレッドシートから値を取得するところと取得した値をtoに指定しているところだけです。他は同様の記述で問題ないです。

//スプレッドシートからユーザーを配列で取得してメッセージを送信
function push(message) {
  var spreadsheet = SpreadsheetApp.openById('SpreadsheetのIDを指定');  //スプレッドシートを取得
  var sheet = spreadsheet.getActiveSheet(); //シートを取得
  var data = sheet.getDataRange().getValues(); //シートに記載されている値を全て取得
  var userlist = []; //型を整えるためにuserlistを作成し値を詰める
  for(var i=0; i < data.length; i++){
    userlist.push(data[i][0]);
  }
  var postData = {
    "to" : userlist, //ここに取得したユーザーIDの配列を指定する
    "messages" : [
      {
        "type" : "text",
        "text" : message
      }
    ]
  };
  var options_push = {
    "method" : "post",
    "headers" : {
      "Content-Type" : "application/json",
      "Authorization" : "Bearer " + channel_access_token
    },
    "payload" : JSON.stringify(postData)
  };
  UrlFetchApp.fetch("https://api.line.me/v2/bot/message/multicast", options_push);
}

 

4.PythonからGASの処理を実行する

Python側の処理もかなり簡単に書けます。GASはGETかPOSTで処理を受け取りますが、POSTはLINEボットへメッセージを送信した時にも使用されているのでGETの処理をPythonから実行する処理を記述していきます。
以下で定義した関数にプッシュ通知を行いたいメッセージを渡してあげるだけでOKです。簡単ですね。
「url」はGASを公開した時に表示されるURLを指定してください。そのURLの最後に「?message=」とだけ追記するのを忘れずに。これを追記してあげることで引数として値を渡すことができます。
リプライメッセージの説明で「e」という引数から色々と値を取り出していたかと思いますが、それと同様です。

def lineMessagingAPI(message):
    url = "https://script.google.com/macros/s/'GASのURLを指定'/exec?message="
    url = url + message
    result = requests.get(url)

ちなみにこのメッセージに改行を入れたい場合は「%0A」と記述しておくと勝手に改行されるようです。
 

4-1.GAS側でPythonからの処理を受け取る

PythonからGETでリクエストを飛ばしているのでGAS側でもdoGetを実装してそこから先ほど記載したプッシュメッセージを送信する関数に繋げます。

//ボットの友達にPush通知する処理
function doGet(e) {
  push(e.parameter.message)
}

こんな感じですね。「e.parameter.message」でPythonから渡したmessageの引数を受け取ることができます。そのメッセージを先ほど作った関数に渡してあげるだけです。
これで全体の流れと実装部分の説明は終了です。
あとはPython側でどのタイミングにどのようなメッセージを送信するか考えるだけですね。(そこが一番重要な気はしますが。)
 

まとめ

いかがでしたでしょうか。一つずつ説明していたので長文になってしまいましたが、やっていること自体はかなり単純です。
この記事の内容さえ理解できてしまえば、プッシュメッセージ型のLINEボットはだいたい作れるかと思います。ぜひ試してみてください。
わかりにくい点や質問があればコメントなどに残していただければ時間がある時に返信します。
 

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA