🍣

Python+Gemini APIを使って簡単なBlueskyのbotのようなものを作ってみた

2024/03/09に公開

はじめに

PythonとGoogleのGeminiのAPIを使ってチョー簡単なbotのようなものを作ってみたという話です
プログラミング初心者がプログラミング初心者に向けて記事を書いてみたという感じなので、そこはご了承いただければ
また、GeminiのAPIが無料で使えるのは2024年初頭までという記事を見ました。今現在は使えますが、おそらく夏までには有料になるのではないかと思います
その時はClaude3を使ってみようかな…

概要

今回作ったプログラムではGemini API(GCP的にはGenerative Language API??)を使ってGeminiに返信内容を考えてもらい、それをBlueskyに投稿するという流れになっています
APIを使うにあたって、以下の記事を大いに参考にさせていただきました。ありがとうございます

https://zenn.dev/peishim/articles/2e2e8408888f59

プログラムを作る

Blueskyに投稿できるようにしてみる

まずはBlueskyに投稿できるようにしてみます
Blueskyで使われているAT ProtocolのPython向けSDKがあるので、今回はそれを使って進めていきます
ということで、atprotoをpipを使ってインストール

pip install atproro

これで投稿のための準備は整いました

Blueskyに投稿するためにプログラムを組んでみます

from atproto import Client

def main():
    client = Client()
    # Blueskyにログインする
    client.login("Your ID or Email", "Your App Password")

    # Blueskyに「こんにちは」と投稿する
    client.send_post(text="こんにちは")


if __name__ == "__main__":
    main()

これを、コマンドラインから実行してみると自分のアカウントに「こんにちは」と投稿されるはずです
ただ、ここで atproto_client.exceptions.UnauthorizedError というエラーを返されることがあります
そういうときは、だいたい入力すべきパスワードが間違っています
ここでいうApp Passwordというのは、アカウントのパスワードではなく「アプリパスワード」になります
詳しくはほりべあさんの書いたこちらのページを読むと良いかと思います
https://docs.tokimeki.blue/ja/apppassword

Gemini APIを使ってみる

さて、次はGemini APIを使って文章を作成するプログラムを作っていきます
Geminiを使うにも便利なSDKが用意されているのでありがたく使います
コマンドラインにて

pip install google-generativeai

と実行して必要なSDKをインストールします

このSDKを使って、Gemini Proを呼び出し、テキストを送ってみます

import google.generativeai as genai

def main():
    # APIキーを使って認証する
    genai.configure(api_key="Your API Key")

    # Gemini Proのモデルを読み込む
    ai = genai.GenerativeModel("gemini-pro")
    # 新たなチャットを始める
    chat = ai.start_chat(history=[])
    # Geminiにメッセージを送る
    response = chat.send_message("調子はどうですか?")
    # 返ってきたレスポンスのテキストを出力する
    print(response.text)

if __name__ == "__main__":
    main()

これを実行してみると、以下のように表示されました

調子が良いです。ありがとうございます。

シンプルですね。Webで使える普通のGemini(中身はBardと一緒でしたっけ?)に聞いてみたら3行くらいの長文で返ってきたんですが

ちなみに500エラーが返ってくることが何度もありました
原因はよくわかってません…もう一度実行するとちゃんと返答が返ってくるので、向こうのサーバーの問題なのかなと思ったりはしています

2つのプログラムを繋げてみる

先程作ったBlueskyに投稿するプログラムと組み合わせて、ランダムな寿司のネタを投稿するプログラムを作ってみます

main.py
from atproto import Client
import google.generativeai as genai

def main():
    client = Client()
    client.login("Your ID or Email", "Your App Password")

    genai.configure(api_key="Your API Key")

    ai = genai.GenerativeModel("gemini-pro")
    chat = ai.start_chat(history=[])
    response = chat.send_message("ランダムな寿司ネタを1つだけ生成してください")
    
    client.send_post(text=response.text)

if __name__ == "__main__":
    main()

これを実行してみると、ランダムな寿司ネタがBlueskyに投稿されます
良いですね

でもbotというくらいですから、定期的に投稿してほしいものですよね
というわけで、scheduleというモジュールを使って1時間おきに投稿できるようにしてみましょう
まずはインストール

pip install schedule

そしてコードを書き換えていきます

main.py
from atproto import Client
import google.generativeai as genai
+ import schedule
+ from time import sleep

+ def post(chat: genai.generative_models.ChatSession, client: Client):
+    response = chat.send_message("ランダムな寿司ネタを1つだけ生成してください")
+
+    client.send_post(text=response.text)

def main():
    client = Client()
    client.login("Your ID or Email", "Your App Password")

    genai.configure(api_key="Your API Key")

    ai = genai.GenerativeModel("gemini-pro")
    chat = ai.start_chat(history=[])
-    response = chat.send_message("ランダムな寿司ネタを1つだけ生成してください")
-
-    client.send_post(text=response.text)

+    # 1時間おきに投稿するようにスケジュールに登録
+    schedule.every(1).hours.do(post, chat, client)
+
+    while True:
+        # 指定時間になっていたら登録されたスケジュールのジョブを実行
+        schedule.run_pending()
+        # 1秒待ってから繰り返す
+        sleep(1)

if __name__ == "__main__":
    main()

これで1時間おきに実行するプログラムができました
実際に走らせてみると、1時間毎に寿司ネタをつぶやいてくれていますね

BlueskyのFeed

さいごに

リプライが来たら返信するような実装も余裕があれば書きたいです
ちなみに一番好きな寿司ネタはいくらです

Discussion