
【コード編集不要】ChatGPTを使用したTwitter(X)ボットで最新情報を自動ツイート【TwitterBotforGpt1.7】
はじめに
近年、AI技術の進化により、自然言語処理がますます人間のような対話を実現できるようになっています。その中でも、OpenAIのChatGPTは、様々な会話を行うことができるAIとして注目を集めています。今回は、コードの編集なしで設置可能なTwitterボットを作成しましたので、その機能と設置手順ご紹介をさせていただきます。Google Cloud PlatformのCloud Runでアプリケーションを設置しようと思っている方も参考になるかと思います。
以下の記事リンクは、現在の最新バージョンになります。
これ以降に記載されているのは古いバージョンになります。
注意事項
コード編集不要とはいえ設置手順は非常に複雑なので手に負えないと思ったら諦めたほうが無難です。
掲載されている手順は2024年1月13日に確認したものです。
このボットは、OpenAI APIを利用しているため、事前にAPIキーが必要です。APIキーは、OpenAIのウェブサイトから取得できます。
このボットはTwitterのAPIを使用しているため、事前にAPIキーが必要です。APIキーは、Twitter Developerのウェブサイトから取得できます。
このボットはGoogle Cloud Platformを使用しているため事前にGoogleアカウントが必要です。
このボットの設置にはGithubを使用しているためGithubアカウントが必要です。Githubアカウントの作成手順については手順の中で解説しています。
OpenAI APIとGoogle Cloud Platformの利用料が発生します。料金については記事内で説明しています。
主な機能
最近、Twitterボットの有料化というニュースが一部で話題となりました。しかし、APIを使用してツイートを行うだけであれば、一定の範囲内では無料で利用可能です。私自身、運用コストを抑えることを重視していますので、今回はChatGPTを活用して最新のニュース情報をツイートする機能のみを実装することを目指しました。
ツイート機能
指定したページやGoogle検索の結果を元にツイートします。
指定したページを元にURLを含んだ形でつぶやけるかどうかはページの構造によります。
Google検索のデータベースは更新が遅めなので、検索を指示するより特定のページを指定してリンクのリストを取得する方が早く情報が入手できます。
技術的な話になりますが各機能の呼び出し処理は6月にリリースされたfunction calling機能を元に実現しています。
画像生成機能
画像作成を指示すると、指示に基づいた画像を生成し画像をツイートします。


スケジュール機能
このスクリプトの機能というよりはGoogle Cloud Platformの機能になりますが、決まった時間にツイートします。
UNIX-CORN形式での指定が可能です。

WEB設定機能・ランダム命令機能
スクリプトを編集せずにWeb画面でツイートを命令を設定します。
命令は「,」区切りとすることで複数の命令が設定可能で、実行のタイミングでランダムに選択されます。

