定期的にリツイートを行うTwitterBotの作り方

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

Twitterの仕様変更により、elevated以上のトークンしかこちらのライブラリは使用できません。

Exception: Request failed for https://api.twitter.com returned code 403. Truncated server response: {“errors”:[{“message”:”You currently have Essential access which includes access to Twitter API v2 endpoints only.

というエラーが出た際は、
https://developer.twitter.com/en/portal/products/elevated
こちらより申請を行なってください

久しぶりにTwitterBotに対するご要望を頂きました。

「毎日、任意の時間(たとえば朝・昼・版の一日3回)に、最新10ツイートを自動でセルフリツイートする」といったことをしたい

任意のリスト(DMや外部連携)に貼り付けられたツイートをリツイートしたい

リツイート関連のTwitterBotの需要ってかなり高いんですね。。

以前、リツイートを行うTwitterBotを作ったのですが、こちらは指定した単語を含むツイートがあったらいいねやリツイートするものでした。

今回はご要望にあったリツイートに特化して

  • 特定のユーザーの最新ツイートを定期的にリツイートするTwitterBot
  • 指定したツイートを定期的にリツイートするTwitterBot

この2つの機能を簡単に導入できるようにライブラリを更新しました。

今回の記事では、その使い方、実装内容や注意点を解説していきます。

定期的にリツイートを行うTwitterBotの作り方

最初の基本的な準備は以下の記事を参考にしてください。

ざっくりとした流れとしては

  1. Googleスプレッドシートを用意する
  2. Google Apps Scriptを用意する
  3. TwitterClientライブラリを導入する
  4. コードをコピペする(今回もここをカスタマイズします)
  5. 認証を行う

となります。

1fHCjI78BV3o7nGx2l0lJ7WXM49VFbobGDNdFGqAoVFZyRJ2kepQYzVLd

こちらのIDのライブラリの最新のバージョンを更新してご利用ください。

特定のユーザーの最新ツイートを定期的にリツイートするTwitterBot

“セルフリツイート”という形で要望頂きましたが、自分自身を指してもらえばセルフリツイートになるので、特定のユーザーの最新ツイートを定期的にリツイートするBotの実装方法を紹介します。

スプレッドシートの準備

今回の場合すべてTwitter上のデータで完結するので白紙のスプレッドシートでOKです。

コード

ライブラリを作った話のコードの③の部分を上記コードに差し替えてください。

自身のツイートをリツイートしたい場合はaccountNameを自身に、誰かのツイートを追ってリツイートしたい場合はaccountNameをその人のアカウントにすれば取得できます。

自分のツイートだけをRTする場合はincludeRTはfalse、他の人のRTも含めてRTしちゃう場合はtrueにしてください。

リツイートする数を調整したい場合は、countを調整してください。

コメント欄に要望が多くあったので、特定の単語の除外やリプライも含めた取得が出来るように修正しました。

指定したツイートを定期的にリツイートするTwitterBot

リリースした後に定期的に特定のツイートを繰り返しリツイートしたいとか、そういう場合はこちらが参考にしてください。

スプレッドシートの準備

参考例を用意しました(参考にするほどでもない内容だけど…)

A列にツイートの詳細のURLを貼り付けていってください。

コード

こちらはシートから一覧を取得するだけですので比較的シンプルです。

シートのURLからツイートIDを取っていくのでそのままRTを行います。

コード例

最後に「全体としてこんな感じになるよ」という例を書きます。「なんかどうしても動かないんだけど」という時の参考にしてください。※consumerKey と consumerSecret は各自書き換えてください!

指定した時間に繰り返し実行するには?

コピペしただけでは定期実行はされません。GASにはタイマー機能があるのでそれで設定を行います。

以前使い方を図で解説しているので参考してください!(ポチポチするだけなので簡単なはず)

自動的に投稿するように設定を行う

解説&使用上の注意点

最後に今回の実装の内部実装を紹介します。

今回作成した関数は

  • pickupTweetsLatest
  • pickupAllTweetLink
  • retweet

です。

pickupTweetsLatest

pickupTweetsLatestでは指定したアカウントの最新のツイートを取得する機能ですが、一番実装方針を悩まされました。

最新のツイートの定義は人によって曖昧で、ユーザーの要望に合わせたカスタマイズ性が必要でした。

『最新の5件』を取得する場合、Twitterの最新のツイートを取得するAPIは図の黄色の範囲になります。

ただ、自分のツイートのみに限定したものが適切では?という考えや、別アカウントのツイートを含めて複数回RTする仕様が良いという声もあり、pickupTweetsLatest では図の赤と紫の範囲のツイートを選択式で選べるように実装しています。

またRTや@を含まない最新の5件を取得するとAPIでは黄色の範囲しか取得しません。

そのためAPIで多めに取得して適切に5件取得できるように実装しています。

