Pythonで作成するLINE公式BOTの完全ガイド
FastAPIとCloudflare Tunnelを活用して自宅サーバーで動作するLINE BOTを構築し、Notionに日記を記録する方法
主なポイント
- 環境構築と依存関係の設定: 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データベースに日記が正しく記録されることを確認します。
テスト手順
- LINEアプリでBOTを追加します。
- Webhook URLが正しく設定されていることを確認します。
- BOTに日記メッセージを送信します。
- 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