URL学習機能
一度読み込んだページは7日間データベースに記録されURLリストの結果に表示されなくなります。
この機能により同一のページを再度読み出してしまうのを防いでいます。
URLリストを使わずに直接URLを指定した場合はデータベースに記録されていても読み出し可能です。
利用用途
以下のような用途に利用できます。
最新ニュースの配信
ニュースサイトを参照先として使用することで自分のTwitterアカウントで特定ジャンルのニュースが配信できます。
ブログ更新を配信
参照先を特定のWEBサイトにしておき実行間隔をブログの更新頻度と合わせておくことで対象ページの情報を定期的に配信できます。
動的サイトを配信
参照先を例えば天気予報のWEBサイトにしておき実行間隔をWEBサイトの更新頻度と合わせておくことで対象ページの情報を定期的に配信できます。
利用料金
本システムを運用するための料金ですが、コード自体は無料です。利用するAPIやインフラが利用規模に応じて従量制の有料となります。
ChatGPTの利用料以外は基本的に無料で利用できます。
2023年6月現在の料金は以下のようになっています。
OpenAI ChatGPT API
本コードでのチャットエンジンはgpt-4が標準です。本当はgpt-3.5-turboの方が安いのですが出力で良い結果が得られませんでした。
1トークンは日本語で約一文字で概算してください。
一回のツイートで最低でも3500から4000トークンぐらいは消費します。
ツイートのし過ぎにご注意ください。
Links取得とWebページ読み込み等、複数機能を同時稼働させると使用トークンが倍の倍に増えていきます。安く抑えるコツはリンクページだけ取得してリンクの文字列だけでツイートさせるとか、読ませたいページを直接読ませてツイートさせる方法です。
入力:0.03ドル/1000トークン
出力:0.06ドル/1000トークン
その他の料金はここを参照
OpenAI Dall-E 3 API
画像生成する際に使用するAPIです。画像サイズにより料金が異なります。
サイズによって大して料金は変わらないので、本ボットは最大サイズである1024×1024を指定しています。
0.040 ドル/ image
その他の料金はChatGPT APIと同じここを参照
Google Cloud Build
ソースコードを実行できるようにビルドする際に最低スペックのサーバーでビルドする基準の料金です。
無料枠に収まると思うのでほぼ気にする必要はないです。
$0.003/ビルド分。1 日あたり最初の 120 ビルド分は無料
その他の料金はここを参照
Google Cloud Run
ソースコードを実行するサーバーの利用料金です。
小規模利用であれば無料枠で運用できるかと思います。
CPU:毎月最初の 180,000 vCPU 秒は無料
メモリ:毎月最初の 360,000 GiB 秒は無料
リクエスト:毎月 200 万リクエストは無料
その他の料金はここを参照
FireStore
会話ログを保存するためのデータベースです。
小規模利用であれば無料枠で運用できるかと思います。
ドキュメントの読み取り:50,000回/日まで無料
ドキュメントの書き込み:20,000回/日まで無料
ドキュメントの削除:20,000回/日まで無料
保存データ:1GBまで無料
その他の料金はここを参照
Custom Search
Web検索を行うためのAPIです。
小規模利用であれば無料枠で運用できるかと思います。
100回/日までは無料
その他の料金はここを参照
Artifact Registry
デプロイ時に利用される領域です。デプロイ履歴を放置しておくと蓄積されます。
通常は意識する必要はありませんが当プログラムはSeleniumというプログラムを利用しているのでデプロイサイズが大きめで0.5GB程度あります。
0.5GBを超えると1GB毎に$0.10/月が加算されるので注意が必要です。
少量だと問題ない程度の料金ですがため込むと高額請求されますので注意してください。
その他の料金はここを参照
Twitter
1500ツイート/月まで無料
そんなにツイートしてないつもりでも、制限がかかります。一日50ツイートの制限があるかもしれません。
その他の料金はここを参照
設定
以下に設定手順を記載します。
GitHubの設定
まずはGithubという場所にソースコードをコピーするためにアカウントを作成するところから始めます。
🔗GitHub Japan | GitHubにアクセスし「GitHubに登録する」を押します。

登録情報を入力し「Crate accont」を押します。

メールにコードをが届くのでそれを入力します。

GitHubのURLコピー
筆者が作成したソースコードをあなたのGithubのアカウントにコピーします。
🔗Githubの筆者のソースコードが置いてあるページにアクセスします。
右上の「fork」から「Create a new fork」を選びます。

「Create fork」を押します。

以上でコードが自分のGithubアカウントにコピーされました。
Google Cloud Platformのプロジェクト作成
Googleが提供するサーバー上でスクリプトを実行するための作業を行っていきます。
Googleアカウントを作成済みでGoogle Cloud Platformの🔗コンソール画面にログインできることを前提とします。
右上のGoogle Cloudの文字の右側を選択します。

新しいプロジェクトを選択します。

自分が分かりやすいと思うプロジェクト名を「プロジェクト名」に入力して「作成」を選択します。

少し経つと画面右上に以下のような表示が行われるので「プロジェクトを選択」を選択します。

