そろそろTwitterBotの記事に一区切りしようと思っていた折、こんなコメントを頂きました。
画像を一緒にツイートする時はどの様にすれば良いでしようか?
確かにTwitterBotを運用する上で画像の投稿は必要不可欠ですね…!!(コメント助かります😭)
今回は画像をアップロードする機能を作ったので、紹介&解説をしたいと思います!
【関連記事】
■ 自分専用のTwitterBotを作り方を完全公開します【コピペOK】
全ての始まり
■ スプレッドシートの順番通りにツイートするTwitterBotの作り方
今回の記事のベースになっている「順番通り」の処理について解説しています
■ 【爆速】自作のTwitterBotを簡単に作るライブラリを作った話【初心者向け】
今回はこちらのライブラリを利用しています。詳しい使い方はこちら。
画像をアップロードするTwitterBotの作り方
細かいことは気にせずに画像を投稿するTwitterBotを作りたい方向けにライブラリを改造しましたのでご利用ください。
スプレッドシートを用意する
新しいスプレッドシートを用意して以下のシートの内容をコピーしてください
- A列 投稿内容
- B列 回数(0でOK)
- C~F列 一緒にアップロードしたい画像のGoogleドライブのURL
を入れてください。
投稿用の画像を用意する
GoogleドライブのURLは https://drive.google.com/drive/u/0/my-drive を入れがちですが、ファイルごとにちゃんとURLが存在します。
画像を開いたら右上のメニューから『新しいウィンドウで開く』を選択します。
表示されたページのURLが https://drive.google.com/file/d/****************/view の形式となっていると思うのでそのURLをスプレッドシートに貼り付けてください。
GASを用意する
ここからはいつものようにGASを用意してコードを書いていきます。
まずはGASを用意します。先程作ったスプレッドシートから『ツール』→『スクリプトエディタ』でGASを用意しましょう。
GASの編集ページが開かれたら以下の画像を参考にライブラリを登録していきます。
ライブラリのIDは以下をコピペしてください。
1fHCjI78BV3o7nGx2l0lJ7WXM49VFbobGDNdFGqAoVFZyRJ2kepQYzVLd
不具合の修正が含まれているのでver12以上をご利用ください。
下記コードをコピペする
コード.gsに以下のコードをコピペします。
cunsumerKeyとconsumerSecretは使用するTwitterアプリのものに上書きしてください。(初めての方はこちら)
これで完成です!(使い方は こちら を参考に postTweetWithMedia を実行するように設定してください)
次の章からは具体的にどのような仕組みで動いているかの解説を行います。
単純に仕組みが気になる人、少し改造したい人、怪しい処理が行われていないか不安な人はもう少しお付き合いください!
画像をアップロードするTwitterBotの仕組み
大まかな流れ
4つの処理を順番に実行しています。
- 画像の場所(URL)を取得する
- Googleドライブの画像を取得する
- Twitterに画像をアップロードする
- アップロードした画像を含めてツイートする
人が画像を投稿する順番を代わりにプログラムが行っているようなものなのでそこまで複雑ではありません。
① 画像の場所を取得する
スプレッドシートからdriveURLを取ってきます。
これまでの投稿の処理と同じようにテキストとしてURLを取得すればOKです。
Googleのファイルの場所は
https://drive.google.com/file/d/******/view
の******の部分だけでファイルを識別しています。
******をGoogleドライブのFileIdと言い、これが今回必要です。
FileIdを直接シートに書いてもらってもいいのですが、今回は使いやすさを重視してURLから抽出するようにしました。
Utility.gs のpickUpTweetInOrderに処理を書いているので参考にどうぞ。
② Googleドライブの画像を取得する
ここからは TwitterClient.gs の postTweetWithMedia の内部の処理の説明になります。
GoogleドライブのFileIdを取得したら、次に投稿する画像を取得します。
GASではGoogleのサービスと連携するためのAPIが用意されているのでそれを利用しましょう。
// ファイルのデータをドライブから取得 const fileByApp = DriveApp.getFileById(fileId)



