はじめに
コラボフローの申請画面上から直接AI-OCRのAPIを実行しようとしたら、CORSエラーで失敗しました。(そりゃそうだ)
じゃあ、オンプレ環境に構築されているDify(Community版)上でAPI実行をやってもらえばいけるんじゃねという発想で作ってみたら、ちゃんと動いたので、記事にさせていただきました。
実現したこと
- コラボフローの申請画面に「領収書解析」ボタンを設置
- 添付画像(領収書)をDifyに渡して、日付・金額・発行者・電話番号・登録番号を抽出
- 抽出結果をフォームに自動入力
アーキテクチャ
[Collaboflow (Browser)]
├─ 添付ファイルダウンロード(認証付き)
├─ Difyへファイルアップロード(local_file)
└─ Dify Workflowを実行(blocking)
[Dify (On-Prem / Community)]
├─ Workflow: 開始 → HTTPリクエスト(AI-OCR) → 終了
└─ body(JSON)で抽出結果を返す
[Collaboflow (Browser)]
└─ JSONをフォームの各項目へ反映
Difyの設定
アプリの種類はワークフローを使用しています。
HTTPリクエストして、実行結果を返すだけの簡単なノード構成です。
また画面右上の「機能」から画像アップロードを許可してください。
Difyからコラボフローの添付ファイルを直接見に行けないので、ローカルアップロードを設定しています。
※コラボフロー側のJavascriptで添付ファイルをダウンロード、Difyへアップロードを行っています、後ほどご説明します
コラボフロー側の実装
添付ファイルダウンロード
Dify側で使用する添付ファイルを取得します。
やり方についてはこちらの記事で紹介していますので、よろしければご確認ください。
Difyへファイルアップロード
取得した添付ファイルをDify側にアップロードします。
const uploadForm = new FormData();
uploadForm.append('file', blob, file_name);
const uploadResponse = await fetch('https://api.dify.ricoh.com/v1/files/upload', {
method: 'POST',
headers: { 'Authorization': `Bearer ${apiKey}` },
body: uploadForm
});
const uploadData = await uploadResponse.json();
const difyFileId = uploadData.id;
Workflowを実行
いよいよワークフローの実行です。
読み込み対象のファイルの指定のところがややこしいので、ここはお作法だと思ってコピペしてください。
const workflowPayload = {
inputs: {},
response_mode: "blocking",
user: userId,
files: [{ transfer_method: "local_file", upload_file_id: difyFileId, type: "image" }]
};
const response = await fetch('https://api.dify.ricoh.com/v1/workflows/run', {
method: 'POST',
headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
body: JSON.stringify(workflowPayload)
});
const data = await response.json();
JSONをフォームの各項目へ反映
実行結果を反映します。
AI-OCRの実行結果JSONがDifyワークフローの実行結果JSONに含まれているため、ネストが深くなっています。
※データ成形してもよいのですが、そんなことのためにLLMを使うのもなあ…と思って今回はそのままにしました
また使用するAPIによってJSONの中身も変わると思いますので、ご自身の環境にあわせて変えてください。
if (data.data.outputs.body) {
const parsedBody = JSON.parse(data.data.outputs.body);
document.getElementById(`fid3_${i}`).value = parsedBody.date || '';
document.getElementById(`fid8_${i}`).value = parsedBody.amount || 0;
document.getElementById(`fid13_${i}`).value = parsedBody.tel || '';
document.getElementById(`fid5_${i}`).value = parsedBody.issuer || '';
document.getElementById(`fid14_${i}`).value = parsedBody.options.registration_number?.[0] || '';
} else {
console.warn(`行${i}の読み取りに失敗しました`);
}
実行結果
自分でいうのもなんですが…結構上手くいってると思います。
さいごに
今回はDifyのワークフローをAzure Functionsのようなサーバーレス関数的に使ってみました。
ブラウザ直叩きではCORSに阻まれるAPIでも、同一ネットワーク内のDifyからなら素直に呼べることができたので良かったです。