左上の表示が設定したプロジェクト名に変更されていることを確認します。

Cloud Runの設定
次に実行環境の設定を行います。
画面中央上側の検索ボックスに「cloud run」と入力し「Cloud Run」を選択します。

「サービスの作成」を選択します。

「ソースリポジトリから新しいリビジョンを断続的にデプロイする」を選択し「CLOUD BUILD」を押します。

リポジトリプロバイダに「GitHub」を選択します。

「Username or email address」には自分のGitHubアカウント、「Password」にはGitHubのパスワードを入力し「Sign in」を押します。

リポジトリから「TwitterBotForGPT」を選択し、チェックをつけたら「接続」を押します。

「Dockerfile」を選択して「保存」を押します。

リージョンに「asia-northeast1(東京)」を選択、認証で「未承認の呼び出しを許可」を選択して「作成」を押します。

エラーが表示されますがそのまま待ちます。

状況が改善されない場合上部の「断続的デプロイを編集します」を選択します。CLOUD BUILDERの設定と同じ設定画面が出るので設定をやり直します。

デプロイが一向に進まない場合はCloud Buildの管理画面を確認します。

画面中央上側の検索ボックスに「cloud build」と入力し「Cloud Build」を選択してCloud Buildの管理画面を呼び出します。

画面左側にマウスカーソルをあてるとメニューが表示されるので「トリガー」を選択します。

「リージョン」で「グローバル(非リージョン)」を選択し一覧に項目があった場合「実行」を押します。一覧に何もない場合はCloud runの管理画面から「断続的デプロイを編集します」をやり直してください。

「トリガーの実行」を押します。
エラーメッセージが表示され、トリガーが実行できない場合はエラーメッセージの指示に従ってください。

画面中央上側の検索ボックスに「cloud run」と入力し「Cloud Run」を選択しCloudRun画面を呼び出します。

「twitterbotforgpt」を押します。

画面が以下の状態になっていることを確認します。なっていない場合はまだデプロイ中です。

FireStoreAPIの設定
設定を保管しておくためにデータベースとして利用するFireStoreを設定していきます。
画面中央上部の検索に「firestore api」を入力し「firestore api」を選択します。

「有効にする」を選択します。
※ボタンが「管理」になっている場合は何もしなくてよいです。

画面中央上部の検索に「firestore」を入力し「Firestore」を選択します。

「データベースを作成」を押します。

「続行」を押します。

ロケーションタイプを「リージョン」に、「リージョン」を「asia-northeast1(Tokyo)」にいして「データベースを作成」を押します。

この画面に飛ばされたらデータベースの作成は完了です。

Google Cloud PlatformのAPIキー作成
一部のサービスと接続を行うのに必要になるAPIキーを作成していきます。
上部の検索ボックスに「認証情報」と入力し「認証情報(APIとサービス)」を選択します。

「認証情報を作成」を選択し「APIキー」を選択します。

APIキーの右側のアイコンをクリックしAPIキーをクリップボードにコピーします。「GOOGLE_API_KEY」に設定する情報となります。メモ帳などに貼り付けて一時保存しておきます。保存が終わったら「閉じる」を選択します。

Custom Search APIの設定
Web検索に必要な機能を設定します。
Google Cloud Platformの上の検索ボックスに「custom search」と入力して「Custom Search API」を選択します。

「有効にする」を押します。

Googleの🔗「プログラム可能な検索エンジン」のページに移動し「追加」を押します。

自分の任意の名前を「検索エンジンの名前を入力してください」に入れ「ウェブ全体を検索」「私はロボットではありません」を選択した後に「作成」を押します。

「カスタマイズ」を選択します。

検索エンジンIDの右のアイコンを押しクリップボードに検索エンジンIDをコピーします。「GOOGLE_CSE_ID」に設定する情報となります。コピーしたIDはメモ帳などに保管しておきます。

