ポエム風つぶやきをブログ記事に変換するシステム：LINEからのデータ転送

# 要旨
　AIを活用してポエム風つぶやきをブログ記事に変換するシステムを検討している。

https://qiita.com/EasyCording/items/40a5ddc13bb9f7c6c645

# LINEからのポエム風つぶやきをキャッチする仕組み
　つぶやきの方法については、当初はWebアプリのようなものをスマホで作って同時にスキルを獲得したいと思っていたが、やはりこれからの時代、なんでも既存品を活用することを考えた方が利口だ。
 　そこで今回は流行りのLINE Botのスキルをつけることを優先とした。幸いLINEであれば、ユーザー自体の学習スキルは不要、コンテンツのデリバリーも圧倒的に早い。

```plantuml

@startuml
actor "LINE User" as user
participant "LINE Platform" as line
participant "Web Server\n(Flask)" as server
participant "Message Handler" as handler
participant "External System" as external

user -> line : 1. Send Message
line -> server : 2. POST /callback\n(with X-Line-Signature)

activate server
server -> server : 3. Verify Signature

alt Signature Valid
    server -> handler : 4. Process Message
    activate handler
    
    alt Is Poem Content
        handler -> external : 5a. Transfer Poem Data
        external --> handler : 5b. Transfer Result
        handler -> line : 6a. Send Success Message
    else Not Poem
        handler -> line : 6b. Send Normal Message
    end
    
    deactivate handler
    
else Signature Invalid
    server --> line : Error 400
    line --> user : Error Response
end

deactivate server

line -> user : 7. Display Reply Message

note right of server
  実装ポイント:
  * 署名検証は必須
  * 3秒以内に応答
  * HTTPSが必要
end note

@enduml
```

# アーキテクチャの工夫

LINE-BOTというのは、WEBHOOKで所定のサーバーURLに、何らかのリクエストを送るものであり、そのリクエストを受けるための待機サーバーが必要だということが分かった。
このところを如何にローコストに構築することがポイントになっているが、最終的にはConoHaのVPSを使うことにした。ここはGoogle App Scriptとかの方が無料なんだろうけど、とりあえず疎通させるのが優先なので、CENT-OSのインスタンスを作り、VS-CODEでSSH-REMOTE接続して開発した。

```plantuml
@startuml
!define SPRITESURL https://raw.githubusercontent.com/plantuml-stdlib/gilbarbara-plantuml-sprites/v1.0/sprites
!includeurl SPRITESURL/postgresql.puml
!includeurl SPRITESURL/python.puml

' システム構成図
title ConoHa VPS 開発環境構成

' ノードの定義
node "Local PC" {
    [VS Code] as vscode
    [SSH Client] as ssh
}

node "ConoHa VPS\n(CentOS)" {
    frame "Development Environment" {
        [Python 3.9] as python
        [Flask] as flask
        [LINE Bot SDK] as linebot
        database "Logs" as logs
    }
    
    frame "Security" {
        [SSL Certificates] as ssl
        [Firewall] as firewall
    }
}

cloud "LINE Platform" {
    [Messaging API] as api
}

' 接続関係
vscode --> ssh : Remote Development
ssh --> python : SSH (Port 22)
python --> flask
flask --> linebot
linebot --> logs : Write Logs
api --> firewall : Webhook\n(Port 5000)
firewall --> flask : HTTPS

note right of python
  開発環境:
  * CentOS
  * Python 3.9
  * Flask
  * LINE-BOT-SDK 2.4.2
end note

note right of firewall
  セキュリティ:
  * SSL証明書
  * Firewall (5000/tcp)
  * Webhook認証
end note

@enduml
```

# 苦労した点

Conohaのセキュリティグループ設定
LINE側の認証要求

```plantuml

@startuml
@startuml
skinparam componentStyle rectangle

title 開発における課題と解決策

package "セキュリティ設定の課題" {
  [ConoHa VPS] as conoha
  note right of conoha
    ポート開放:
    * SSH (22)
    * Webhook (5000)
    * IN/TCP
  end note
}

package "LINE Platform要件" {
  [SSL/TLS] as ssl
  [Webhook認証] as webhook
  note right of ssl 
    * 自己署名証明書
    * cert.pem/key.pem
  end note
  note right of webhook
    * Channel Secret
    * 署名検証
  end note
}

package "制約事項" {
  [実装要件] as impl
  note right of impl
    * 3秒以内の応答
    * HTTPS必須
    * 公開アクセス必要
  end note
}

conoha --> ssl
ssl --> webhook

@enduml
```
# 開発過程
いちいち、詳細は書かないが、CLAUDE3を使って、ほとんどコピペで完成した
コピペでエラーを都度貼り付けて、対処をコピペでターミナルに張り付け実行した。
この部分、Google AI Studioは役に立たない。
CLAUDE3一択である・・・

