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?

Notion × ChatGPT × Slackで作る健康分析システム

Posted at

はじめに

私はこれまで毎日の睡眠時間と筋トレの内容をNotionに記録していました。
しかし、記録以外は特に何もしていませんでした。

そこでせっかく記録しているのであれば、AIに分析とアドバイスを貰いながら健康に関して改善ができないかなと思い、分析作業自動化を行ったので振り返りも兼ねて記事にします。

システム概要

できること

  • 📊 Notionから自動データ収集:
    • ワークアウト・睡眠データベースから最新100件を取得
  • 🤖 AI による自動分析:
    • ChatGPTが健康データを分析し、傾向や改善点を提示
  • 📱 Slack自動通知:
    • 週次レポートをSlackに自動投稿
  • GitHub Actions自動実行:
    • 毎週日曜日の18時に自動実行

アーキテクチャ

技術スタック

使用技術

  • TypeScript - メイン言語
  • Notion API - データベース連携
  • OpenAI API - AI分析
  • Slack Webhook - 通知
  • GitHub Actions - 定期実行
  • Luxon - 日時操作

実装のポイント

1. Notion API連携

Notionのデータベースから睡眠と筋トレのデータを取得します。
また、分析観点や出力フォーマットもNotionで管理することによりアプリの修正をせず分析観点やフォーマットを変更することができます。
※プロンプトの記載は色々と試行錯誤したところがあったので別記事にします。

//分析プロンプトを取得
const workoutInstruction = await getPagePlainText(notion, env.WORKOUT_INSTRUCTION_PAGE_ID);
const sleepInstruction = await getPagePlainText(notion, env.SLEEP_INSTRUCTION_PAGE_ID);
  
// メタデータとデータを並行取得
const [workoutProps, sleepProps] = await Promise.all([
  getDatabaseProperties(notion, env.WORKOUT_DB_ID),
  getDatabaseProperties(notion, env.SLEEP_DB_ID),
]);

const workoutRows = await getRecentRowsRaw(notion, env.WORKOUT_DB_ID, 100);
const sleepRows = await getRecentRowsRaw(notion, env.SLEEP_DB_ID, 100);

2. ChatGPT分析

構造化されたデータをChatGPTに送信し、分析結果を取得します。

const payload = {
  meta: {
    generated_at: DateTime.now().setZone("Asia/Tokyo").toISO(),
    timezone: "Asia/Tokyo",
    retrieval: { strategy: "created_time_desc_first_100" },
    dbs: {
      workout: { id: env.WORKOUT_DB_ID, properties: workoutProps },
      sleep: { id: env.SLEEP_DB_ID, properties: sleepProps },
    },
  },
  data: {
    workout_rows: workoutRows,
    sleep_rows: sleepRows,
  },
};

const workoutResult = await analyzeText(env.OPENAI_API_KEY, workoutInstruction, payload);
const sleepResult = await analyzeText(env.OPENAI_API_KEY, sleepInstruction, payload);

3. Slack通知

分析結果をSlackに自動投稿します。

await postSlack(env.SLACK_WEBHOOK_URL, result.workout, {
  title: "Health Analysis 週次レポート - Workout",
  footer: "_retrieval: latest 100 by created_time_"
});

4. GitHub Actions自動実行

週次で自動実行する設定です。

name: Weekly Health Analysis
on:
  schedule:
    - cron: '0 9 * * 0'   # JST 日曜18:00(= UTC 日曜09:00)
  workflow_dispatch:

jobs:
  health-analysis:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm install
      - run: npm run dev
        env:
          NOTION_API_KEY: ${{ secrets.NOTION_API_KEY }}
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

セットアップ手順

1. Notion設定

  1. Notion APIキーを取得
  2. 分析したい記録のデータベースを作成
  3. 分析指示ページを作成(ChatGPTへの指示を記載)

2. OpenAI設定

OpenAI APIキーを取得します。

3. Slack設定

Incoming Webhookを設定してWebhook URLを取得します。

4. 環境変数設定

# Notion API設定
NOTION_API_KEY=your_notion_api_key
NOTION_VERSION=2022-06-28

# Notion データベース・ページID
WORKOUT_INSTRUCTION_PAGE_ID=your_workout_instruction_page_id
SLEEP_INSTRUCTION_PAGE_ID=your_sleep_instruction_page_id
WORKOUT_DB_ID=your_workout_database_id
SLEEP_DB_ID=your_sleep_database_id

# OpenAI API設定
OPENAI_API_KEY=your_openai_api_key

# Slack通知設定
SLACK_WEBHOOK_URL=your_slack_webhook_url

5. 実行

npm install
npm run dev

Slack通知例

📊 Health Analysis 週次レポート - Workout

**Summary:**
今週は4回の運動を実施。先週と比較して頻度は維持しているが、
強度が少し下がっている傾向。

**Insights:**
• 筋力トレーニングの頻度が減少(3回→2回)
• 有酸素運動の時間が増加(平均+10分)
• 休息日が適切に配置されている

**Action:**
来週は筋力トレーニングを1回追加し、
高強度インターバルを取り入れてみましょう。

開発で工夫したポイント

プロンプトの管理をNotionで完結

ChatGPTへのプロンプトは全てNotionのページにマークダウンで記載することで、いつでも気軽に変更できるようにしました。
これによって、アプリの修正をせずとも分析観点の変更や出力フォーマットの変更が行えます。また、ChatGPTのレベルが上がれば分析精度も向上することが期待できます。

// Notionから分析指示を動的に取得
const workoutInstruction = await getPagePlainText(notion, env.WORKOUT_INSTRUCTION_PAGE_ID);
const sleepInstruction = await getPagePlainText(notion, env.SLEEP_INSTRUCTION_PAGE_ID);

この設計により:

  • 非エンジニアでも編集可能: Notionページを編集するだけで分析内容を変更
  • バージョン管理: Notionの履歴機能で変更を追跡
  • 即座に反映: 再デプロイ不要で次回実行時から新しいプロンプトが適用
  • チーム共有: 複数人でプロンプトを改善・共有可能

プロンプトをマークダウンで記述

1. AIが構造を正確に理解しやすい

マークダウン形式は見出し(#、##)、リスト(-、1.)などで階層構造を明確にできるため、LLMが「どこが目的で、どこが指示で、どこが出力フォーマットか」を機械的に正しく解釈できます。

## 分析観点
1. 理想の睡眠時間
2. 理想の就寝時刻

2. 出力フォーマットの統一・整形が容易
Markdownで出力フォーマットを定義しておくと、AIが回答を「整ったレポート形式」で返してくれます。

### 💡 結論
理想の就寝時刻: {{理想就寝時刻}}
理想の睡眠時間: {{理想睡眠時間}}

→ 出力時もAIは見出し構造を維持して出すため、Slack上でも読みやすいレポートになります。

まとめ

このシステムの特徴:

柔軟性: 分析指示を変更するだけでカスタマイズ可能
拡張性: コーディングせずに分析観点、出力フォーマットの変更が可能
コスト効率: サーバー不要、GitHub Actions利用
自動化: 人手を介さずに完全自動

分析プロンプトはまだまだ改善の余地がありますが、
これまで無駄に溜めていた健康データを活用することで、これまでより健やかに暮らしていけるような気がします。

ソースコード

完全なソースコードは以下のリポジトリで公開してます:
GitHub Repository

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?