僕の世界観を変えてみる

文系男子が趣味でプログラミングを勉強していくブログです。他にも日常で起きたどうでもいいことや愚痴を書いていきたいです。座右の銘は和を以て貴しとなすです。仲良くやろうよ。

【GAS】Google apps scriptとスプレッドシートで作るTwitter Bot

この前ツタヤ行った時に犬が座っているフィギュアのガチャガチャ(一回300円)をやったんですよ。

犬バージョンと猫バージョンがあったので2回やって、普通の柴犬とロシアンブルーが出たんですね。

可愛かったんで彼女にあげるって言ったら、いやまじでいらんって言われてすごく傷つきました。

こんばんは、えこです。

今日はですね、前々から気になっていたTwitter Botを作っていきたいと思います。

Twitter APIに登録

GASに限らずTwitterの機能を他のプログラムで使用する場合はTwitterAPIに登録し、コンシューマーキーを取得する必要があります。

登録には時間がかかるのと、少し苦労するので根気が必要です。(僕の場合は)

方法に関しては別の記事を参考にして下さい。

www.htmllifehack.xyz

ライブラリの追加

まずGASからツイートを行う為のライブラリを追加します。

1つ目はTwitterWebService

非公式ですがこのライブラリを使用した方が簡単です。

バージョンは2を使用。

TwitterWebService.gs · GitHub

プロジェクトキー: 1rgo8rXsxi1DxI_5Xgo_t3irTw1Y5cxl2mGSkbozKsSXf2E_KBBPC3xTF

2つ目はOAuth1

OAuthはアカウントに権限を許可する仕組みのことで、"○○にアカウントの利用を許可しますか?"と表示されるあれです。

こちらも非公式ですが、この他の認証方法を僕は知らないのでこちらを利用させていただきました。

バージョンは最新のものを使用します。

2019年7月現在はバージョン16です。

GitHub - gsuitedevs/apps-script-oauth1: An OAuth1 library for Google Apps Script.

プロジェクトキー: 1CXDCY5sqT9ph64fFwSzVtXnbjpSfWdRymafDrtIZ7Z_hwysTY7IIhi7s

f:id:htmllifehack:20190723153457p:plain
ライブラリのバージョン

認証してみよう

まず、GASからTwitterAPIを使えるようにコンシューマーキーを与えます。

// 変数twitterにコンシューマーキーを渡す
var twitter = TwitterWebService.getInstance(
  "**************************",
  "**************************");

コンシューマーキーはTwitterのDeveloper用サイトで確認することができます。

Developer — Twitter Developers

f:id:htmllifehack:20190723174918p:plain
コンシューマー

次にGASがTwitterアカウントにアクセスできるようにOAuth認証して権限を与えます。

// Twitterアカウントの認証をする関数
function authorize(){
    twitter.authorize();
    }


// 認証の解除をするための関数.
// ほかのTwitterアカウントでログインする場合はresetを実行してから
function reset(){
    twitter.reset();
    }


// 認証後のコールバック 直接触ることはない
function authCallback(request) {
  return twitter.authCallback(request);
}

これらの関数は定められているのか関数名を変更するとうまく動作しません。

さて、このままコードを実行するとcallbackのエラーが発生します。

Error starting OAuth flow: <?xml version="1.0" encoding="UTF-8"?>Callback URL not approved for this client application. Approved callback URLs can be adjusted in your application settings(行 334、ファイル「Service」、プロジェクト「OAuth1」)

なんでも2018年ごろからcallbackのURLを指定しなければAPIの機能が使えなくなったんだとか。

TwitterのAPIでcallbackURLをチェックするようになった - Qiita

なのでTwitter DeveloperのサイトでcallbackURLを登録します。

f:id:htmllifehack:20190723173858p:plain

callbackURLはhttps://script.google.com/macros/d/*************/usercallbackの*の部分にGASのスクリプトIDを入力します。

スクリプトIDはGASのエディタから、ファイル→プロジェクトのプロパティ→スクリプトIDで確認できます。

f:id:htmllifehack:20190723180617p:plain
プロパティ
f:id:htmllifehack:20190723180634p:plain
スクリプトID

あるいは下記のコードを実行するとログにcallbackURLが表示されます。

function logCallbackUrl() {
  var service = twitter.getService();
  Logger.log(service.getCallbackUrl());
}

お好きな方でお試しください。

以上ができましたら関数authorizeを実行してください。

エラーがでなければログに認証用のURLが表示されるはずです。

ログとはGASのページの、表示→ログ、のことです。

表示されたURLをコピーしそのページに飛ぶとTwitterの認証画面になるので、許可して権限を与えてください。

これでGASからTwitterにアクセスできるようになりました。

GASからツイートしてみる

次はツイート用のコードを書いていきます。

