connpassのイベント情報を生成AIで自動評価してSlack通知する仕組みを作った話

# 1. はじめに
最近、生成AI（ChatGPTやClaudeなど）を活用した業務改善や自動化の事例が増えてきました。私自身もAI技術を使って「自分の課題を少しでも楽にしたい」と考えていたところ、「技術系イベントの探し方」に毎週時間をかけていることに気づきました。

特に、以下のような課題感がありました：

- イベントが多すぎて、自分に合ったものを見つけるのが大変

- タイトルや説明文だけでは内容が把握しきれない

- 「実務的に役立つか？」「初心者向けではないか？」など、毎回チェックするのが面倒

そこで今回、**connpass APIで取得したイベント情報を生成AI（GPT）で自動評価し、Slackに要約付きで通知する仕組み**を作ってみました。
GitHub Actionsによって週1回自動実行されるため、「Slackを見るだけで、自分に合ったおすすめイベントがわかる」状態を実現しています。

Slackでの表示イメージ：

![connpassイベント_Slackイメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2681141/4746b2bc-9a28-4d22-9d33-f9ea1521913d.png)

（※本キャプチャは現実には存在しない架空のイベント情報です）

## 🎯 本記事の目的
本記事では、以下の内容を紹介します：

- connpass API × GPT × Slack連携によるイベント通知Botの構築方法

- GitHub Actionsを使った週次自動実行の仕組み

- 実際に使って感じた効果や工夫した点

生成AIや自動化に興味がある方、技術系イベントの情報収集に時間をかけている方に、少しでも参考になれば嬉しいです。

