LoginSignup
4
7

More than 3 years have passed since last update.

Google Apps Scriptで(大体)1時間毎にTweetするBotを作る

Last updated at Posted at 2019-09-07

PHP + cron で動いていた Twitter Bot を Google Apps Script (GAS) で置き換えました。
スクリプトをざっくりメモ書き程度に書いておきます。

スクリプトの全容は Gist/gasTwitterBot.gs に置いておきます。

Bot の要件

  1. Tweetを投稿する
  2. Tweetする内容はスプレッドシートからランダムに取得する
  3. 投稿時間は1時間に1度のペース
  4. Botっぽくないように いい感じ にバラけた時間に投稿する
  5. 投稿は9時から21時の間まで

最終結果

雰囲気はこんな感じです。
Tweet 候補をシートに記載しておいて、コードを実行することであとは寝ているだけで動き出します。

Screen Shot 2019-09-03 at 22.14.20.png

実際に Tweet が投稿された時間帯です。
いい感じにバラけた時間に投稿しているので、Botっぽさが低減されているかと。

起動 9:13
1回目 10:01
2回目 10:33
3回目 12:09
4回目 13:07
5回目 13:50
6回目 14:52
7回目 15:33
8回目 16:32
9回目 18:07
10回目 18:51
11回目 19:46

使い方(参考)

1か2、好きな方をお好みで。

  1. createEveryHoursScheduler() をトリガー画面から実行する
  2. 以下の init() を実行して、好きな時間に createEveryHoursScheduler() の起動を予約する
function init() {
  const time = "好きな時間";
  ScriptApp.newTrigger("createEveryHoursScheduler").timeBased().at(time).create();
}

実現方法

1. Tweetを投稿する

GASでTweetする系の記事はいくつもあるので、それを参考にしていただければ!

参考: Qiita | Google Apps Script (GAS) でTwitterへ投稿するだけの機能を実装してみる
参考: Gist | TwitterWebService.gs

var twitter = TwitterWebService.getInstance(
  'xxxxx', // 作成したアプリケーションのConsumer Key
  'xxxxx'  // 作成したアプリケーションのConsumer Secret
);

// Twitterの認証
function authorize() {
  twitter.authorize();
}

// Tweetをする投稿
function postTweet(tweet) {
  const service  = twitter.getService();
  const response = service.fetch('https://api.twitter.com/1.1/statuses/update.json', {
    method: 'post',
    payload: { status: tweet }
  });
}

// 実際に実行する関数
function execute() {
  const tweet = "HOGE"; // TODO: とりあえず固定
  postTweet(tweet);
}

2. Tweetする内容はスプレッドシートからランダムに取得する

"Tweet" シートのA列に各Tweetが並んでいるのが前提です。
そして「1. Tweetを投稿する」の execute() を少し変更します。

function selectRandomTweet() {
  // Tweetシートを取得する
  const sheetData = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Tweet");

  // 1 ~ 最終行までの行をランダムに選択する
  const lastRow = sheetData.getLastRow();
  const selectedRow = Math.floor(Math.random() * lastRow) + 1; 

  // 選んだ行の内容を取得する
  const selectedTweet = sheetData.getRange(selectedRow, 1).getValue();
  return selectedTweet;
}

function execute() {
  const tweet = selectedTweet(); // tweetをランダムにする
  postTweet(tweet);
}

3. 投稿は1時間に1度のペース

トリガーを設定して、1時間に一回 execute() を実行するようにします。

参考: Google App Script | Trigger
参考: Google App Script | everyHours(n)

function createEveryHoursScheduler() {
  ScriptApp.newTrigger("execute").timeBased().everyHours(1).create();
}

4. botっぽくないようにいい感じにバラけた時間に投稿する

  1. schedulePost() を1時間に1度実行
  2. 次の schedulePost() が実行されるまでの1時間の間で、ランダムな時刻を取得
  3. 取得したランダムな時刻に execute() を実行

参考: Google App Script | at(Date)
注意: 実は at(Date)±15分の誤差 が生まれます(cf. at(Date)


function createEveryHoursScheduler() {
  // schedulePost() を1時間に1度実行するように変更
  ScriptApp.newTrigger("schedulePost").timeBased().everyHours(1).create();
}

function schedulePost() {
  const scheduledTime = getScheduledTime();
  // スケジュールした時刻に execute() を実行する
  ScriptApp.newTrigger('execute').timeBased().at(scheduledTime).create();
}

function getScheduledTime() {
  var setTime = new Date();
  const minutes = setTime.getMinutes();
  const randomMinute = Math.floor(Math.random() * 59);

  // 現在時刻 + 0~59分 の時刻を設定する
  setTime.setMinutes(minutes + randomMinute); 
  return setTime;
}

5. 投稿は9時から21時の間まで

24時間ずっと投稿し続けていると人間らしくありません。
そこで9:00~21:00の間でしか投稿しないように制限します。

function schedulePost() {
  const scheduledTime = getScheduledTime();
  // スケジューリングした時間をバリデーションにかける
  if (!validateHourRange(scheduledTime.getHours())) return;

  ScriptApp.newTrigger('execute').timeBased().at(scheduledTime).create();
}

function validateHourRange(hour) {
  if (hour >= 9 || hour <= 21) return true;  // 投稿したい時間を指定する
  return false;
}

感想

Google Apps Script、めちゃめちゃ多機能で便利だなーと思いました。

  • Google Spreadsheet でコンテンツ管理可能
  • 基本は JavaScript で書ける
  • Debugger 機能
  • 定期実行機能
4
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
7