function tweet(){
  var response = twitter.getService().fetch('https://api.twitter.com/1.1/statuses/update.json',{
    method: "post", payload: { status: "やあ"}
  });
}

参考サイト:[Google Apps Script (GAS) でTwitterへ投稿するだけの機能を実装してみる - Qiita

するとこんな感じでツイートされます。

ちなみにツイートの詳細を見るとGASからツイートされていることがばれちゃいます。

他にもフォロワー数のリクエストを送ったり色々できますが詳しくはTwitter Developersを参照ください。

ランダムでツイートする

次はスプレッドシートにあらかじめ入力しておいた文言をランダムで呟くことにします。

スプレッドシートになんでもいいのでツイートしたい文言を入力します。

f:id:htmllifehack:20190724094907p:plain
スプレッドシート

ツイートリストを作ったら次はGASからスプレッドシートを読みにいきます。

var ssid = "****************************************";
var sh = SpreadsheetApp.openById(ssid).getSheetByName("tweet_list");

変数ssidはスプレッドシートIDを入れます。

IDはスプレッドシートのURL、https://docs.google.com/spreadsheets/d/***********/edit#gid=0の *マークの部分です。

変数shはシートの名前を指定してあげます。

次にツイートする文章を取得していきます。

var last_row = sh.getRange("b:b").getValues().filter(String).length;

var tweet_list = [];
for(var i=0;i<last_row;i++){
  tweet_list.push(sh.getRange(3+i,2).getValues());
}

sh.getRange("b:b").getValues()にするとB列の値全てを取得してしまいます。

すると空白のセルも含んでしまうのでfilter(String).length;で文字が入力されているセルの数だけを数えるようにします。

今回はB2のtweet_listという項目も含まれて、last_rowには6が入っています。

変数tweet_listで空のリストを作りこの中にfor文でツイートの文章を入れていきます。

for文の1行目は、0からlast_rowになるまでiの数を増やすという意味です。

2行目は、シートの(3,2)の値をtweet_listに入れるという意味です。

シートはエクセルと同様、A1やB2という指定の他に(行、列)で指定できます。

さて、リストが完成したので次はランダムで文言を取り出していきます。

var rand = Math.floor(Math.random()*last_row);

Math.randomは0〜1未満の数字をランダムで生成します。

Math.floorは小数点以下を切り捨て整数で返す関数です。

function sample(){
  for(var i=0;i<10;i++){
    Logger.log("random : " + Math.random());
  }
  Logger.log("floor : " + Math.floor(1));
  Logger.log("floor : " + Math.floor(1.2));
  Logger.log("floor : " + Math.floor(0.8));
  Logger.log("floor : " + Math.floor(1-.8));
}

/*
random : 0.11979965249669566
random : 0.7574196515945959
random : 0.9663028636931555
random : 0.8088873717871752
random : 0.6110360848011891
random : 0.9555394766433617
random : 0.44548536263625693
random : 0.42640056795875547
random : 0.2198717198158735
random : 0.5479904596445123
floor : 1
floor : 1
floor : 0
floor : -2
*/

randomで生成された数字にlast_rowをかけることで整数にしてあげます。

0.1が生成された場合、そこにlast_rowの6をかけるので0.6、floorで変換されて0

0.9が生成された場合、6をかけると5.4、floorで変換されて5、という具合です。

そしてこのrandomとfloorで生成された数字をリスト番号に充てます。

function tweet(){
  var response = twitter.getService().fetch('https://api.twitter.com/1.1/statuses/update.json',{
    method: "post", payload: { status: tweet_list[rand]}
  });
  }

最後に以上のスクリプトをトリガーに設定してBotの完成です。

自動的にツイートする

スクリプトの編集画面から、編集→現在のプロジェクトのトリガー、をクリック。

f:id:htmllifehack:20190727224532p:plain
トリガー

画面が変わったら右下にある、+トリガーを追加、ボタンをクリック。

ここで実行する関数をtweetに、イベントのソースを選択を時間主導型に変更し、時間の間隔を選択して保存するだけです。

f:id:htmllifehack:20190727225011p:plain
トリガー

まとめ

いかがでしたでしょうか。

pythonでBotを作る場合はHerokuを使ったりAWSを利用したり、とにかくサーバが必要になってきます。

その点GASはGoogleのサーバを利用して行っているため、その辺の心配はいりません。

GASについての記事は多くはないので苦労するかもしれませんが、コードを理解するよりもまずやってみたほうがいいですね。

さて、今回は文字をツイートだけでしたが実は画像データを投稿するBotも作れるんですよ。

次回は画像Botの作り方を記事にしよう!と思ったんですが、noteで販売していってもいいかなって考えています。

ということで今回は以上です。

次回もがんばります!