Twitter APIの設定
TwitterAPIの設定を行いAPIキーを入手します。
Twitter Developerのアカウントは作成済みであることを前提とします。
作成方法は他の方の記事もありますので参考にしてください。
Twitter Developerの管理画面で下の図の①の部分を選択し②の「Set up」を押します。

App permisssionsを「Read and write 」を選択しType of Appを「Web app, Automated App or Bot」を選択します。
App InfoのCallback URI / Redirect URL」にはCloud run設定時に表示されるURLを入力します。
Website URLはあなたの持っているWebサイトを設定します。筆者はNOTEのプロフィールURLを設定しています。

「Save」を選択し設定を保存します。

「Yes」を押します

「Done」を押します。

「Yes, I saved it」を押します。

画面上部の「Keys and tokens」を選択します。

以下の画面の「API Key and Secret」の「Regenerate」及び「Access Token and Secret」の「Regenerate」を押して画面に表示される「API Key」「 Secret」「Access Token」「Access Token Secret」の4つのキーをメモします。

環境変数の設定
🔗Cloud Runの管理画面から対象のサービスを選択します。

上部から「新しいリビジョンの編集とデプロイ」を選択します。

メモリを「512MB」から「1GB」に変更します。内部処理でSeleniumというアプリを使っているため512MBでは動作しません。

「変数とシークレット」を押します。

環境変数の「変数を追加」を押して「OPENAI_APIKEY」「ACCESS_TOKEN」「SECRET_KEY」「ADMIN_PASSWORD」「GOOGLE_API_KEY」「GOOGLE_CSE_ID」の6項目を追加します。

変数名の前後に空白文字が入らないように注意してください。
API_KEY: TwitterのAPIキーを入力してください。
API_KEY_SECRET: TwitterのAPIキーシークレットを入力してください。
ACCESS_TOKEN:Twitterのアクセストークンを入力してください。
ACCESS_TOKEN_SECRET:Twitterのアクセストークンシークレットを入力してください。
OPENAI_API_KEY: OpenAIのAPIキーを入力してください。
GOOGLE_API_KEY:Google Cloud Pratformに発行したAPIキーを入力してください。
GOOGLE_CSE_ID:Google Cloud PratformのCustom Search設定時に発行した検索エンジンIDを設定してください。
ADMIN_PASSWORD:WEBの管理画面のログインに使用する管理者パスワードです。このシステムはインターネットから誰でも触れるので、必ず複雑なパスワードを設定してください。

一番下の「デプロイ」を押します。

アイコンがすべて緑になるまで待ちます。

Cloud Schedulerの設定
ツイートのスケジュール実行に必要な機能を設定します。
Google Cloud Platformの上の検索ボックスに「cloud scheduler」と入力して「Cloud Scheduler」を選択します。

上部メニューの「ジョブを作成」を選択します。

以下の項目を設定します。
名前
任意の名前を設定します。
リージョン
「asia-northeast1(東京)」を選択します。
頻度
UNIX-CORN形式でツイートを実行する時間を設定します。
以下は設定例です。
9時12時15時18時の平日だけ四回実行:0 9,12,15,18 * * 1-5
9時12時15時18時の四回で実行:0 9,12,15,18 * * *
毎時実行:0 * * * *
タイムゾーン
「日本標準時(JST)」を選択します。
「続行」を押します。

以下の項目を設定します。
ターゲットタイプ
HTTPを選択します。
URL
CloudRunでメモしたURLに「/tweet」を付与して設定します。
HTTPメソッド
「GET」を選択します。
「作成」を押します。

運用上の操作
本スクリプト利用にあたってのいくつか必要な操作を説明しておきます。
Botの設定変更
ブラウザのURL欄にメモしたURLの後に「/login」を追加して入力します。以下の画面が表示されるので環境変数に入れた管理者パスワードを入力して「submit」を押します。