上記のリンクに細かい使い方が解説されていますが、その中で『DriveApp』というクラスの『getFileById』を使ってファイルの情報を取ってきます。
新しい画像を作ってGoogleドライブに保存したり、Googleドライブ以外のGoogleのサービス(カレンダーやメールなど)と連携することも出来るので興味のある方はここから色んなものをアレンジして作ってみてください!
③ Twitterに画像をアップロードする
次にTwitterAPIを実行してファイルをアップロードします。
Twitterに画像をアップロードするAPIを実行することになります。
media か media_data をパラメータにセットしてアップロードするのですが、Googleドライブでは画像そのものを取得できなかったので(やり方がわからなかった…)、base64という形式の文字列のデータに変換して送ります。
// ファイルのデータをbase64形式に変換 const base64Data = Utilities.base64Encode(fileByApp.getBlob().getBytes()); // 画像アップロードのAPIを実行 const uploadUrl = 'https://upload.twitter.com/1.1/media/upload.json' const uploadParam = { media_data: base64Data // base64形式なので media_data にデータを入れる } // uploadResult にアップロードした画像の参照IDなどが入っている const uploadResult = this.postRequest(uploadUrl, uploadParam)
④ アップロードした画像を含めてツイートする
③でアップロードした際にuploadResultにアップロードされた画像の参照IDが含まれています。
ツイートのAPIを実行時にそのIDを入れると③でアップロードした画像を紐付けてツイートされます。
// アップロードしたファイルを添付して投稿 const postUrl = 'https://api.twitter.com/1.1/statuses/update.json' const postParam = { status: postData.message, // 画像と一緒に投稿する文章 media_ids: mediaIds // カンマ区切りで書く } const postResult = this.postRequest(postUrl, postParam)
これで画像を付けて投稿するTwitterBotの処理は完成です。
あとは時間の設定などを行えば自動で画像を投稿することも出来るようになります。
この方法を使えばTwitterで画像を予約投稿することも
某TwitterBotサービスでは画像をアップロードすることが出来ないようで、小技として一度画像をアップロードした際のリンクをBotで投稿することで画像つきツイートをしているようです。
確かに参照先が一致していれば画像は表示されますが、日付が変わる瞬間に情報を開示したい場合などにあらかじめ画像を投稿しておくのは難しいので実用性はイマイチです。
今回紹介した方法であれば処理の中で画像のアップロードを行うので、元のツイートを用意する必要はなく、事前に投稿内容がバレることはありません。
画像を知らない外部のサーバーに置かないのでセキュリティ的にも安心ですね!
Twitterに予約投稿機能は付いたのですが、1つ1つ設定する必要がなく、スプレッドシートなので簡単に大量に作れるので色々とメリットはこちらのほうが多そう(*´∀`)
めっちゃ良い!と思った方は是非参考に作ってみてください!
投げ銭・拡散頂けると喜びます\(^o^)/
ここまで読んでいただきありがとうございました!
コメント
TwitterBotの記事全て読みました!初心者にもとてもわかりやすくて感謝してます、ありがとうございます!
ただ、画像付きのツイートをしようとしたら、「ReferenceError: uploadTwitterForDriveMedia is not defined at postTweetWithMedia(TwitterClient:135:23)」とエラーが出て、ツイートができなくて困っております。
↓確認したこと、やってみたこと↓
・サンプルコードをそのままコピペして、APIキーを入れて使っている。認証は完了している
・ライブラリのバージョンは4
・シート1のA列2行目に投稿する内容、B列2行目に0、C列2行目に「https://drive.google.com/file/d/ほにゃらららら/view」のURLを書いている(ちゃんとかけてるはず…)
・「【爆速】自作のTwitterBotを簡単に作るライブラリを作った話【初心者向け】」に書かれていたコードで、文章のみのツイートをすることはできた
・一応、投稿する画像をリンクを知っていれば誰でも見れる共有設定にして、一応DriveAPIはonにした
・postTweetWithMediaを実行するたびに投稿回数の数字は+1されている
・スプレッドシートを新しく作り直してやってみたけど結果は同じだった
たすけてドラえも~ん(血涙)
きっと僕がどこかでなにかをやらかしているのですが、原因がちっともわからないので、もし何が原因がわかれば教えていただけると嬉しいです。長文失礼しましたm(_ _)m
すみませんんん!!!!ライブラリ側の不具合です!!
諸々調査して頂いて心苦しいです、、、
修正完了しました!!! 『5 画像投稿の not defined を修正』 というバージョンをリリースしたのでこちらをお使いください。
TwitterClient:xxx:xx というエラーが出たら99%私なのでコメントで『エラーが出てるぞ!!』とご指摘頂けるとありがたいです。。
「自分のやり方が間違っているかも」と思うこともあるかもしれませんが、このブログにおいては「迷わせる記事を書いた方も責任がある」覚悟で書いています
もっとわかりやすい記事を書けるきっかけになるのでどしどしコメントください!!
めっちゃ早い対応ありがとうございます!画像付きツイートできました!
GASについて調べてる間に色々な情報を知れたので、結果的には良かったと思ってますw
わかりました、また何かあったらコメントしますね(`・ω・´)ゞ
スプレッドシートから画像をTwitterに投稿したいと思い、こちらのページにたどり着きました。GASの私にも初心者にもとてもわかりやすくて感謝申し上げます。本当にありがとうございます!
ただ、画像付きのツイートをしようとしたら、「TypeError: Cannot read property ‘length’ of undefined(行 134、ファイル「TwitterClient」)」とエラーが出て、ツイートができなくて困っております。
↓確認したこと、やってみたこと↓
・サンプルコードをそのままコピペして、APIキーを入れて使っている。認証は完了している
・ライブラリのバージョンは『5 画像投稿の not defined を修正』
・「【爆速】自作のTwitterBotを簡単に作るライブラリを作った話【初心者向け】」に書かれていたコードで、文章のみのツイートをすることはできた
・一応、投稿する画像をリンクを知っていれば誰でも見れる共有設定にして、一応DriveAPIはonにした
・postTweetWithMediaを実行するたびに投稿回数の数字は+1されている
・スプレッドシートを新しく作り直してやってみたけど結果は同じでした。
お忙しいところ大変恐縮ではございますが、ご教授いただけますと幸いです。よろしくお願い申し上げます。
参考にしてくださりありがとうございます!
そして、ご迷惑おかけして申し訳ございません。。
今、確認をおこなっているのですが、再現しないため時間がかかっております。。
エラーの箇所をみたところ、スプレッドシートからdriveのURLを取得する部分で正しくデータを取れていないようです。。
原因は掴めていないのですが以下の事を試して頂きたいです
・バージョンを最新(2021/2/5時点だとver11)にして実行
・シートの形式をサンプルと比較
まだこれだけでは解決には繋がらないと思うのですが、エラーログに変化がある可能性があるのでよろしくお願い致します。
何か状況が変わりましたらコメントでもメールでもTwitterのDMでも大丈夫なのでご連絡ください!
早速ご返信誠にありがとうございます。
ご助言いただいた通り、『・バージョンを最新(2021/2/5時点だとver11)』で実行しました。
また、シートについてはサンプルと同じ形式にいたしました、
上記を実行したうえで『postTweetWithMedia』を実行したところ以下のエラーが出ました。
1回目
Exception: https://upload.twitter.com のリクエストに失敗しました(エラー: 401)。サーバー応答の一部: {“request”:”\/1.1\/media\/upload.json”,”error”:”Read-only application cannot POST.”}(応答の全文を見るには muteHttpExceptions オプションを使用してください)
at Service_.fetchInternal_(Service:457:22)
at Service_.fetch(Service:305:15)
2回目
TypeError: Cannot read property ‘split’ of undefined
at pickUpTweetDataInOrder(Utility:153:23)
at postTweetWithMedia(TwitterClient:139:22)
3回目
投稿内容を上手く取得できませんでした。以下のシートを参考にしてください。
エラー TypeError: Cannot read property ‘length’ of undefined
at postTweetWithMedia(TwitterClient:143:47)
1回目、2回目を実行した際にはスプレッドシート上の投稿回数は1ずつ追加されるのですが、3回目は追加されず。
3回目のエラー「TypeError: Cannot read property ‘length’ of undefined at postTweetWithMedia(TwitterClient:143:47)」がでて4回目以降は3回目のエラー「TypeError: Cannot read property ‘length’ of undefined at postTweetWithMedia(TwitterClient:143:47)」になります。
Consumer Keysを再発行してコードのほうも更新したのですがエラーの内容は変わらないです。
ご助言いただけますと幸いです。
お忙しいところ大変恐縮ではございますが、よろしくお願い申し上げます。
詳細にエラー内容をまとめて頂きありがとうございます!
おかげさまで原因を掴むことが出来ました。
【1回目のエラー】
『Read-only application cannot POST』ということでTwitterアプリのWrite権限が足りないようです。
おそらく試行錯誤の中で新しくアプリを作ったりした影響かと思うので、以前ツイートに成功したアプリに切り替えるか、権限を付与してみてください!
(なおKeyを再発行したり権限やアプリを切り替えた後はGASからreset&authrizeで再認証が必要です)
【2回目のエラー】
付与しようとしているGoogleDriveのURLが意図した形式ではないようです。。
投稿用の画像URLを作る方法をまとめているのでご確認ください!
【3回目のエラー】
私のコードに原因がありました。。
参考にして頂いたスプレッドシートの右側に『参考記事』の記述があると思うのですが、そこが投稿と間違えて読み込まれてエラーになっていました。
不具合を修正した『バージョン12』を公開しましたので、そちらで試していただければと思います!
動かないなどありましたらお手数ですがご連絡頂けると幸いです!よろしくお願い致します!
早速のご返信誠にありがとうございます。また、適切なご助言誠にありがとうございます。
ご助言いただいたように
『バージョン12』に変更し、Developer Portalの『App permissions』が『Read』になっていたので『Read and Write』にし、GASからreset&authrizeを実施した結果、無事にスプレッドシートからツイッターに投稿することができました。
本当にありがとうございました。
スプレッドシート上で指定した時間に投稿できるように工夫してみたいと考えています。
今後とも勉強させていただきます。
記事の更新、大変かと存じますが、応援しています。頑張ってください。
はじめまして。
初めてこちらを試したところお蔭様でなんとか成功し、
https://belltree.life/twitter-bot-order/
今度はこのページの方法で画像付き投稿をやってみたく、同じツイッターアカウントと同じApps Scriptの画面で、ライブラリとファイル(.gs)を、前のものを消して入れ替えたものの、実行すると以下のエラーが出ます。
ステートメントの前に ; がありません。
(匿名)@TwitterClient.gs:5
よろしければアドバイスをいただけると有り難いです。どうぞ宜しくお願い致します。
原因は V8ライブラリ がオフになっているからですね…
V8ライブラリを『オン』に戻すと動くようになりますのでお試しください!
ありがとうございました!色んな記事で、記事によっては「オフに」と書いてあった気がして、教えていただくまで分かりませんでした。お蔭様で動くようになりました!!嬉しいです。
実は自作方法を探してこちらへ辿り着いた理由が、今まであったツイッターbotサービスが終了したり動かなくなったりしていて、残ったツイッターbotサービスもいつ動かなくなったり終了したりするか心許ないと思ったためです。
Beltzさまの私見で充分なのですが、ここで作り方を教えていただいているツイッターbotと、一部でまだ残っているツイッターbotサービスを比べて、強いて言えばおそらくどちらが長く使えるであろうと推測されますか。あくまで参考までにお聞かせいただけると有り難いです。
この作り方のBotのほうが圧倒的に長く使えると思いますよ。
というのもサービスが終了するパターンは主に以下の2つがあるからです。
① 金銭的な問題があった時(運用しているサーバー費用が赤字になった等)
② 技術的な問題があった時(Twitterで提供しているAPIが対応しなくなった/規約違反で規制された等)
今まであったTwitterBotサービスはサーバーを立てる必要があるので、管理者がサーバー代を支払い続ける形になっていたのですが、
ここで紹介しているスプレッドシートの方法は一切お金が掛かっていないので、Googleが突然スプレッドシートを有料化しない限りはずっと使えます。
また②の規約違反に関しても、今みなさんに『自分でアプリを申請して』作ってもらっているので、ある意味公式から認められている状態です。
自己責任ではあるものの、正しく使っていれば半永久的に使えるのでそこも自作の良さですね。
唯一の懸念点はライブラリで使っているAPIが古くなって対応されなくなることですが、そこは他のサービスでも同じなので結果的にこの方法の方が長く使えるかなと思っています。
ちなみにAPIが対応しなくなりそうになっても、今のところは頑張って修正する気持ちでいるので安心してください!
最後に一点だけ。
この記事読んで作ってくれた人はもう利用者ではなく提供者なので、ライブラリが万が一動かなくなったとしても努力次第で自分で復旧することも出来ます。
ライブラリはちょっとしたお手伝いをするツールなだけで、右ききさんのアイディア次第でもっと長く使うことも、もっと便利なBotを作ることも出来るので色々楽しんでほしいと思います、
困ったことがあったらサポートも出来るのでお気軽にご相談ください〜