GASでこれはどう作る?〜実装サンプル集〜【プログラミング初心者向け】

GAS/TwitterBot
two 3d humans give their hand for handshake
この記事は約5分で読めます。

またまた様々なコメント頂きました〜

スプレッドシートに書き込みそこから投稿する方法はいまいち理解できません

質問があるのですが、『スプレッドシートの順番通りにツイートするTwitterBotの作り方』のように順番にいいねやRTをするにはどのようにすればいいのでしょうか。

いいねやRTの回数を検索ワードごとに指定することはできないのでしょうか。

様々なコメントありがとうございます。

これまで様々なTwitterBotを作ってきましたが実際に作ってみると細かい設定が欲しくなってくる頃だと思います。

一人ひとりにあったプログラムを書いていくのは限界があるので、今回はTwitterBotでよく使うGASのプログラミングのテクニックをまとめていこうと思います。

GASでスプレッドシートに書いたものを取得する

スプレッドシートに書き込みそこから投稿する方法はいまいち理解できません

まずはこちらの回答に答えていきます。

投稿に関してはTwitterのAPIを実行するだけなので、スプレッドシートのデータ取得周りについて詳しく解説していきます。

GASでスプレッドシートの取得は頻出

GASでスプレッドシートの取得は頻出です。TwitterBot以外でもよく使うため是非覚えましょう。

SpreadsheetAppというライブラリにシートの情報を取得する関数が揃っています。

↑で書いたように少しずつ階層を細かく指定していき、getValuesでデータを取得します。

取得したデータは2次元配列となっており、行ごとのデータが配列に入っています。

cellsなどの変数にデータを入れたあとは for などを使ってデータを取り出して処理に利用してください。

今回4つの関数を使っていますが、Spreadsheet Service のサイトに全ての関数が載っているので利用してみましょう。

出来るだけまとめてデータを取得しましょう

GASのgetRange,getValues(getValue)は非常に時間がかかります。

スプレッドシートのデータを取りたい場合は、forの中で呼び出すのではなく、forの外側であらかじめ取得しておくことが大切です。

GASを使って順番に処理を実行する

続いてこちらの質問に移ります。

質問があるのですが、『スプレッドシートの順番通りにツイートするTwitterBotの作り方』のように順番にいいねやRTをするにはどのようにすればいいのでしょうか。

GASは毎回同じ処理しか出来ない

GASは毎回同じ関数を実行することしか出来ません。

つまり順番で実行したいときに「前回Aのツイートを投稿したから次はBの投稿を行う」という設定の仕方は仕様上出来ません。

このような処理をしたい場合はプログラムの中で『前回どこまで処理を行っていたか』を記録しておくことが重要になってきます。

処理を実行したら実行記録を付ける

記録を付ける場合、2種類の記録方法があります。

1つは実行回数を記録する方法、もう1つは実行したかどうかのフラグを記録する方法です。

順番で且つループさせたい場合は実行回数を記録する方法を使います。

1度だけ実行させたい場合は、数字で回数を保存する必要はないのでTrueとFalseでチェックしていきましょう。

実装サンプル(順番でのループ)

プログラムに合わせて図に表すと以下のようなイメージになります(例:順番に投稿)

これをプログラムに落とし込むと以下のようになります。