```plantuml
@startuml
skinparam componentStyle rectangle

title LINE Bot 開発プロセスと活用ツール

[Claude 3] as claude #lightgreen
note right of claude
  AI支援により効率的に実装:
  * コードの生成
  * エラー対応
  * 実装アドバイス
end note

package "開発課題" {
  [ConoHa設定] as conoha
  [LINE認証] as line
}

package "実現した機能" {
  [LINE Botサーバー] as bot
  note right of bot
    Python + Flask
    で基本実装完了
  end note
}

claude --> conoha : コード生成・設定方法
claude --> line : 認証実装・トラブル対応
claude --> bot : サーバー実装

@enduml
```

主なエラーとトラブルシューティング：


```plantuml
@startuml
@startuml
title LINE Bot 開発手順とエラー対応

skinparam componentStyle rectangle

package "1. 環境構築" {
  [Python/Flask導入]
  note bottom
    エラー: pip/gunicornなし
    対処: yum install python3-pip
  end note
}

package "2. 通信設定" {
  [ポート開放]
  note bottom
    エラー: netstatなし
    対処: yum install net-tools
  end note
}

package "3. LINE連携" {
  [SSL/Webhook]
  note bottom
    エラー: latin-1 codec
    対処: line-bot-sdk==2.4.2
  end note
}

[Python/Flask導入] --> [ポート開放]
[ポート開放] --> [SSL/Webhook]

@enduml
```
## 実装手順：


```plantuml
@startuml
title LINE Bot 実装手順

skinparam componentStyle rectangle

rectangle "1.環境準備" {
  [ConoHa VPS]
  note right
    CentOS
    Python3.9
    Flask
  end note
}

rectangle "2.認証設定" {
  [LINE Developer]
  note right
    Channel ID取得
    Channel Secret取得
  end note
}

rectangle "3.サーバー設定" {
  [Webhook]
  note right
    ポート開放(5000)
    SSL証明書
    Python実装
  end note
}

[ConoHa VPS] --> [LINE Developer]
[LINE Developer] --> [Webhook]

@enduml

```

1. **ConoHa VPS準備**
```bash
# Python環境構築
yum install python3 python3-pip
pip install flask line-bot-sdk==2.4.2
```

2. **LINE Developer設定**
- LINE Developersコンソールで新規チャネル作成
- チャネルシークレット取得
- Messaging API設定

3. **サーバー設定**
```bash
# SSL証明書生成
openssl req -x509 -nodes -newkey rsa:4096 -out cert.pem -keyout key.pem -days 365

# ポート開放
firewall-cmd --permanent --add-port=5000/tcp
firewall-cmd --reload
```

4. **Webhook URL設定**
```
https://サーバーIP:5000/callback
```

シンプルな実装で、LINE経由のメッセージ取得が可能になります。

## LINE Bot
実装コード：

```App.py
from flask import Flask, request, abort
from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)
import logging
from logging.handlers import RotatingFileHandler
import os

# ログ設定
log_dir = "/root/python/logs"
if not os.path.exists(log_dir):
    os.makedirs(log_dir)

formatter = logging.Formatter(
    '%(asctime)s - %(levelname)s - %(message)s'
)

file_handler = RotatingFileHandler(
    f"{log_dir}/linebot.log",
    maxBytes=1024 * 1024,
    backupCount=5,
    encoding='utf-8'
)
file_handler.setFormatter(formatter)
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(file_handler)

app = Flask(__name__)

# LINE Messaging API設定
CHANNEL_ACCESS_TOKEN = "アクセストークンを入力"
CHANNEL_SECRET = "チャネルシークレットを入力"

line_bot_api = LineBotApi(CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(CHANNEL_SECRET)

@app.route("/callback", methods=['POST'])
def callback():
    signature = request.headers['X-Line-Signature']
    body = request.get_data(as_text=True)
    logger.info("Webhook received")
    
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)
    return 'OK'

@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    try:
        # メッセージを受信して応答
        line_bot_api.reply_message(
            event.reply_token,
            TextSendMessage(text="OK")
        )
        logger.info("Reply sent successfully")
    except Exception as e:
        logger.error(f"Error: {str(e)}")

if __name__ == "__main__":
    app.run(host='127.0.0.1', port=5000, ssl_context=('cert.pem', 'key.pem'))

```

実装後の起動手順：

```bash
# 環境構築
yum install -y python3 python3-pip
pip3 install flask line-bot-sdk==2.4.2

# SSL証明書生成
openssl req -x509 -nodes -newkey rsa:4096 -out cert.pem -keyout key.pem -days 365

# ポート開放
firewall-cmd --permanent --add-port=5000/tcp
firewall-cmd --reload

# アプリケーション実行
python3 app.py

```

LINE Developersコンソールの設定：
1. チャネル作成
2. Messaging API設定画面でWebhook URL設定：
   ```
   https://サーバーIP:5000/callback
   ```
3. Webhook利用を有効化

# まとめ

とりあえず三連休の初日で、かなりのマイルストーンを動かすことができた（所要時間３ｈ）
ついでに、このQiitaの記事もClaude3に書かせた（ここの会話のやり取りが一番重要だとは思うけど、ＡＩとのコミュニケーション能力があれば誰でもできるのであえて書かない）