以下は設定画面にある主な設定項目です。
ORDER
Twitterへツイートさせるための命令(プロンプト)を記載します。
デフォルトで設定されてるプロンプトを参考に変更してください。
{nowDateStr}の部分には実行日の日付が挿入されます。
インターネットから情報を取得する方法として「Web検索」「URLからリンク読み込み」「URLからページを読み込み」「画像の生成」の4つの命令が実行できます。
標準設定では画像は生成されないようになっています。試しに画像生成してみたい方は標準設定の一番下の「画像を生成しないでください。」を「-参照元のニュース内容に合うイメージ画像を生成してください。」に変更してみてください。
機能を使えば使うほどトークンを消費します。
AI_MODEL
利用するOpenAIのAIモデルを指定します。
標準では筆者が推奨しているモデルである「gpt-4-0613」が指定されています。あくまでもその当時の推奨であり変更していただいて構いません。
function calling機能を持ったモデルでしか動作しません。
REGENERATE_ORDER
GPTで生成された文字が半角で280文字をオーバーしてしまった場合に実行される命令文です。
変更する必要はありません。
REGENERATE_COUNT
再生成するため回数を指定します。標準では5回まで再試行します。
オーバーしないためにはプロンプトの指示が重要になります。
URL_LINKS_FILTER
ページ上部にあるページ内の余計なリンクをフィルタするキーワードです。
Cloud runのログを確認してみて不要なリンクが多数混ざっていたときに指定します。

一番下の「save」を押すことで設定が保存されます。以上で設定は完了です。
READ_TEXT_COUNT
ページを読み込む際の文字数を指定します。読み込むコンテンツに応じて文字数を調整してください。
READ_LINKS_COUNT
URL一覧を読み込む際の文字数を指定します。読み込むコンテンツに応じて文字数を調整してください。
PAINTING
画像生成の有効化(True)または無効化(False)を指定します。標準では無効化(False)です。
URL_FILTER
一回ツイートしたURLを次回ツイート時に含めるかどうかの有効化(True)または無効化(False)を指定します。標準では有効化(True)です。項目名がURL_LINKS_FILTERとかぶっててすいません。
手動実行
ツイートを手動実行するには🔗Cloud Schedulerの管理画面の操作の項目から「強制実行」を行うことでツイートが行えます。

ログの確認
ツイートの生成状況の確認は🔗Cloudrunの管理画面のサービス内にある「ログ」タブ内で確認できます。

最新版へアップデート
ソースコードは不具合が出たタイミングで見直しています。
Twitterやこのページで告知します。更新する際は以下のページを参考に更新をお願いします。
Githubへマージを行うと自動でGoogle Cloud Platformのデプロイが実行されます。デプロイをグローバルリージョンに変更していても自動実行されます。実行状態はCloud Buildの履歴画面から確認してください。
バージョンアップ後に管理画面からSAVEを忘れないでください。それでも動かない場合は設定値をいったんデフォルトに戻してください。
トラブルシューティング
ツイートがされない
ログに「An Tweep error occurred:429 Too Many Requests」が出力されていたらツイートしすぎです。有料アカウントに変更するかしばらくたってから再度実施してください。

URLを指定した先の情報がツイートされない
まずはログを見てフィルターワードの設定を見直してください。
ページの構造によってはうまく取得できません。
たいして使っていないのに利用料金でOpenAI以外にGoogle Cloud Platformでも料金がかさむ
本プログラムは基本的に利用料金はOpenAIの利用量しかかかりませんがSeleniumというプログラムを組み込んでいる関係上デプロイサイズが大きいためデプロイ履歴を残していると料金がかさんでしまう事がありますので注意してください。料金の詳細について料金の章を参考にしてください。
Google Cloud Platformの検索ボックスで「Artifact Registry」を検索して最新のデプロイファイル以外を削除してください。

まとめ
新しいタイプのLINEボットに行き詰まっていたので息抜きにTwitterボットを作ってみました。
ツイートするだけの単純構造なので処理を複雑に考える必要もなくリラックスした気持ちで開発を終えられました。
これからもアイデアを形にしていきます。その時はまたお付き合いください。