LINEに送られた領収書を自動でMoneyForwardクラウドBoxに保存するbotを作った話
顧問先とのやり取りはLINEが多いのですが、そこに送られてくる領収書の画像を、毎回手動でMoneyForwardにアップロードするのが地味に手間でした。そこで、LINEのグループに投げるだけでクラウドBoxに保存されるbotを作りました。
全体構成
- LINE公式アカウント + Messaging APIでメッセージ(画像・PDF)を受信
- FastAPIでWebhook受信用エンドポイントを実装し、Renderにデプロイ
- マネーフォワード クラウドBox APIでファイルを直接アップロード
顧問先ごとにLINEグループを分けていて、グループIDをキーに、どの事業者のクラウドBoxに保存するかを出し分けています。 顧問先ごとにOAuthの認可を1度ずつ通してもらい、アクセストークンとリフレッシュトークンを保持しておく形です。
つまずいたポイント
1. 画像の実体はWebhookに含まれていない
Webhookで届くのはメッセージイベントで、画像そのものは入っていません。イベント内の messageId を使って、別のエンドポイントからバイナリを取得する必要があります。
GET https://api-data.line.me/v2/bot/message/{messageId}/content
ホストが通常のAPI(api.line.me)ではなく api-data.line.me になる点に注意してください。Python SDK(v3)を使うなら MessagingApiBlob の get_message_content() が対応するので、自前でホストを意識する必要はありません。
なお、ユーザーが送信したコンテンツは一定期間で自動的に削除される仕様です。「後でまとめて取りに行く」設計にすると取りこぼすので、Webhookを受けたその場で取得してしまうのが安全です。
2. 送信元の検証を省略しない
Webhookのエンドポイントはインターネットに公開されるので、リクエストが本当にLINEプラットフォームから来たものかを検証する必要があります。x-line-signature ヘッダーの署名を、チャネルシークレットを鍵としたHMAC-SHA256(Base64)と突き合わせます。SDKの WebhookHandler に任せれば、不正な署名は InvalidSignatureError で弾かれます。領収書という性質上、ここは必須です。
3. クラウドBoxへのアップロードは multipart で2パート必要
クラウドBox APIのアップロードは、ファイル本体だけでは通りません。file(バイナリ)と metadata(JSON)の2つのパートを multipart/form-data で送ります。metadata には最低限 file_name が必要です。
POST https://api.box.moneyforward.com/v1/files
Authorization: Bearer {access_token}
成功時は 201 が返り、file_id を含むFileオブジェクトが得られます。ファイルサイズの上限は10MBなので、大きめのPDFを扱う場合は事前にチェックしておくと安全です。
4. アクセストークンの期限切れをどう捌くか
ここが一番面倒でした。クラウドBox APIはOAuth 2.0の認可コードフローで、アクセストークンには期限があります。有効期限を自前で管理して先回りする方法もありますが、結局ズレるので、アップロードが401で返ってきたらリフレッシュして1回だけリトライするという素朴な作りに落ち着きました。
リフレッシュ時は新しいリフレッシュトークンも返ってくるので、両方を保存し直すのを忘れないでください。ここを取りこぼすと、次回の更新で詰みます。
5. 誰が送ったファイルか分からなくなる
グループに複数人いると、保存されたファイルを見ても誰が送ったものか分かりません。get_group_member_profile() で送信者の表示名を取得し、20260615_1430_山田太郎.jpg のようにタイムスタンプ+送信者名でファイル名を組み立てるようにしました。後から探すときに効きます。
今後の展望
現状は保存するだけですが、クラウドBox APIには /v1/files/{file_id}/content でファイルコンテンツのメタデータ(取引日・合計金額・取引先名・書類種別など)を取得するエンドポイントがあります。ここを読んで仕訳の下書きまで自動生成するところまで発展させたいと考えています。
同じような「クラウド会計まわりの自動化」に興味がある方は、お気軽にお問い合わせください。
この内容について相談したい場合は
無料相談を申し込む