プログラムは文字が多くて面食らうかもしれないですが、図と照らし合わせながら分解すれば、少しは読みやすくなるはず…(´・ω・`)

応用例(TwitterClientを利用して順番にRTするBotを作る)

いいねやRTを行いたい場合、表の1列目に投稿文でなく、ツイート情報を入力することで応用することが出来ます。

私が作ったTwitterClientのライブラリを使う必要があるのですが、以下のようなシートを作って、数行のコードを書くだけで順番にRTするBotになります。

GASでデータ毎に個別の設定(オプション設定)をする

いいねやRTの回数を検索ワードごとに指定することはできないのでしょうか。

できます!細かい設定を追加したい時は列を増やして実装を追加します。以下の記事を例にします。

上記の記事ではスプレッドシートはこのような形になっていましたが、1列「実行回数」を追加します。

変更&追加が3箇所あるのですが、わかりますでしょうか…?

  1. 最初のforの var limit = searchWords[i][3];
  2. 2個目のforの if (count == limit) 付近
  3. pickUpSearchWords の var endCol = 4;

ですね。データを追加で取得して回数を数える処理になっています。

回数以外にも「特定のアカウントで絞りたい」「特定の地区限定のツイートで絞りたい」という細かい設定も出来ます。(参考

スプレッドシートを活用すれば大抵のことは出来る

GASはPHPやPythonのような汎用性の高いプログラミングではないのですが、ある程度のことであれば出来ます(認証が弱いのでサービスとかは作れないですが。。)

GASにおけるスプレッドシートはサービスで言うデータベースに当たるので、一時的なデータの保存が出来ますし、ライブラリによってGoogleDriveなどのリソース関連も管理できます。

APIの受け口にも出来るため、ちょっとした外部ツールとの連携も出来ますし、本当に色々出来ます。

これって作れるの?みたいなのがあれば普通に相談くらいは乗れると思うのでお気軽にご連絡ください。

ここまで読んで頂きありがとうございました〜

コメント

  1. リクエストに応えていただきありがとうございます。回数を指定するにはそのようにすれば良いのですね。
    それから、大変申し訳ないのですがスプレッドシートの順番通りにツイートするTwitterBotのように上から順番にRTする為にはどのようにすれば良いのでしょう。記事のサンプルコードを組み合わせれば出来るのだと思いますが、何処をどうして良いかよく分からず上手くいきません。
    お手間を取らせてしまい誠に恐縮なのですがご教示いただけないでしょうか。

  2. 突然失礼します
    受け取った@ツイートに対してリプライを飛ばす機能はできますでしょうか?

  3. はじめまして、参考にさせていただきました。

    ひとつ質問です。

    返信ツイートをRTしない方法はありますでしょうか?

    お手数をおかけしますが、よろしくお願いいたします。

    • この記事のサンプルを参考にすると、RTする前にツイートを1つ1つ確認する処理があるので、そこでリプライだったら弾く処理を入れるのはいかがでしょうか?
      リプライの場合はツイートのデータに in_reply_to_status_id という返信先のデータが含まれるのでそれがあったら飛ばすという感じでいけるかと

      https://gist.github.com/belltreeSzk/0d0ee28f49a1d8737adbf8946c18f991

  4. 返信ありがとうございます。
    教えていただいたコードをどのようにいじればよいのかわかりません。

    お手数をおかけしますが、よろしくお願いいたします。

    • 今ってコードはどこを参考にしてますか?
      言葉で説明しにくい場合は suzuki@belltree.life 宛に現状のコード送ってください〜

  5. お初にお目にかかります。参考にさせていただきます。
    毎日の特定時刻(午後11時55分、午前6時、午前6時25分……)や特定曜日の特定時刻(午前6時30分、午前6時35分、午前6時40分……)に予約投稿をする場合、スプレッドシートやコードをどのように変更するとうまく行くでしょうか。

    • GASって分指定の実行がないので困りますよね…
      結構力技なんですが、「『毎分実行』で設定した上で条件にヒットしなかったら即終了」って処理を作って対処していました。
      以下にサンプルを載せておくので参考程度に見てもらえると幸いです!(曜日までは判定していないのでご注意ください・・・)

      // リストのツイートを取得する時間
      const execTimes = [
        '23:55',
        '6:00',
        '6:25',
      ]
      
      // 実行時間判定
      function isExecTime () {
        const now = new Date();
        const hour = now.getHours();
        const minute = now.getMinutes();
        let isHit = false;
        for (let i in execTimes) {
          const execTime = execTimes[i];
          const times = execTime.split(':');
          if (Number(times[0]) === hour && Number(times[1]) === minute) {
            isHit = true;
          }
        }
        return isHit;
      }
      
      // この関数に毎分実行のトリガーを入れる
      function main () {
        // ここで条件にあう時間かチェックする
        if (!isExecTime()) {
          return;
        }
        // やりたい処理を以下に書く
        // ~~~~~
      }
      
タイトルとURLをコピーしました