Chat
Ask me anything
Ithy Logo

Pythonで作成するLINE公式BOTの完全ガイド

FastAPIとCloudflare Tunnelを活用して自宅サーバーで動作するLINE BOTを構築し、Notionに日記を記録する方法

line bot setup infrastructure

主なポイント

  • 環境構築と依存関係の設定: Proxmox上のUbuntuサーバーに必要なパッケージをインストールし、仮想環境を整備します。
  • Cloudflare Tunnelの設定: 自宅サーバーを外部から安全にアクセス可能にするためにCloudflare Tunnelを利用します。
  • LINE BOTとNotionの連携: FastAPIを使用してWebhookを受け取り、Notion APIを通じて日記データを管理します。

1. 環境のセットアップ

1.1. Proxmox上のUbuntuサーバーの準備

Proxmox上にUbuntuの仮想マシンを作成し、インターネットに接続できる状態にします。これにより、外部からのアクセスや必要なパッケージのインストールが可能となります。

1.2. 必要なパッケージのインストール

UbuntuサーバーにPythonや関連パッケージをインストールします。以下のコマンドを使用してください。

sudo apt update
sudo apt install -y python3 python3-pip python3-venv

1.3. 仮想環境の作成とアクティベーション

Pythonの仮想環境を作成し、アクティベートします。これにより、プロジェクトごとに依存関係を管理できます。

python3 -m venv venv
source venv/bin/activate

1.4. 必要なPythonパッケージのインストール

FastAPIやLINE BOT SDK、Notionクライアントなどの必要なパッケージをインストールします。

pip install fastapi uvicorn line-bot-sdk python-dotenv notion-client requests

2. Cloudflare Tunnelの設定

2.1. Cloudflareアカウントの作成とドメインの準備

Cloudflareのアカウントを作成し、既存のドメインをCloudflareに追加します。ドメインがない場合は新規取得も検討してください。

2.2. `cloudflared`のインストール

Cloudflare Tunnelを利用するために、`cloudflared`をインストールします。

wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared-linux-amd64.deb

2.3. トンネルの作成

Cloudflare Tunnelを作成し、トンネルIDを取得します。

cloudflared tunnel create line-bot-tunnel

2.4. トンネル設定ファイルの作成

作成したトンネルを設定するために、設定ファイルを作成します。以下はサンプル設定です。

tunnel: YOUR_TUNNEL_ID
credentials-file: /root/.cloudflared/YOUR_TUNNEL_ID.json

ingress:
  - hostname: your-domain.com
    service: http://localhost:8000
  - service: http_status:404

2.5. トンネルの起動

設定ファイルを基にトンネルを起動します。

sudo cloudflared tunnel --config /etc/cloudflared/config.yml run line-bot-tunnel

3. LINE BOTの設定

3.1. LINE Developers Consoleでの設定

LINE Developers Consoleにログインし、新しいプロバイダーとチャネルを作成します。チャネル作成後、チャネルアクセストークンとチャネルシークレットを取得します。

3.2. Webhook URLの設定

