占いしてくれる Twitter Bot を GASで作った
これは株式会社SUPER STUDIO Advent Calendar 2022の18日目の記事です。
きっかけ
ある日、占いをしている友人から連絡を受けた。
友達「占いの集客の一つとして Twitter アカウントを利用しててさー」
ボク「へー」
友達「特定のワードを含むリプライをされたら、自動返信をする機能が欲しいんだよね」
ボク「そういうサービスすでにあると思うよ」
友達「うん、知ってる。けどあれを使うと、Twitter for iPhone みたいな送信元の表示に、〇〇bot って表示される」
ボク「うん」
友達「Bot臭がしちゃうと、イケてないじゃんー」
ボク「そういうもんかー」
友達「できそう? できれば焼き肉とかご馳走しちゃうよ」
ボク「やってみるー。(はじめてのクライアントワークだー)」
ということで作ってみた
自動返信機能のコードだけ教えてあげようと思ったのだけれど、せっかくなので試しに占いアカウントを作ってみた。それがこちら。 このTwitterアカウントに、「占って」とリプライをすると、占い結果が返ってくる。
やっていることは、、、
- 自分へのリプライを監視する
- 占って、というワードが含まれていることの検知
- スプレッドシートからランダムにテキストを選ぶ
- リプライにリプライを返す
です。
こうやって作った
まずは、Twitter側で必要な準備をする。参考記事はたくさん見つかる。 ボクはこちらを参考にした。インターネットには何でもある。
【GAS】Google Apps ScriptでTwitter API v2.0を使ってみた【Twitter】 » CAMPANISTA
Twitter認証までできたら、早速自動返信機能を実装する。
まず、このようにスプレッドシートを用意する。なぜ、1なのかは、こちらを参照。
こちらのコードを書く。愚直に書いたのであまりきれいではない。
function auto_reply() { //リプライ内容を書いたスプレッドシートの情報を取得 var spreadsheet = SpreadsheetApp.openById('[スプレッドシートのID]'); var sheet = spreadsheet.getSheetByName('[リプライのテキストのあるスプレッドシートのシート]') //最後に取得したTwitterのリプライのIDをシートのA1セルから取得 var last_id = sheet.getRange("A2").getValue(); var result = {}; result = getNewReply(last_id); // リプが0件の場合は強制終了 if (result.result_count === 0) return; last_id = result.last_id; //GASの動作制限にかかった場合は強制終了 if (result['replies'] == false) return; result['replies'].forEach(function(value) { var text = value['text']; text = text.replace(/ /g," "); //「占って」という単語に反応する if (text.includes('占って')) { var message = makeTextToSend(); var replyTo = value['id'] tweet_reply(replyTo, message) } } ); sheet.getRange("A2").setValue(last_id); Logger.log(last_id); } //リプライをくれたTwitter ID・text・最後のリプライしたtweet_idを記憶 function getNewReply(last_id) { //リクエストオプション var options = { "method": "get", "headers": { "authorization": "Bearer [作成したTwitter bot のBearerトークン]" } } var url = "https://api.twitter.com/2/users/[運用するtwitter アカウントのID]/mentions?since_id=" + last_id var response = JSON.parse(UrlFetchApp.fetch(url, options)); // リプライの情報を格納 resp = {} resp['replies'] = response.data resp['last_id'] = response.meta.newest_id resp['result_count'] = response.meta.result_count return resp; } // リプライする function tweet_reply(tweet_id, message){ //トークン確認 var service = checkOAuth(appname); // ここはTwitter 認証等で参考にした記事によるかもしれない //message本文 var message = { //テキストメッセージ本文 reply: { in_reply_to_tweet_id: tweet_id }, text: message } //リクエストオプション var options = { "method": "post", "muteHttpExceptions" : true, 'contentType': 'application/json', 'payload': JSON.stringify(message) } //リクエスト実行 var response = JSON.parse(service.fetch("https://api.twitter.com/2/tweets", options)); //リクエスト結果 console.log(response) } // リプライするテキストを取得 function makeTextToSend(){ try { //リプライ内容を書いたスプレッドシートの情報を取得 var spreadsheet = SpreadsheetApp.openById('[スプレッドシートのID]'); var sheet = spreadsheet.getSheetByName('[リプライのテキストのあるスプレッドシートのシート]') var maxRow = sheet.getDataRange().getLastRow(); //最終行の番号を取得。特定の列にしている方がいいかも var rand_res = getRrandRes(maxRow)//ランダムで行数を決める //B列:ツイート内容 var tweetString1 = "B" + rand_res; var tweet1 = sheet.getRange(tweetString1); //リプライ内容をresultに入れて tweet_reply関数へ返す var result = tweet1.getValue() return result; } catch(e) { } } // 2以上最大行数以下の整数の乱数 function getRrandRes(maxRow){ var x = 2 var y = maxRow +1 return Math.floor(Math.random()*(y-x)+x) }
実装で困ったこと
Twitter API では自分のアカウントにリプライしてくれたツイートについて調べるAPIが用意されている。それになかなか気づけなかった。
https://api.twitter.com/2/users/[運用するtwitter アカウントのID]/mentions
このエンドポイントを叩くと、リプライをしてくれた全ツイートに関する情報を渡してくれる。便利だ。ただし、毎回全部の情報はいらない。すでにリプライしたツイートに関する情報は不要だ。なのでひと工夫する。
エンドポイントが返す情報の中には、最後にリプライしてくれたツイート情報があるので、そのツイートIDをスプレッドシートに記録しておく。「最後にリプ返したtweet_id」がそれだ。そして、次回エンドポイントを叩くときに、since_id にそのツイートIDを渡してあげれば、それ以降のリプライを拾ってくることができる。下記のように。
https://api.twitter.com/2/users/[運用するtwitter アカウントのID]/mentions?since_id=" + last_id
あとはこの処理を含む関数 auto_reply を GASのトリガー機能を使って1分ごとに動くようにすれば完成。このあたりもネットに記事が置いてある。
友人に報告
ボク「作ったよー」
友人「おおーすごいー」
ボク「焼き肉おごってー」
友人「これだけだとなー。実際は自動返信機能よりも、自動定期投稿機能が欲しかったんだよねー」
ボク「そっかー。できたらまた連絡するねー。(まじかー、ちゃんとヒアリングするべきだったー。クライアントワーク、ムズカシイ!)」
参考
【GAS】Google Apps ScriptでTwitter API v2.0を使ってみた【Twitter】 » CAMPANISTA https://campanista.com/gas_twitter/
プログラミング未経験でもできた!文系女子がGASでTwitterのbot作ってみた - paiza開発日誌 https://paiza.hatenablog.com/entry/2020/02/14/バレンタインにチョコが届く!%3F_プログラミング未
Google Apps Script での 「oAuthConfig」のサポート終了後用の Twitter API スクリプト。「OAuth1」ライブラリ(ID:Mb2Vpd5nfD3Pz-_a-39Q4VfxhMjh3Sh48)が必要。 · GitHub https://gist.github.com/kijtra/f4cdd8775277372d42f7
【GAS】Twitterのbotを作ってみました。サクッとできます! | Webird Programming.Tech http://webird-programming.tech/archives/274#toc8
Google Apps Script での 「oAuthConfig」のサポート終了後用の Twitter API スクリプト。「OAuth1」ライブラリ(ID:Mb2Vpd5nfD3Pz-_a-39Q4VfxhMjh3Sh48)が必要。 https://gist.github.com/kijtra/f4cdd8775277372d42f7
【爆速】自作のTwitterBotを簡単に作るライブラリを作った話【初心者向け】 | すずきライフ https://belltree.life/twitterbot-library/
Twitter Search API v1.1 と v2の 違いメモ - Qiita https://qiita.com/TakeshiNickOsanai/items/cf695370dde1ec21dbd6
GASでTwitterのAPIを使用して、ツイートの内容を取得する https://zenn.dev/specially198/articles/54d0b957f185b8
Google Apps Script(GAS)でTwitter API v2の非公開統計情報を取得する https://zenn.dev/rikei_ocojo/articles/gas-twitter-non-public-metrics
Google Apps ScriptからTwitter API v2を使ってツイートする【GAS】 🌴 officeの杜 🥥 https://officeforest.org/wp/2021/05/22/gas_twitter_v2/
(了)