0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

connpass API v2 でのイベント取得とDiscord Botでの投稿メモ

Posted at

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が投稿したら成功。

image.png

ポイント

  • connpass APIでイベント検索は サブドメインタイトルの部分一致 を組み合わせ
  • 投稿文は生成AI(今回はGemini API)でイベントに応じて変化するように設定
  • ローカル環境で動作確認後、そのままLambdaなどのスケジュール実行にも流用可能
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?