その影響で10件取得したい場合でもAPIでは30件分取得している可能性もありえます。

極端に数が多い場合、APIで取得しきれないエラーが出たり、APIを叩きすぎてエラーになる可能性はあるので、常識の範囲内でご利用ください(ちなみに@やRTを含めた直近100件までは見てきます)

この辺に関しては結構力技で実装してしまっているので解説はしませんが、興味のある方はは GitHubTwitterClient – Google Apps Script でコードを公開していますので御覧ください。

pickupAllTweetLink

特に特筆する内容はないですが、今の実装ではシートに書いてある全てのツイートを一度にごっそりリツイートします。

例えば10個のツイートを順番にRTしていきたいという場合、今回は自分で考えてもらいたいかなと思ってます。

ヒントになる記事は既に書いているからです(似たような処理を何度も書きたくなかった)

↓の記事では投稿文を順番に取得して、ツイートを投稿しています。

投稿文ではなくリンクを取得して、IDを渡せば…?

こういう組み合わせから「プログラミング楽しい」と思ってくれると嬉しいなぁ(´・ω・`)

retweet

これも普通にリツイートの処理だけでは行っていないです。

通常のリツイートのAPIは既にリツイートされている場合はエラーを返す仕様になっています

ただリツイートを一度消して再度リツイートすると再度上位に上げることが出来るので、この機能を活かすべく、内部処理ではリツイートされているものが対象になっている場合は一度リツイートを削除した上で再度リツイートしています。

注意点ですが引数が配列なので自分でカスタマイズする場合はTweetIdをStringのまま送らないように!

まとめ

ライブラリのコードは GitHubTwitterClient – Google Apps Script で見ることが出来ます。

興味のある方は御覧ください(GitHub手動で更新してるので反映遅いかも)

また引き続き質問や要望承っています。

週末など時間が空いた時に作るので緊急性の高いものは厳しいですが、「今度この作り方の解説して」と言われれば多分作ります。やらなくても個人ブログなのでそこんとこは許してクレメンス(´・ω・`)

今後の予定ですが、

  • ブログでの解説がごちゃごちゃしてきているので綺麗にまとめて技術書化をすること
  • GASで各々で作ってもらう形式でなく、簡単に導入が出来るサービスを作ること

この2つを目標にしています。

へただなあベルツくんへたっぴさ……..!収益化のさせ方がへた….。」と言われないように少しずつ価値あるもの作っていきたいと思います(コメントで応援くださるとモチベーション上がります)

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