## ⚠️ 注意点（connpass APIの利用規約について）
本記事は [connpass API](https://help.connpass.com/api/api-term)利用規約 に則り、以下の制約を守っています：

- 本システムは個人利用および通知目的に限定しています

- イベント情報の再配信・改変・商用利用は一切行っていません

- 通知内容にはイベント公式URLを必ず記載し、出典元を明示しています

# 2. システムの全体像
今回構築したシステムは、以下の要素で構成されています。

- `connpass API` でイベント情報を取得

- `GPT（OpenAI API）` でイベントを要約・スコア評価

- 上位3件を抽出し、Slackへ通知

- `GitHub Actions` により週1回、自動で実行

この処理全体で、「技術系イベントの自動レコメンドBot」が実現できました。

## システム構成図
![connpass_events.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2681141/0d212c1d-b5b3-4baf-bd6a-9b62e1853e86.png)

## 🔄 処理の流れ（概要）
**1. connpass APIでイベントを取得**

- 毎週、あらかじめ指定した**キーワード**（例：「生成AI」「LangChain」など）かつ**オンラインイベント**に絞って検索

- タイトルに「もくもく会」「MokuMoku会」が含まれるイベントは除外（※講義系のイベントに注目するため）

**2. GPTでイベントの要約とスコア評価**

- 評価軸（後述）に沿って、イベントごとに1〜5点のスコアを付ける

- スコア理由も含めて要約を生成

**3. 上位3件を選定し、Slackに通知**

-  スコア上位のイベントだけを整形して、Slackチャンネルに投稿

-  イベントのタイトル・開催日時・申込URLなどを含めて表示

**4. GitHub Actionsで自動実行**
- 毎週金曜日9時（JST）にワークフローを起動

- APIキー等はGitHub上のSecretsで安全に管理

## 🎯 使用した主要技術スタック
| 項目      | 使用技術                                  |
| ------- | ------------------------------------- |
| 言語・実行環境 | Python 3.11、GitHub Actions            |
| 外部API   | connpass API、OpenAI API、Slack Webhook |
| 自動化ツール  | GitHub Actions（週次定期実行）                |
| 評価ロジック  | ChatGPT（gpt-3.5-turbo）でのプロンプトベース評価            |

# 3. 各コンポーネントの実装詳細
このセクションでは、実際に使用したPythonコードや処理の工夫点を解説します。コードはすべて [GitHubリポジトリ](https://github.com/pomeshiba29/connpass_events_notifier) に公開しています。

## 3.1 connpass APIによるイベント取得
### ✅ 事前準備：connpass APIは申請が必要
connpass APIは誰でも使えるわけではなく、**APIキーの取得には申請が必要**です（[connpassのAPI利用について](https://help.connpass.com/api/)） 。

※ 本記事はconnpass APIの利用規約を遵守しており、取得したイベント情報は商用目的や再配信には一切使用していません。

### 🗂️ 条件設定はJSONで柔軟に管理
イベント取得条件（キーワード・除外ワード・開催地域・件数など）は、Pythonコード内にハードコーディングせず、別途 config.json にて管理するようにしています。

```json
{
  "search": {
    "keywords": ["生成AI", "LLM", "MCP", "Claude", "GPT", "RAG", "Gemini"],
    "count": 10,
    "online_only": true,
    "exclude_titles": ["もくもく会", "MokuMoku会"]
  }
}
```
📎 GitHub上のコード([fetcher.py](https://github.com/pomeshiba29/connpass_events_notifier/blob/main/fetcher.py))

##  3.2 GPTでの評価・スコア付け
取得したイベント情報に対して、**OpenAIのGPT(gpt-3.5-turbo)を用いて要約＋スコア評価を実施**しています。
このパートでは、イベントの良し悪しを定量的に判定するために、**プロンプト設計**に特にこだわりました。

### ✅ 評価の目的
connpassのイベント情報を効率的に読み込むために、以下のような点を個人的に重視しました：

- そのイベントは「業務に役立つ実践的内容か？」

- 「初心者向け」なのか「中級以上向け」か？

- 登壇者はどういった業務背景を持たれた方なのか？

これらをGPTに評価させることで、自動かつ一貫性のあるスコア付けができるようになります。

### 📝 評価項目とルール
GPTには以下4つの観点で、1〜5点でスコア評価してもらうよう設計しました：
| 評価項目              | 内容                  |
| ----------------- | ------------------- |
| ① 実務的な開発スキルが身につくか | 現場で使える内容かどうか        |
| ② 対象者のレベルが中級以上か   | 初心者向けでないか           |
| ③ ハンズオン（実践演習）があるか | 手を動かす内容かどうか         |
| ④ 登壇者の専門性・実績 | スピーカーの実績・肩書など       |
| ✅ 平均スコア           | 上記4項目の平均（GPTに計算させる） |

### 🧪 プロンプト設計（抜粋）
以下のようなプロンプトやパラメーターをGPTに渡し、イベントごとに評価を依頼しています。
※3.1のようにプロンプトは以下のようなJSONで管理

```json
{
  "scoring": {
    "criteria": [
      "①生成AIの実務的な開発スキルが高められるか",
      "②対象者のレベルが中級以上か",
      "③ハンズオン（実践演習）があるか",
      "④登壇者の専門性・実績"
    ],
    "summary_limit": "【概要】概要を3行以内で要約してください。",
    "score_format": "【平均スコア】平均スコアを以下の形式で明示してください：\n平均スコア：4.25点",
    "model": "gpt-3.5-turbo",
    "temperature": 0.3,
    "max_tokens": 900,
    "system_role": "あなたは生成AIイベントの評価専門家です。"
  }
}
```

📎 GitHub上のコード([scoring.py](https://github.com/pomeshiba29/connpass_events_notifier/blob/main/scoring.py))

## 3.3 上位3件を選定・整形
GPTによってスコア付けされたイベント一覧から、平均スコアの高い上位3件を抽出し、Slack通知用の整形を行います。
この工程では、単に点数でソートするだけでなく、通知メッセージの視認性や読みやすさも意識してフォーマットしています。

### ✅ 処理の流れ
1. GPTの出力から「平均スコア」を抽出

2. スコア順に並び替え

3. 上位3件をフォーマット（順位・要約・スコア・URLなどを含む）

### 📌 平均スコアの抽出処理
GPTから返ってくる出力には「平均スコア：X.X」という形式で点数が含まれています。正規表現でそれを抜き出し、数値として扱います。

```python
import re

def extract_average_score(text):
    match = re.search(r"(?:平均スコア|評価スコア|スコア)[^\d]*([0-9]+(?:\.[0-9]+)?)", text)
    return float(match.group(1)) if match else 0.0

```

### 🧾 上位3件の整形出力（Slack向け）
Slack通知での見やすさを意識し、以下のような情報を整えて表示します：

- ランキング（第1位～第3位）

- タイトル・開催日時

- GPTによる要約とスコア

- イベントURL

```python
def format_top_events(scored_events):
    output = "\n🔝 今週の上位3件のイベント紹介：\n"
    for idx, (score, summary, event) in enumerate(scored_events[:3], start=1):
        url = f"https://connpass.com/event/{event['event_id']}/"
        output += f"\n---\n【第{idx}位】{event['title']}\n"
        output += f"📅 開催日時：{event['started_at']}\n"
        output += f"📍 開催場所：{event['place']}\n"
        output += f"👥 参加状況：{event['accepted']}/{event['limit']}人\n"
        output += f"🔗 URL：{url}\n"
        output += f"📝 GPT評価：\n{summary}\n"
    return output
```


📎 GitHub上のコード([selector.py](https://github.com/pomeshiba29/connpass_events_notifier/blob/main/selector.py))

## 3.4 Slackへの通知とGitHub Actionsによる自動化
整形済みのおすすめイベント情報は、Slackに毎週自動投稿されるように構成しています。
このパートでは、

- Slack通知（Webhook）の使い方

- GitHub Actionsによる週次自動実行

- Secrets管理の注意点

についてご紹介します。
### ✅ Slack通知：Webhookで投稿
SlackのIncoming Webhook URLを使って、通知テキストを送信します。
```python
import os
import requests

def send_to_slack(message: str):
    if not SLACK_WEBHOOK_URL:
        raise ValueError("Slack Webhook URLが設定されていません。")
    response = requests.post(SLACK_WEBHOOK_URL, json={"text": message})
    if response.status_code != 200:
        raise Exception(f"Slack送信失敗: {response.status_code} - {response.text}")
    print("✅ Slackへ送信完了")
```
環境変数 SLACK_WEBHOOK_URL はGitHub Secrets に安全に格納します。
Slack側では「アプリを追加 → Incoming Webhooks 有効化 → チャンネル選択 → URL発行」で準備可能です(詳細は[こちら](https://api.slack.com/messaging/webhooks))
📎 GitHub上のコード([notifier.py](https://github.com/pomeshiba29/connpass_events_notifier/blob/main/notifier.py))

### ⚙️ GitHub Actionsで週次自動実行
毎週金曜日の朝9時（JST）に、GitHub Actions でPythonスクリプトを自動実行するように設定しています(GitHub>Actionsのタブで以下のyamlファイルを実行)。
※以下が実際の .github/workflows/notify.yml の一例です：
```yaml
name: Weekly AI Event Notifier

on:
  schedule:
    - cron: '0 0 * * 5'  # 毎週金曜 午前9時（JST）
  workflow_dispatch:       # 手動実行も許可

jobs:
  run-notifier:
    runs-on: ubuntu-latest

    steps:
    - name: ✅ リポジトリをチェックアウト
      uses: actions/checkout@v3

    - name: 🐍 Pythonをセットアップ
      uses: actions/setup-python@v4
      with:
        python-version: '3.11'

    - name: 📦 ライブラリをインストール
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt

    - name: 🚀 通知スクリプトを実行
      env:
        OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
        SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
        CONNPASS_API_KEY: ${{ secrets.CONNPASS_API_KEY }}
      run: |
        python main.py
```


### 🔐 Secretsの安全な扱い（超重要）
以下のようなAPIキー・Webhook URLはすべて GitHubの「Secrets」に登録して管理しています：
| 変数名                 | 用途               |
| ------------------- | ---------------- |
| `OPENAI_API_KEY`    | GPT用のAPIキー     |
| `SLACK_WEBHOOK_URL` | Slack通知用のWebhook |
| `CONNPASS_API_KEY`  | connpass API用キー  |

設定手順：
GitHubリポジトリ → Settings → Secrets and variables → Actions → `New repository secret`

# 4. 運用で見えた効果と改善ポイント
**タイトル・開催日時・要約・スコア・申込URL**が1メッセージにまとまって届くので、イベントの内容と魅力をすばやく把握でき、参加検討の意思決定が格段に早くなりました。
さらに人気のイベントはすぐに定員オーバーになってしまうので、早めのキャッチアップも行えるようになり、機会損失の回避にもつながりました。
## 🎯 使ってみたメリット(まとめ)
| 観点     | 内容                          |
| ------ | --------------------------- |
| 時間削減   | 検索や比較の手間がなくなり、Slackを見るだけで済む |
| 見逃し防止  | 週次通知で定期的に最新イベントをチェックできる     |
| 精度の高さ  | GPTが内容を要約＋スコア付けしてくれるので、精査不要 |
| 学習意欲UP | 良質なイベントに早めに出会えるため、参加モチベが向上  |

##  GPTスコアの感触
GPTのスコアリング精度については、おおむね直感とも一致しており、信頼性を感じました。

- タイトルや講師情報が具体的なイベントは、評価が高くなりやすい
- 抽象的なテーマや短い説明のイベントは、スコアが低くなる傾向あり

これは評価基準が明示されている分、GPTがある程度客観的にフィルタをかけてくれている証拠だと感じています。

## 📌 参考：使ってみた工夫
- 評価プロンプトを数回調整し、スコア表現がブレにくくなるよう改善

- 通知内容の整形を工夫し、Slackでの可読性を向上

- 「もくもく会」除外など、ノイズ除去も地味に効いている

## 🧪 今後の運用に向けて
- GPT以外の他のエージェント（ClaudeやGeminiなど）で出力結果の比較
- スコアが「一律0点」になるなど異常が起きた場合のリトライ処理などの実装
- connpass以外（Peatix, Doorkeeperなど）への拡張性の検討

# 5. まとめと参考リソース
## ✅ まとめ
この仕組みによって、イベント選定・参加判断の効率化が大きく進みました。一方で、評価モデルの選択や例外対応など、さらなる改善点も明確になってきました。

## 🔗 参考リソース
本記事で紹介した技術やAPIに関する詳細は、以下の公式ドキュメントをご参照ください。
- 💻 [GitHubリポジトリ（コード全体）](https://github.com/pomeshiba29/connpass_events_notifier)

- 📄 [connpass API 利用規約](https://help.connpass.com/api/api-term)

- 🤖 [OpenAI API ドキュメント](https://platform.openai.com/docs/overview)

- 🔧 [Slack API ドキュメント（Incoming Webhooks）](https://api.slack.com/messaging/webhooks)

- 🔁 [GitHub Actions ドキュメント](https://docs.github.com/ja/actions)