connpassの特定グループから任意の名前(ここでは「読書会」)のイベントを取得し、Gemini APIで生成した一言紹介文を添えてDiscordチャンネルに投稿します。
私たちのDiscordサーバーでは、「もくもく読書会」という、ゆるめの読書会を定期開催しています。今回は、その運営をサポートするために作ったDiscord Botの機能の一部をご紹介します。
参考:
connpassとは
connpassは、エンジニア同士をつなぐIT勉強会支援プラットフォームです。
「グループ」という単位でイベントを開催することができ、例えば以下のようなグループがあります。
今回は、この「技術チャレンジ部(challenge-club)」が主催するイベント情報を取得し、開催前にリマインドするBotを作成します。利用するのは challenge-club
というサブドメインです。
API キーの準備
connpass API v2 は X-API-Key
ヘッダで認証します。
取得方法は公式サポートに問い合わせ(2025年8月時点)です。
私の場合は、問い合わせから1週間以内にメールで返信があり、APIキーが発行されました。
必要な環境変数
.env
ファイルに以下の値を設定してください。
DISCORD_BOT_TOKEN=DiscordBotのトークン
DISCORD_CHANNEL_ID_REMIND=投稿先チャンネルのID
CONNPASS_API_KEY=connpass APIキー
GEMINI_API_KEY=Google Gemini APIキー # Geminiを使う場合
ローカル実行時は .env
に保存します(.env
は .gitignore
に追記)。
※ Lambdaで実行する場合は、Lambdaの環境変数にも同名で登録します。
CONNPASS_API_KEY=xxxxxxxxxxxxxxxxx
イベント取得
connpass v2 APIを利用して、特定期間内の「読書会」イベントを取得します。
def fetch_reading_events(days=7, debug=False):
url = "https://connpass.com/api/v2/events/?subdomain=challenge-club&count=50&order=2"
headers = {
"X-API-Key": CONNPASS_API_KEY,
"User-Agent": "dokusyo-kun-bot/0.1"
}
response = requests.get(url, headers=headers)
data = response.json()
today = datetime.now(pytz.timezone("Asia/Tokyo")).date()
limit_date = today + timedelta(days=days)
events = []
for ev in data.get("events", []):
if "読書会" in ev.get("title", ""):
start_time = parser.isoparse(ev["started_at"])
start_date = start_time.date()
if today <= start_date <= limit_date:
events.append(ev)
return events
-
subdomain=challenge-club
で技術チャレンジ部のイベントに絞り込み - タイトルに「読書会」を含むイベントのみ抽出
- 取得範囲は
days
引数で指定(デフォルト7日以内)
一言紹介文の生成(Gemini API)
取得したイベントの内容から、Gemini APIを使って一言紹介文を生成します。
def generate_summary(event):
title = event.get("title", "")
description = event.get("description", "")
started_at = event.get("started_at", "")
prompt = f"""
以下はイベントのタイトルと説明です。
- タイトル: {title}
- 説明: {description}
- 日時: {started_at}(JST)
このイベントについて、参加を促すような「やわらかく親しみやすい一言紹介文」を日本語で1つ作ってください(100文字以内、敬体)。
"""
model = genai.GenerativeModel(model_name="models/gemini-1.5-flash")
response = model.generate_content(prompt)
return response.text.strip()
Discordへの投稿
Discord.pyを使用して、指定チャンネルにイベント情報を投稿します。
async def post_to_discord(event):
client = discord.Client(intents=discord.Intents.default())
@client.event
async def on_ready():
channel = client.get_channel(CHANNEL_ID)
if channel:
summary = generate_summary(event)
msg = f"""{summary}
{event['url']}"""
await channel.send(msg)
await client.close()
await client.start(DISCORD_TOKEN)
ローカルテスト実行
以下のように実行して、1週間以内の「読書会」イベントを取得し、Discordに投稿できます。
def main():
events = fetch_reading_events(days=7, debug=True)
if events:
asyncio.run(post_to_discord(events[0]))
else:
print("該当するイベントは見つかりませんでした。")
if __name__ == "__main__":
main()
このようにbotが投稿したら成功。
ポイント
- connpass APIでイベント検索は サブドメイン と タイトルの部分一致 を組み合わせ
- 投稿文は生成AI(今回はGemini API)でイベントに応じて変化するように設定
- ローカル環境で動作確認後、そのままLambdaなどのスケジュール実行にも流用可能