This workflow follows the Form Trigger → HTTP Request recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "OCR",
"nodes": [
{
"parameters": {
"formTitle": "\u4e0a\u4f20\u56fe\u7247",
"formFields": {
"values": [
{
"fieldLabel": "images",
"fieldType": "file",
"acceptFileTypes": ".jpg,.png"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.formTrigger",
"typeVersion": 2.2,
"position": [
-480,
220
],
"id": "7c3cd707-4b45-4775-aab2-baf293e91557",
"name": "Batch Image Upload"
},
{
"parameters": {
"jsCode": "let results = [];\nfor (const item of $input.all()) {\n // \u83b7\u53d6 binary \u4e2d\u7684\u6240\u6709\u6587\u4ef6\n for (const [key, binaryData] of Object.entries(item.binary)) {\n results.push({\n json: {\n ...item.json,\n currentFile: key, // \u6dfb\u52a0\u5f53\u524d\u5904\u7406\u7684\u6587\u4ef6\u6807\u8bc6\n filename: binaryData.fileName || key,\n fileSize: binaryData.fileSize\n },\n binary: { \n data: binaryData // \u53ea\u5305\u542b\u5f53\u524d\u6587\u4ef6\u7684 binary \u6570\u636e\n }\n });\n }\n}\nreturn results;"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-240,
220
],
"id": "05427da1-d4bd-4793-af7e-6e90e68d6605",
"name": "Split Files to Items"
},
{
"parameters": {
"content": "### \u5c06\u591a\u4e2a\u6587\u4ef6\u5206\u5272\u6210\u72ec\u7acb\u7684 items \n",
"height": 240,
"width": 280,
"color": 4
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-320,
160
],
"id": "0808e9fb-7da4-45c1-8429-986e3fed6312",
"name": "Sticky Note"
},
{
"parameters": {
"method": "POST",
"url": "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=<redacted-credential>",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"contents\": [\n {\n \"parts\": [\n {\n \"text\": \"\u8bf7\u63d0\u53d6\u56fe\u7247\u4e2d\u7684\u5168\u90e8\u6587\u672c\u5185\u5bb9\uff0c\u4e25\u683c\u4fdd\u6301\u539f\u6709\u683c\u5f0f\u548c\u6392\u7248\u3002\u8981\u6c42\uff1a\u4fdd\u6301\u539f\u59cb\u7684\u884c\u95f4\u8ddd\u3001\u6bb5\u843d\u7ed3\u6784\u548c\u7f29\u8fdb\uff0c\u4fdd\u7559\u8868\u683c\u3001\u5217\u8868\u7b49\u7279\u6b8a\u683c\u5f0f\uff0c\u4e0d\u6dfb\u52a0\u4efb\u4f55\u89e3\u91ca\u3001\u8bf4\u660e\u6216\u989d\u5916\u7b26\u53f7\uff0c\u5982\u9047\u4e0d\u6e05\u6670\u6587\u5b57\u7528[?]\u6807\u8bb0\uff0c\u76f4\u63a5\u8f93\u51fa\u63d0\u53d6\u7ed3\u679c\u65e0\u9700\u524d\u8a00\u540e\u8bed\u3002\"\n },\n {\n \"inline_data\": {\n \"mime_type\": \"image/jpeg\",\n \"data\": \"{{ $('Convert to Base64').item.json.data }}\"\n }\n }\n ]\n }\n ],\n \"generationConfig\": {\n \"temperature\": 1,\n \"maxOutputTokens\": 65536\n }\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
820,
100
],
"id": "075ad19f-3fc2-4389-8103-16321467afa2",
"name": "Gemini OCR API"
},
{
"parameters": {
"content": "## \ud83d\udccb \u6279\u91cf OCR \u5904\u7406\u6d41\u7a0b\n\ud83d\udd04 \u5bf9\u6bcf\u5f20\u4e0a\u4f20\u7684\u56fe\u7247\u6267\u884c\uff1a\n1. \u8f6c\u6362\u4e3a Base64 \u683c\u5f0f\n2. \u53d1\u9001\u81f3 Google Gemini API\n3. \u8bc6\u522b\u5e76\u63d0\u53d6\u6587\u672c\u5185\u5bb9\n4. \u6536\u96c6 OCR \u7ed3\u679c\u540c\u6b65\u5230\u98de\u4e66\u591a\u7ef4\u8868\u683c\n\n\ud83d\udca1 \u5faa\u73af\u4f1a\u81ea\u52a8\u5904\u7406\u6240\u6709\u4e0a\u4f20\u7684\u56fe\u7247\u6587\u4ef6\n\n",
"height": 480,
"width": 1240,
"color": 5
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
0,
-20
],
"id": "5932d166-03f0-4246-9ca9-94efda33b326",
"name": "Sticky Note1"
},
{
"parameters": {
"operation": "binaryToPropery",
"options": {
"keepSource": "both"
}
},
"type": "n8n-nodes-base.extractFromFile",
"typeVersion": 1,
"position": [
380,
220
],
"id": "7a790c83-a782-4dde-8eb9-a03ecce1e9e8",
"name": "Convert to Base64"
},
{
"parameters": {
"resource": "bitable",
"operation": "bitable:table:record:add",
"app_toke": "VMoXbh9aMav6L4sWeRkcpmfynLd",
"table_id": "tblhoyqA6BGOLnVH",
"body": "={\n \"fields\":{\n \"\u6587\u4ef6\u540d\": \"{{ $('Convert to Base64').item.json.filename }}\",\n \"\u4e0a\u4f20\u65f6\u95f4\":\"{{ $now.format('yyyy-MM-dd HH:mm:ssa') }}\",\n \"\u8bc6\u522b\u6587\u672c\": {{ JSON.stringify($json.candidates[0].content.parts[0].text) }},\n \"\u539f\u56fe\u7247\": [\n {\n \"file_token\": \"{{ $('Upload to Feishu Drive').item.json.data.file_token }}\"\n }\n ],\n \"\u6587\u4ef6\u5927\u5c0f\": \"{{ $('Convert to Base64').item.json.fileSize }}\"\n }\n}"
},
"type": "n8n-nodes-feishu-lite.feishuNode",
"typeVersion": 1,
"position": [
1020,
220
],
"id": "1c7f77ce-f795-42f2-b18b-9bc6b47ccd67",
"name": "Save to Feishu Sheet",
"credentials": {
"feishuCredentialsApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"options": {}
},
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [
80,
220
],
"id": "ecd34bd3-a7ed-4bff-a107-398fb69a496d",
"name": "Process Each Image"
},
{
"parameters": {
"resource": "space",
"operation": "space:upload",
"parent_type": "bitable_image",
"parent_node": "VMoXbh9aMav6L4sWeRkcpmfynLd",
"fileFieldName": "=data",
"file_name": "={{ $json.filename }}"
},
"type": "n8n-nodes-feishu-lite.feishuNode",
"typeVersion": 1,
"position": [
600,
220
],
"id": "b2d906a1-12cd-4b54-9be5-a66d3dc5cf0d",
"name": "Upload to Feishu Drive",
"credentials": {
"feishuCredentialsApi": {
"name": "<your credential>"
}
}
}
],
"connections": {
"Batch Image Upload": {
"main": [
[
{
"node": "Split Files to Items",
"type": "main",
"index": 0
}
]
]
},
"Split Files to Items": {
"main": [
[
{
"node": "Process Each Image",
"type": "main",
"index": 0
}
]
]
},
"Process Each Image": {
"main": [
[],
[
{
"node": "Convert to Base64",
"type": "main",
"index": 0
}
]
]
},
"Convert to Base64": {
"main": [
[
{
"node": "Upload to Feishu Drive",
"type": "main",
"index": 0
}
]
]
},
"Upload to Feishu Drive": {
"main": [
[
{
"node": "Gemini OCR API",
"type": "main",
"index": 0
}
]
]
},
"Gemini OCR API": {
"main": [
[
{
"node": "Save to Feishu Sheet",
"type": "main",
"index": 0
}
]
]
},
"Save to Feishu Sheet": {
"main": [
[]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "4e159621-7ad1-4be5-9924-d2229c2eceac",
"meta": {
"templateCredsSetupCompleted": true
},
"id": "wXDFVRWQLafMQwgu",
"tags": [
{
"createdAt": "2025-07-15T07:28:23.497Z",
"updatedAt": "2025-07-15T07:28:23.497Z",
"id": "JJ7MXl6bL0HM32F4",
"name": "Gemini"
},
{
"createdAt": "2025-07-15T07:28:23.514Z",
"updatedAt": "2025-07-15T07:28:23.514Z",
"id": "V1PmSlniEGIv9M3I",
"name": "OCR"
}
]
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
feishuCredentialsApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
OCR. Uses formTrigger, httpRequest, n8n-nodes-feishu-lite. Event-driven trigger; 9 nodes.
Source: https://github.com/FlyAIBox/LLM-101/blob/28992f0efcf947b06db3d2a7010c2a22484fe6a0/chapter07-llm-n8n/template/feishu/OCR-FeiShu.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow allows you to import any workflow from a file or another n8n instance and map the credentials easily. A multi-form setup guides you through the entire process At the beginning you have t
[n8n] Advanced URL Parsing and Shortening Workflow - Switchy.io Integration. Uses splitInBatches, stickyNote, httpRequest, html. Event-driven trigger; 56 nodes.
[](https://youtu.be/c7yCZhmMjtI)
N8n recently introduced folders and it has been a big improvement on workflow management on top of the tags.
This workflow automates the creation of press releases for music artists releasing a new single. Upload your MP3, fill in basic info, and receive a publication-ready press release saved as a Google Do