Webhook URLとして、Cloudflare Tunnelで設定したURL(例: https://your-domain.com/webhook)をLINE Developers Consoleに設定します。


4. FastAPIアプリケーションの作成

4.1. プロジェクト構造の設定

プロジェクトディレクトリを以下のように構造化します。

linebot_project/
  ├── main.py
  ├── .env
  └── services/
      ├── line_service.py
      └── notion_service.py

4.2. `.env`ファイルの設定

環境変数を管理するために、`.env`ファイルを作成し、以下の内容を記述します。

LINE_CHANNEL_SECRET=your_line_channel_secret
LINE_CHANNEL_ACCESS_TOKEN=your_line_channel_access_token
NOTION_API_KEY=your_notion_api_key
NOTION_DATABASE_ID=your_notion_database_id

4.3. LINEサービスの実装

`services/line_service.py`を作成し、LINE BOTの基本設定を行います。

import os
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent, TextMessage

class LineService:
    def __init__(self):
        self.line_bot_api = LineBotApi(os.getenv('LINE_CHANNEL_ACCESS_TOKEN'))
        self.handler = WebhookHandler(os.getenv('LINE_CHANNEL_SECRET'))

    def validate_signature(self, body, signature):
        try:
            self.handler.handle(body, signature)
            return True
        except InvalidSignatureError:
            return False

4.4. Notionサービスの実装

`services/notion_service.py`を作成し、Notion APIとの連携を設定します。

import os
from notion_client import Client
from datetime import datetime

class NotionService:
    def __init__(self):
        self.notion = Client(auth=os.getenv('NOTION_API_KEY'))
        self.database_id = os.getenv('NOTION_DATABASE_ID')

    def create_diary_entry(self, text):
        today = datetime.now().strftime("%Y-%m-%d")
        try:
            self.notion.pages.create(
                parent={"database_id": self.database_id},
                properties={
                    "Date": {"date": {"start": today}},
                    "Content": {"rich_text": [{"text": {"content": text}}]}
                }
            )
            return True
        except Exception as e:
            print(f"Notion error: {e}")
            return False

4.5. メインアプリケーションの実装

`main.py`を作成し、FastAPIアプリケーションを設定します。

from fastapi import FastAPI, Request, Header, HTTPException
from dotenv import load_dotenv
from services.line_service import LineService
from services.notion_service import NotionService
from linebot.models import TextSendMessage

load_dotenv()

app = FastAPI()
line_service = LineService()
notion_service = NotionService()

@app.post("/webhook")
async def line_webhook(request: Request, x_line_signature: str = Header(None)):
    body = await request.body()
    body_str = body.decode('utf-8')

    if not line_service.validate_signature(body_str, x_line_signature):
        raise HTTPException(status_code=400, detail="Invalid signature")

    events = line_service.handler.parser.parse(body_str)
    for event in events:
        if isinstance(event.message, TextMessage):
            text = event.message.text
            if notion_service.create_diary_entry(text):
                line_service.line_bot_api.reply_message(
                    event.reply_token,
                    TextSendMessage(text="日記を保存しました!")
                )
            else:
                line_service.line_bot_api.reply_message(
                    event.reply_token,
                    TextSendMessage(text="日記の保存に失敗しました。")
                )
    return {"message": "OK"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

5. アクセストークン入力機能の実装

5.1. トークン設定用エンドポイントの作成

ユーザーが初回にアクセストークンを入力できるように、トークン設定用のエンドポイントを追加します。

@app.post("/set_tokens")
async def set_tokens(payload: dict):
    """
    JSON形式の例:
    {
        "line": "YOUR_LINE_ACCESS_TOKEN",
        "notion": "YOUR_NOTION_API_KEY"
    }
    """
    if "notion" in payload:
        notion_service.notion = Client(auth=payload["notion"])
    if "line" in payload:
        line_service.line_bot_api = LineBotApi(payload["line"])
    return {"message": "アクセストークンが設定されました。", "current_tokens": payload}

5.2. トークンの安全な管理

アクセストークンは環境変数や安全なストレージに保存し、不正アクセスを防ぐために適切に管理します。


6. データの保存と管理

6.1. Notionデータベースの構築

Notionで日記を保存するためのデータベースを作成し、各日付ごとにページを作成します。各ページには日記の内容が追加されていきます。

6.2. データベースIDの取得

作成したNotionデータベースのIDを取得し、`.env`ファイルに設定します。


7. 実行とテスト

7.1. FastAPIサーバーの起動

以下のコマンドでFastAPIサーバーを起動します。

uvicorn main:app --host 0.0.0.0 --port 8000

7.2. Cloudflare Tunnelの起動

Cloudflare Tunnelを起動して、外部からのアクセスを可能にします。

sudo cloudflared tunnel --config /etc/cloudflared/config.yml run line-bot-tunnel

7.3. LINE BOTの動作確認

LINEアプリからBOTにメッセージを送信し、Notionデータベースに日記が正しく記録されることを確認します。

テスト手順

  1. LINEアプリでBOTを追加します。
  2. Webhook URLが正しく設定されていることを確認します。
  3. BOTに日記メッセージを送信します。
  4. Notionデータベースに新しいページが作成され、メッセージ内容が追加されていることを確認します。

8. プロジェクト構造の概要

8.1. ディレクトリ構造

ディレクトリ/ファイル 説明
linebot_project/ プロジェクトのルートディレクトリ
├── main.py FastAPIアプリケーションのメインファイル
├── .env 環境変数を格納するファイル
└── services/ サービス関連のモジュールを格納するディレクトリ
├── line_service.py LINE BOTのサービスロジック
└── notion_service.py Notion APIとの連携ロジック

9. まとめ

本ガイドでは、PythonとFastAPIを使用してLINE公式BOTを構築し、Cloudflare Tunnelを介して自宅サーバーから外部アクセスを可能にする方法を詳述しました。BOTはユーザーから受け取った日記メッセージをNotionデータベースに自動的に記録します。これにより、ポート開放を行わずに安全かつ効率的にサービスを提供できます。セキュリティ対策やエラーハンドリングを強化することで、さらに信頼性の高いシステムを構築することが可能です。

参考文献


Last updated February 11, 2025
Ask Ithy AI
Download Article
Delete Article