コメント

  1. 初めまして!すごく参考になりました!ありがとうございます!
    プログラミングしたことがないのですが、もし「複数のアカウントを指定してRTする」という操作をしたい場合、

    const accountName = ‘a’
    const accountName2 = ‘aa’

    という風に増やせば実行できますか?

  2. 2度送信になってるかもしれません(汗
    プログラミングが初めてのものです。

    このサイトを見て、「指定した複数のアカウントのツイートをRTする」という操作を実行したいのですが、
    ③のコードの

    const accountName = ‘a’
    const accountName = ‘aa’

    という風に増やして実行することであってますでしょうか?
    動くには動きましたが、バグがあるかどうか仕様が分からないので教えていただけると嬉しいです!

    また、現在の仕様の場合、ツイートの取得を定期的に時間をセットして確認するようになっていますが、
    これをツイートしたら即RTするという風に書き換えるにはどうしたらいいでしょうか?

    • 参考になってよかったです〜

      『特定のユーザーの最新ツイートを定期的にリツイートするTwitterBot』 を複数アカウントで対応する場合ですが、色々やり方はあります。

      takeさんの行ったような書き方でも動くには動きます
      constで同じ名前の変数を書いてしまうとエラーになるので別名にしなければいけないですが↓こんな感じになるかと思います。
      https://gist.github.com/belltreeSzk/33eb3bed5e0b045602fd5a582c6daeb0

      ただそのようにすると対象者が増えた時に大変なので、↓のように書くとスマートなのでお試しください!(accountNamesにカンマ区切りで追加するだけで動きます)
      https://gist.github.com/belltreeSzk/548c746b8749ee7ff8c9d7a1969b2930

      > ツイートしたら即RTするという風に書き換える
      これGASでは出来ないんですよね。。
      即RTをするにはTwitterのサーバーを24時間監視するプログラムを書く必要があるのですが、
      GASは長い時間プログラムを動かし続けられる機能がないので実行時間の間隔を短くしてカバーする方法しかないのです。。

  3. うわ・・・めちゃくちゃ簡単にできますね・・・笑
    すごく面白いです!!ありがとうございます!!

    あと、動かしてみて思ったのですが、すでにRTされているものも定期的にRTさせるとRT対象に含まれてしまいます。
    これを取り除く方法はあるのでしょうか?

    • あーーなるほど。。
      https://belltree.life/twitterbot-for-retweet/#toc11
      この記事の画像のようにRTされているものは弾いているつもりだったのですが、RTされた”元ツイート”がヒットしてしまっているようですね。。

      プログラムである以上は出来ます
      ただ少しコードを書く必要があるので難易度が少し上がってしまいます…(汗
      サンプル(というより答え)のコードを書いたのでこちら参考にしてみてください!
      https://gist.github.com/belltreeSzk/5eeebf1c844292c14de9c215eeca532b

  4. おおおおお!!!ありがとうございます!!!
    以前いただいたコードと組み合わせたら複数アカウントでも動きました!!ありがとうございます!!!

  5. コードを読んでなんとなく分かる程度の初学者です。こういう記事を探していました、ライブラリーをインポートするだけなんてめちゃくちゃありがたいです!本当に助かります……!

    RTの自動化につきまして、「リスト内の全ツイート(リプライやRTも含む)を一定件数遡り、それらを古いものから順にRTする(ただし、すでに自分が行ったRTは取り消さない)」という処理をさせたいのですが、下記の2点について教えてください。

    1) RT対象のユーザーを複数指定する際、Twitter IDを列挙する代わりに、リストのURLを用いて同様の結果を得る方法はありますか?

    2) 公開してくださっているretweet関数をそのまま実行すると過去のRTが取り消されるため、ライブラリーのコードを改変して使用させていただきたいのですが、改変後のものを新たなライブラリーとして保存するにはどうすればよいですか?

    お忙しいところ恐縮ですが、よろしくお願いいたします。

    • 色々参考にしていただいてありがとうございます!

      > 1) RT対象のユーザーを複数指定する際、Twitter IDを列挙する代わりに、リストのURLを用いて同様の結果を得る方法はありますか?
      あります。
      リストのURLからリストに登録されているメンバーを取得するAPIがあるのでそれを使ってみましょう!
      https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-members
      サンプルコードも作ったので参考にどうぞ!
      https://gist.github.com/belltreeSzk/8c86330b4e05bcb5324f263c3c895664
      ただ 1) の方法だと、メンバー間でツイートの頻度に偏りがあっても平等に指定した数のツイートを取得することになりますね。

      > 2) 改変後のものを新たなライブラリーとして保存するにはどうすればよいですか?
      その場合は別のライブラリとして作ってしまってもらったほうが簡単です(著作権的なものは個人利用の範疇なら気にしてないので大丈夫です)
      良い機会だったので、ライブラリを新しく公開する方法を記事にまとめてみたので、こちらご参考ください。
      ササッと書いたので、もしわかりづらい場合コメントください〜
      https://belltree.life/google-apps-script-library-publish/

  6. お返事が遅くなり申し訳ありません。
    参考だなんてとんでもない、勉強になってます……!
    サンプルコードまで書いてくださりありがとうございました、個人利用(商用でない)で使わせていただきます!

  7. 度々すみません。
    上のコードだと、取得したメンバー一人一人に対してfor文が回るため、例えばAさんとBさんの2人からなるリストに対して実行すると、自分のタイムラインが

    ↑新しい

    ・RTしました! 2021-03-21
    ・RT: Bさんのツイート「~~~」 2021-03-20
    ・RT: Bさんのツイート「~~~」 2020-01-01
    ・RT: Bさんのツイート「~~~」 2019-01-01
    ・RT: Aさんのツイート「~~~」 2021-03-19
    ・RT: Aさんのツイート「~~~」 2021-03-18
    ・RT: Aさんのツイート「~~~」 2015-01-01
    ・これからRTします! 2021-03-21

    ↓古い

    というふうになるかと思うのですが、これを時系列順にRTするにはどうすればよいでしょうか……?
    lists/statuses で得たツイート一覧を配列に格納すればいけると踏んでいるのですが、書き方が分かりません……。
    何卒よろしくお願いいたします。

    • TwitterのツイートのIDは新しいものほど数字が大きくなっていくので、for文の中でRTをせずにツイートのIDを一度1つの配列にまとめて、まとめたIDを並び替えると良い感じになります〜
      https://gist.github.com/belltreeSzk/ff2181873904d8f1050cbdb6f8634404

  8. あー、なるほど!
    分かりやすい説明、ありがとうございました……!

  9. 頂いたコードでなぜか取得漏れが発生したので、やはり lists/statuses を利用しようと思うのですが、

    const ListURL = ‘https://api.twitter.com/1.1/lists/statuses.json’;

    と書き換えてコードを実行後、 ListResult に返される長いデータから id_str のみ取り出すにはどうすればよいですか?

    頂いたコードは、 ListResult に返されるデータのうち、各メンバーの users という項目から screen_name だけ取り出しているのだろうと考えたのですが(間違っていたらすみません)、 lists/statuses から返されるデータを見ても id_str の親(?)項目がなく、どのように書き換えたらよいか分かりません。検索していく中で目にした JSON.parse() なども試してみましたが、うまくできずお手上げです。

    よろしければお手すきの際にでもご教示いただけますと幸いです。

    • 忙しくて返信できておりませんでした。。

      const listResult = client.getRequest(listURL, listParam);
      

      このように結果を取得しているのであれば、

      Logger.log(listResult[0].id_str);
      

      で id_str を取得できるかと思います。
      for を使って全部取りたい場合だと以下のような感じになります。

      for (let i = 0, il = listResult.length; i < il; i++) {
          Logger.log(listResult[i].id_str);
      }
      

      > 返されるデータを見ても id_str の親(?)項目がなく、
      これ、慣れてないとわからないですよね…
      JavaScriptのデータには "配列" と "連想配列(オブジェクト)" というものがあります。
      users などの親項目(正しくはkeyと呼びます)があれば、〇〇.users という形で取れるのですが、
      今回のような同じものが複数入っているデータだと配列というものになり 〇〇[数字] でデータを取ります。

      今回は配列形式の結果になるため listResult[0].id_str のように一度配列のデータを取り出して id_str を呼び出す書き方になります。

      データ自体は↓のページのレスポンスボディ (JSON) という所にわかりやすく書かれているのですが、
      https://syncer.jp/Web/API/Twitter/REST_API/GET/lists/statuses/

      [ ] で囲われている部分は配列で、 { } で囲われている部分は連想配列です。
      データが取れない!って時はちょっと思い出してみてもらえると解決するかもです〜

      回答になりましたかね?不明点があったらまたご連絡ください。

  10. なるほど……配列が入れ子になっているので、まず ListResult[0] で

    0: {
    ……
    }

    の部分を読み出し、次にその中の id_str というキーを指定するということですね……。

    VBAで少しだけ二次元配列を扱ったことがあるのですが、表のデータを扱うためのものだとばかり思っていたので、実は配列を入れ子にしたものなのだと分かって目から鱗が落ちた気分です。

    大変分かりやすい解説で助かりました。ありがとうございました。

  11. 最近この記事を見つけてボットを作らせていただきました!
    かなりサイトを読み込ませていただいてます。あなたは天才です!

    追加したい機能があるのですが、可能であればご教示いただけますでしょうか。
    出来るだけボットらしくないように、投稿時間はランダム、指定した時間外なら投稿しない、という動きをさせたいです。
    トリガーイベントで指定した時間にランダム化されたクラスを処理しようかなと思いますがいかがでしょうか。

    以下は30分に一度発動、25%の確率で0-29分後にツイートするようにするコードです。
    (確率的には2時間に1投稿)
    全然動かない処理なんですが、やりたいことが伝われば幸いです。動くようにしていただけますでしょうか。

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

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

    function validateHourRange(hour) {
    // 投稿したい時間を指定する
    if ((hour >= 9 || hour = 0){
    Logger.log(ramdomnum);
    var isupload = ‘upload’;
    return isupload;
    }else{
    return false;
    }
    }

    • コードの修正までしてしまうと、「サービスしすぎだろ!」ってなってしまうのであまりしたくないのですが、、
      シンプルに「120分の1の確率で投稿する」を1分毎に実行すれば確率的には2時間に1投稿のBotが出来そうだなあと思いました。
      頂いたコード見た感じ、それを書ける技術力はありそうなのでご検討ください!
      「それじゃダメなんだ」という理由があればまたご連絡ください〜

    • ご返事ありがとうございます!
      まあそうですよね笑

      正直コピペの集合体なので修正は出来ないのですが、出来ることがわかっただけでもOKです!
      勉強しておきます!

      あとこのコメントは良かったら消しちゃってください!
      同じような方がおられると質問面倒だと思うので…
      またいつか記事のネタ尽きたらご利用くださいませ
      陰ながら応援してます!
      ※返事不要です

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

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

    // さらにランダム性を持たせるため、25%の確率で投稿
    function logRandom(){
    var ramdomnum = Math.floor(Math.random()*4);
    Logger.log(ramdomnum);
    if(ramdomnum >= 0){
    Logger.log(ramdomnum);
    var isupload = ‘upload’;
    return isupload;
    }else{
    return false;
    }
    }

  13. はじめまして。貴サイト拝見しtwitter botを作ってみようと思い作成着手するも初心者なもので躓いております。。以下エラーが出る場合原因として何が考えられますか?認証リセット、apiキーシークレットキー再登録後再認証でretweetLatest実行するも以下エラーが出てしまいます。。お力添えの程何卒よろしくお願い申し上げます。

    Exception: https://api.twitter.com のリクエストに失敗しました(エラー: 403)。サーバー応答の一部: {“errors”:[{“message”:”You currently have Essential access which includes access to Twitter API v2 endpoints only. If you need access to this endpo…(応答の全文を見るには muteHttpExceptions オプションを使用してください)
    at Service_.fetchInternal_(Service:457:22)
    at Service_.fetch(Service:305:15)

    • エラーの内容を見ると、Essentialのトークンを使っているようなので、お手数ですが以下のページからelevatedの申請を行ってアップグレードして頂きたいです。
      https://developer.twitter.com/en/portal/products/elevated

      細かい説明は以下のページに書いています。
      https://blog.twitter.com/developer/ja_jp/topics/community/2021/build-whats-next-with-the-new-twitter-developer-platform

      また近々対応版をリリースする予定なので、緊急でなければお待ちいただければ幸いです!

      • お返事いただきありがとうございます。
        水曜日中にelevated申請を行い現在承認を待っているところです。
        承認されたら引き続きretweetLatest実行してみます。
        また何かありましたらご相談いたします。素早いご対応ありがとうございました!

  14. はじめまして。
    スプシに列挙したアカウントを取得して、繰り返しリツイートするコードを書きたいのですがプログラミング初心者のため、苦戦しております、、、
    お忙しいとは思いますが、サンプルコードをいただきたいと思っております。
    お手数ですが、よろしくお願いいたします。

    • すみません。見落としていました。。
      なにか作りたいものがあるときは、やることを細分化するのがコツです。

      ① スプレッドシートにアカウントを書き込む(ここは手動?)
      ② アカウントのどのツイートをRTするか決める ← ここがふわっとしてます。対象のツイートはどういうことをすると取れそうか考えてみましょう。
      ︙ 〜〜 ②で考えた選び方を出来るだけ細かく並べる 〜〜
      ③ ツイートに対してRTをする

      みたいな感じで最初に難しい技術は無視して言葉でやりたいことを並べていくとサポートしやすいです。

  15. 昨夜はお世話になりました。
    もうひとつ質問をさせていただきます。

    グループA[‘belltreeszk’, ‘belltreeszk2”, ‘belltreeszk3’]

    グループB[‘belltreeszk4’, ‘belltreeszk5”, ‘belltreeszk6’]

    グループC[‘belltreeszk7’, ‘belltreeszk8”, ‘belltreeszk9’]

    グループA=3or5or7

    上記のグループをランダムに選択し、グループAが選択された場合は3RT、5RT、7RTのどれかをランダムに選択する。

    グループB=4or6or8

    グループBが選択された場合は4、6、8を選択して、選択された回数分のRTをする。

    グループC=3

    グループCが選択された場合は3RT固定。

    上記のようなことはできますでしょうか?

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

    • プログラムは書いたように動くので動きを説明が出来る範囲であれば基本的に何でも作ることが出来ます。
      ただ今回のブログの内容からはズレてくるのでここは自力で頑張ってみてください。
      実装が難しい場合は仕様を変えるのも1つかもしれませんね!

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

    「リプライ」と「リツイート」を除外してRTしたいのですが、可能でしょうか?

    お力添えのほど、何卒よろしくお願い申し上げます。

    • 自分のタイムラインじゃなくて、他人のタイムラインを探した時に「リプライ」と「リツイート」を除外してRTしたいという要望ですかね?
      最新verの22で他人のタイムラインを検索する時に includeRT を false にすると「リプライ」「リツイート」を除外するようにしたので、お試しください!
      もし違ってたらまたご連絡ください。

  17. 素晴らしいコードをありがとうございます。快適に使わせていただいております。
    1つだけしたいことがあるのですが、

    メインアカウントAがツイートしたものをサブアカウントBでリツイートすることは問題ないのですが、メインアカAがリツイートした他人のツイートをサブアカBでリツイートしたくないのですが、どのようにすればよろしいでしょうか?

    includeRTはfalseなのですが、これでもリツイートしてしまいました。

    • 言われてみると不具合にも感じるのでライブラリのver22でincludeRTがfalseの時は『他人が行ったRTも取らない』ように修正しました。
      ライブラリのバージョンを最新にしてみて試してみていただけますか?

  18. コードを使用させていただいています。ありがとうございます。

    ひとつ質問です。

    URLを含むツイートを、リツイートしないようにすることは可能でしょうか?
    よろしくお願いいたします。

    • 可能ですよ。

      参考にリツイート済みのツイートをリツイートしないサンプルコードがあるのですが、
      このコードを参考にentities.urls.lengthが1以上のデータを除くと実現するかと思います。
      https://gist.github.com/belltreeSzk/5eeebf1c844292c14de9c215eeca532b

      頑張ってみてください!

      • 返信ありがとうございます。
        ちんぷんかんぷんですが、がんばってみます。

        • サービスってことで、そんなに工数掛からないので、先程のリンクを参考に作ってみました。
          コピペして実行すればURL含むツイートは除いてRTするはず。

          https://gist.github.com/belltreeSzk/9d001c91e226c3949b2f884b6b794205

          • できました。丁寧に対応していただき、ありがとうございました。

            感謝いたします。

  19. 素晴らしいコードをありがとうございます。快適に使わせていただいております。

    ひとつ質問があります。

    【特定の文言が含まれている場合はリツイートしない】ということはできますでしょうか?

    • できます。

      他の人と同様にサンプル書いてみました。
      forの中でツイートの内容をチェックしているので、その中で本文を判定することも出来ます。
      https://gist.github.com/belltreeSzk/cebfff2a05c6a74906b5f072661ed2bd

      ご参考まで!

      • コードを教えていただきありがとうございます。

        【bit.ly/abc1234】みたいなリンクがあるツイートをRTしないように、『bit.ly』を登録したのですが、リツイートしてしまいます。

        私のやり方がまちがっているのでしょうか?

        それともこの方法だと、『bit.ly』があるツイートだけを除外することはできないのでしょうか?

        • 調べてみたところ、ツイートに含まれているURLは自動的に『https://t.co/****』のようなTwitter独自の短縮URLに変換されるので単純な文言検索では除外できないようでした。
          出来なくはないのですがちょっと難しそうなので書いてみました。
          URLの情報がAPIの結果に含まれているので、そこから元のURLを取ってきて除外する処理になっています。参考にしてみてください!
          https://gist.github.com/belltreeSzk/e8854e7bcf5f0a39743fb571b00ffa21

          • コードを教えていただきありがとうございます。
            このコードだと、URLがあるツイートをすべて除外してしまうのですが、『https://t.co/****』のようなTwitter独自の短縮URLに変換されるので、『bit.ly』だけを除外するのは不可能ということでしょうか?

            たとえば、
            Amazonのリンク
            楽天市場のリンク
            『bit.ly』になっている、アプリダウンロードページのリンク
            .comや.netなどの個人ブログへのリンク(カード型リンクふくむ)

            Amazonや楽天市場のリンクをふくむツイートが9割で、残りの1割が『bit.ly』があるものと、ブログリンクつきのツイート。
            そのようなアカウントで、1割のほうの『bit.ly』やブログURLがあるツイートを除外し、残りの9割のツイートだけをリツイートしたい。
            ということです。

            当初は、『bit.ly』やブログURLの一部を除外キーワードにすれば実現できるかと思っていましたが、【Twitter独自の短縮URLに変換されるので単純な文言検索では除外できないようでした。】という返答をいただき、手詰まりになってしまいました。

            何度も質問して申しわけございませんが、解決策がありましたら教えていただきたいです。

          • 昨夜送ったコード試して頂けましたか?
            https://gist.github.com/belltreeSzk/e8854e7bcf5f0a39743fb571b00ffa21

            変換される”前”のURLを取ってきて除外するコードを書いたつもりでしたが、もしこのコードでも動かない場合は対象のアカウント教えて下さい
            (アフィリンクとbit.lyのリンクが混在したツイートをするアカウント探せなくて…)

  20. はじめまして、コードを使用させていただいています。

    コメント欄で解答している、URLを除外するコードについてです。
    リプライにURLが含まれている場合も除外されると思うのですが、それを「ツイートにURLがある場合だけ除外する」ということは可能ですか?

    お忙しいところ申しわけありませんが、教えていただければ幸いです。

    • リプライもリツイートしたいってことですかね…?
      リプライをリツイートすること自体需要がないと思っていたので、これまでわざとリツイート対象からリプライは除外していました。
      これまでの要望を受けて、より細かく対象を選べるTwitterClientの新しいバージョンを作ったのでお試し下さい。

      リプライを含めて、URLがある場合だけ除外する場合は includeReply: true, includeURL: false にすれば行けるはず。
      https://gist.github.com/belltreeSzk/c7832f436bab3b7483e867605a819010

      わからない場合や動かない場合はご連絡ください!

  21. 説明がわかりづらくて申しわけありません。


    ↓↓ツイート↓↓

    【「文章とURL」か「URL」】

    【動画】
    ↑↑ツイート終わり↑↑

    ↓↓リプライ↓↓

    【作品はこちらという文章】

    【FANZAやMGSの作品ページURL】

    ↑↑リプライ終わり↑↑


    ↓↓ツイート↓↓

    【「文章」】

    【動画】
    ↑↑ツイート終わり↑↑

    ↓↓リプライ↓↓

    【作品はこちらという文章】

    【FANZAやMGSの作品ページURL】

    ↑↑リプライ終わり↑↑

    URLを除外するコードを使用しますと、①と②のどちらも除外されてしまうと思いますが、①だけを除外したいです。

    つまり

    ツイートにURLがあるとき→リツイートしない。

    リプライにだけあるとき→リツイートする。

    よろしくお願いします。

    • んーー?なんとなく状況がわかってきたかも…?
      ・やりたいことはURLが含まれた『リプライツイート』をリツイートする
      ・ただし親ツイートにURLが入っている場合はリツイートしない
      ですかね?
      実際どんな感じになってるか知りたいんで、可能であればTwitterのDMで対象アカウント教えて下さい(エロ大丈夫です)

  22. 初めまして。
    プログラム等まったくしたことがないド素人ですが、
    どうしてもこの自動リツイートができるボットが作りたくて
    ベルツリさんのブログを拝見させて頂きました。
    コピペ・コンシューマーキー・認証までは出来ていると思います。

    それで実際に動かすにはどの関数を指定すればいいのかわかりません。

    トリガーで「authorize」を指定して実行するように設定
    すると時間通りに実行していてステータスも完了になってます。
    でもツイッターをみてもリツイートがされてません。

    「retweetLatest」で実行すると

    ReferenceError: accountName is not defined
    retweetLatest @ コード.gs:43

    と出てきます。

    定義云々といわれてもさっぱりわかりません。

    何もわかっていないド素人が質問すること自体ダメなのかもしれませんが
    もし許されるならどうやって実行するのか教えて欲しいです。

    ちなみに他のブログも含め何度も読ませてもらっています。
    それでもわかりませんでした。

    お時間があれば是非教えてください。
    よろしくお願いいたします。

    • すみません。
      改めて記事内のコード読んだ所、accountNameの定義の部分、抜けていました。。
      記事内のコード修正しましたので改めて参考にしてください!

      const accountName = 'belltreeszk' // 対象のアカウントの @~~~~ の部分を記入

      という記述を追加しています。

  23. 素晴らしい記事をありがとうございます。
    1つだけエラーで分からないことがあったため教えてください。
    retweetLatestのコードを実行すると

    TypeError: client.pickupTweetsLatest is not a function
    retweetLatest @コード.gs:45

    と表示されてしまいます。
    自分でも検索したりして調べたのですが原因までは分かりませんでした。
    該当箇所のコードは以下のようにしています。

    (文字数が多く送信できなかったため、分割してコメントさせていただきます。)

    • function retweetLatest () {
      // 最新のツイートのツイートIDを取得する(バージョン25以前)
      // const accountName = ‘〇〇’ // 対象のアカウントの @~~~~ の部分を記入
      // const includeRT = true // RTを含むか(他のユーザーのツイートのRTも再度RTします)
      // const retweetCount = 20 // 直近何件のツイートをRTするか
      // const tweetIds = client.pickupTweetsLatest(accountName, includeRT, retweetCount);

      • (バージョン26以降も同様にしてるのですが、なぜか送信できないため省略させていただきます)

        const tweetIds = client.pickupTweetsLatest(accountName, params);

        // 受け取ったツイートIDのツイートをすべてリツイートする
        client.retweet(tweetIds)
        }

        エラー表示に出ている45行目は
        const tweetIds = client.pickupTweetsLatest(accountName, params);
        の箇所になります。
        どこが間違っているのか教えていただけますでしょうか。

        • このコードだけを見ると問題なさそうです・・・

          この関数以外の箇所はブログの記事通りになっていますか?
          あまりないとは思うのですが client.pickupTweetsLatest が何らかの値で上書きされていたりすると同様のエラーが出るので、差し支えなければ一度コードを綺麗にした上でコピペし直して動くか確認してみていただけますか?

          • 返信ありがとうございます。
            TwitterアプリケーションをEssentialからElevatedにグレードアップできたので、API ver2から初期のコードに戻してやってみたところ、エラー無く実行することができました。

            そして最初の人のコメント返信にあった「すでにRTされたものは除外する」というコードも使わせてもらい、重複RTも避けられるようになりました。
            ですが別のエラー(?)が出てしまい、直近10件だけRTするようになってしまいました。

            「const retweetCount」を1にしても10RTしますし、30にしても10RTだけしかしません。
            こちらの重複除外コードを使う前の、昨日表記したコードの場合は「const retweetCount」通りに、1でも30でも適切にRTできたのですが・・・。

            こちらは何が間違っているかお分かりになるでしょうか。
            念のため該当部分のコードを返信欄に表記します。

          • すみません、コードを短く分割しても「不正なパラメータが送信されたためアクセスをブロックしました」と表示されるので、コードは記入できませんでした。

            内容としてはBeltz様の「https://gist.github.com/belltreeSzk/5eeebf1c844292c14de9c215eeca532b」こちらをそのままコピペさせてもらったので、特に間違いはないとは思うのですが・・。

            RT数が10で固定されてしまうことについて、何かやりがちなミスなどありますでしょうか?

          • スパム対策でURLが入っていると弾かれてしまうかもです。。
            差し支えなければ suzuki@belltree.life にコード送って頂いても大丈夫ですよ。

            ライブラリのバージョンはどうなってますか?
            最新は27なのですが、今古いバージョンになっていたりしませんか?

          • メールでご対応いただきありがとうございました。
            無事に実装することができました。
            わずかですがサポートさせていただきます。
            親切にご対応いただきありがとうございました。

          • 無事に動くようになってよかったです!
            サポートもありがとうございます!😭

  24. 自動で特定のアカウントのツイートをRTするTwitter botを作成したいと思っていたので、こちらのサイトの情報が本当に役に立ちました。
    改めて、心からお礼申し上げます。本当にありがとうございました!

    私はまだまだプログラムに関しては数ヶ月オンラインスクールで勉強した程度で分からない事だらけなのですが、管理人様のコードも読ませて頂きながら、自分なりに勉強させて頂きます。GASも勿論、TwitterのAPIでも色々な事が実現できるのですね♪

  25. コメント失礼します。既出でしたら申し訳ないのですがバージョン26以降のコードで複数人のアカウントをリツイートしたい場合はどのようなコードになりますでしょうか…?

  26. 初めまして。
    とても参考になる記事でした!
    1つ質問なのですがスプレッドシートに複数のツイートを記入してその内の何個かだけをランダムでリツイートするプログラムは作れるのでしょうか?
    可能であればそのようなプログラムを教えていただけるでしょうか?もしくは何かヒントをいただきたいです…

    • 「ツイートをランダムで選んで投稿する」というプログラムを過去に作ったのでこれを応用すれば行ける気がします。

      https://belltree.life/twitterbot-library/

      ↑の記事に
      > ランダムに投稿するBotを作りたい場合、pickUpRandomを用意しましたので、ランダム用参考例 を参考にシートを作り、
      > TwitterClient.pickUpTweetRandom(‘シート1’);
      > をご利用ください。

      とあるのですが、シートにツイート本文でなくツイートIDを書き、投稿でなくRTを行うようにすれば行けそうな気はします。
      コード的にはこんな感じです↓

      /**
       * ③ APIを実行する(この辺はアレンジしてください)
       */
      function randomRetweet () {
        let tweetId = TwitterClient.pickUpTweetRandom('シート1'); // 投稿文でなくtweetIdとして変数に入れる
        client.retweet([tweetId]); // 引数が配列なので [ ] で括っておく
      }
      
      • 返信ありがとうございます!!
        無事ランダムにリツイートさせることができました!
        最初はエラーが出て苦戦しましたがツイートIDはURL形式ではなく数字のみにすることにより無事動作しました!!

  27. はじめまして。

    https://www.google.com/amp/s/belltree.life/twitterbot-for-retweet/%3famp=1

    上記の記事のコメント欄にある、

    https://gist.github.com/belltreeSzk/a07b831c414355b647a113262d1f55ed

    上記のコードを使用させていただいています。

    どうしてもわからないことがありましたので、質問させていだきます。

    動画があるツイートのみをリツイートしたいです。

    つまり、動画がないものを除外したいのですが、コードの途中に【動画あり、動画なし】のような項目があると思いますが、どのように設定すれば、動画なしのツイートを除外できますでしょうか?

    お忙しいところ申しわけございませんが、教えていただければ幸いです。
    よろしくお願い申し上げます。

    • 頂いたコードを参考に、動画を除く処理を書くようにすると以下のようになります。
      https://gist.github.com/belltreeSzk/e107c6640b76d969cda5d51c9e82ebfa

      (そもそも元のコードが少し間違っていて画像でも”動画あり”と書かれてしまっていたので修正しました)

      tweetShowResult という変数にツイートのデータが入ってくるので、そこから添付ファイルのデータを探してチェックしています。
      ご参考まで👏

  28. はじめまして。GAS初心者のへびといいます。

    いつも”TwitterClient”のライブラリを利用させていただているのですが、複数アカウントで自動リツイートをしたいと考えています。(1つのアカウントで自動リツイートはできています)

    https://belltree.life/multi-account-twitter-bot/

    上記のサイトを見てコードを変えてみたのですが認証がうまくできなくて、サイトだと”TwitterWebService”のライブラリでやっているのでそこが違うからなのかと思っています。

    “TwitterClient”のライブラリを使って複数アカウントで自動リツイートするときのコードが知りたいです。(おそらく最初の認証用インスタンスのコードを変えるだけ?

    よろしくお願いします。

    • 回答遅れてしまいすみません。
      一番簡単な方法はアカウント毎にシートを作ってそれぞれでアカウントの認証をするのが楽ですかね…
      もしそれだと都合が良くない場合はご連絡ください!

  29. ありがとうございます!参考にさせていただきました!

    elevatedはなくなりProとなったので、Proを使用するための料金を払わないとこの内容は使用できなくなってしまったのでしょうか、、?

タイトルとURLをコピーしました