8
n8n 中文网amn8n.com

使用Gemini AI将训练计划PDF转换为Hevy应用训练计划

高级

这是一个Personal Productivity, AI Summarization领域的自动化工作流,包含 16 个节点。主要使用 Set, Aggregate, FormTrigger, HttpRequest, ExtractFromFile 等节点。 使用Gemini AI将训练计划PDF转换为Hevy应用训练计划

前置要求
  • 可能需要目标 API 的认证凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "meta": {
    "instanceId": "42450f423595f391b7c323eb4191c0bc81df9f6de5483a12f34f76cb4146556c",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "9378321b-87f0-479f-8846-9e40a41c91ca",
      "name": "表单提交时",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -1240,
        -140
      ],
      "webhookId": "833ba56e-1dcb-45f7-9702-57800ff9095c",
      "parameters": {
        "options": {},
        "formTitle": "Upload Training Plan",
        "formFields": {
          "values": [
            {
              "fieldType": "file",
              "fieldLabel": "data",
              "multipleFiles": false,
              "requiredField": true,
              "acceptFileTypes": ".jpg, .png, .pdf, .jpeg"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "634600e6-0b0b-4051-ade7-e0b9f1e353ac",
      "name": "结构化输出解析器",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        228,
        80
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"routine\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\",\n          \"description\": \"The title of the routine\"\n        },\n        \"folder_id\": {\n          \"type\": \"number\",\n          \"nullable\": true,\n          \"default\": 1352963,\n          \"description\": \"The folder id the routine should be added to. Pass null to insert the routine into default 'My Routines' folder\"\n        },\n        \"notes\": {\n          \"type\": \"string\",\n          \"description\": \"Additional notes for the routine\"\n        },\n        \"exercises\": {\n          \"type\": \"array\",\n          \"description\": \"List of exercises in the routine\",\n          \"items\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"exercise_template_id\": {\n                \"type\": \"string\",\n                \"description\": \"The ID of the exercise template\"\n              },\n              \"superset_id\": {\n                \"type\": \"integer\",\n                \"nullable\": true,\n                \"description\": \"The ID of the superset\"\n              },\n              \"rest_seconds\": {\n                \"type\": \"integer\",\n                \"nullable\": true,\n                \"description\": \"The rest time in seconds (Pause). Never negative.\"\n              },\n              \"notes\": {\n                \"type\": \"string\",\n                \"nullable\": true,\n                \"description\": \"Additional notes for the exercise\"\n              },\n              \"sets\": {\n                \"type\": \"array\",\n                \"description\": \"Sets for the exercise\",\n                \"items\": {\n                  \"type\": \"object\",\n                  \"properties\": {\n                    \"type\": {\n                      \"type\": \"string\",\n                      \"enum\": [\"warmup\", \"normal\", \"failure\", \"dropset\"],\n                      \"description\": \"The type of the set\"\n                    },\n                    \"weight_kg\": {\n                      \"type\": \"number\",\n                      \"nullable\": true,\n                      \"description\": \"The weight in kilograms\"\n                    },\n                    \"reps\": {\n                      \"type\": \"integer\",\n                      \"nullable\": true,\n                      \"description\": \"The number of repetitions (wdhl.). Never negative.\"\n                    },\n                    \"distance_meters\": {\n                      \"type\": \"integer\",\n                      \"nullable\": true,\n                      \"description\": \"The distance in meters\"\n                    },\n                    \"duration_seconds\": {\n                      \"type\": \"integer\",\n                      \"nullable\": true,\n                      \"description\": \"The duration in seconds\"\n                    },\n                    \"custom_metric\": {\n                      \"type\": \"number\",\n                      \"nullable\": true,\n                      \"description\": \"A custom metric for the set. Currently used for steps and floors\"\n                    }\n                  }\n                }\n              }\n            },\n            \"required\": [\"exercise_template_id\", \"sets\"]\n          }\n        }\n      },\n      \"required\": [\"title\", \"exercises\"]\n    }\n  },\n  \"required\": [\"routine\"]\n}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "9cf95512-03fc-44ce-8a4c-bdf828927ac2",
      "name": "google/gemini-2.5-flash",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        60,
        80
      ],
      "parameters": {
        "model": "google/gemini-2.5-flash",
        "options": {}
      },
      "credentials": {
        "openRouterApi": {
          "id": "aCsTDT5LGS5D8Ndl",
          "name": "OpenRouter account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d13c6c4d-c938-4617-a679-5e4cd356168e",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1740,
        -200
      ],
      "parameters": {
        "color": 7,
        "width": 420,
        "height": 280,
        "content": "## 使用 AI 将任何锻炼计划扫描到 Hevy 应用中"
      },
      "typeVersion": 1
    },
    {
      "id": "d7a3ba9a-d86d-42bf-a6f9-5f30e699398a",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1100,
        -360
      ],
      "parameters": {
        "width": 260,
        "height": 180,
        "content": "此节点将传入的 PDF 文件转换为 Base64 文本字符串。此格式是在下一步中将文件内容发送到 AI 模型所必需的。"
      },
      "typeVersion": 1
    },
    {
      "id": "5b42918d-1446-4b91-b867-b9b0f771bfb7",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -800,
        -360
      ],
      "parameters": {
        "width": 300,
        "height": 180,
        "content": "此节点将 PDF 内容发送到 AI 模型以执行 OCR 并从文档中提取所有文本。"
      },
      "typeVersion": 1
    },
    {
      "id": "a137506d-75c3-45e6-8c78-8f6e0104914f",
      "name": "便签3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -440,
        -360
      ],
      "parameters": {
        "width": 300,
        "height": 180,
        "content": "这些节点从您的 Hevy 账户获取所有可用练习,并将它们合并为一个列表。此列表为 AI 提供了上下文,使其知道哪些练习是有效的。"
      },
      "typeVersion": 1
    },
    {
      "id": "c8ae0644-c339-4929-990c-ca99ab0247b1",
      "name": "便签说明4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        40,
        -420
      ],
      "parameters": {
        "width": 340,
        "height": 240,
        "content": "这是工作流的核心。"
      },
      "typeVersion": 1
    },
    {
      "id": "88dbdb21-34e3-4faf-a226-2b3633b1dc4c",
      "name": "## 为什么选择 4o 模型?👆",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        440,
        -340
      ],
      "parameters": {
        "content": "此最终节点从 AI 获取结构化数据,并向 Hevy API 发出 POST 请求,在您的账户中创建完整的锻炼日常。"
      },
      "typeVersion": 1
    },
    {
      "id": "0002347a-a9e3-43a3-be10-1773e3efd6cf",
      "name": "将 PDF 转换为 Base64",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        -1020,
        -140
      ],
      "parameters": {
        "options": {},
        "operation": "binaryToPropery"
      },
      "typeVersion": 1
    },
    {
      "id": "fcce2688-1ecc-4337-9737-3b92764ce718",
      "name": "通过 AI 从 PDF 提取文本",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -800,
        -140
      ],
      "parameters": {
        "url": "https://openrouter.ai/api/v1/chat/completions",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"model\": \"google/gemini-2.5-flash\",\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": [\n        {\n          \"type\": \"text\",\n          \"text\": \"Please perform OCR on this document and provide the full extracted content in your response\"\n        },\n        {\n          \"type\": \"image_url\",\n          \"image_url\": {\n            \"url\": \"data:image/jpeg;base64,{{ $json.data }}\"\n          }\n        }\n      ]\n    }\n  ]\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "hPXTjlgijwj0mJav",
          "name": "Header Auth account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "51ad34e9-0aaa-4ebe-adfa-6fd263cba56c",
      "name": "从 Hevy 获取练习列表",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -580,
        -140
      ],
      "parameters": {
        "url": "https://api.hevyapp.com/v1/exercise_templates",
        "options": {
          "pagination": {
            "pagination": {
              "parameters": {
                "parameters": [
                  {
                    "name": "page",
                    "value": "={{ $pageCount + 1 }}"
                  }
                ]
              },
              "maxRequests": 10,
              "requestInterval": 100,
              "limitPagesFetched": true,
              "paginationCompleteWhen": "receiveSpecificStatusCodes",
              "statusCodesWhenComplete": "404"
            }
          }
        },
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "pageSize",
              "value": "100"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "wmbngFqWDYUxVqMb",
          "name": "Hevy Auth"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "20ccb4bb-b0bd-4567-bb26-1015b3fa0105",
      "name": "格式化练习名称",
      "type": "n8n-nodes-base.set",
      "position": [
        -360,
        -140
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "85dd9d76-d527-43ce-bd36-955bb2a3b3f6",
              "name": "exercise_templates",
              "type": "array",
              "value": "={{ $json.exercise_templates }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "16434525-113f-4f93-b6df-05a096658087",
      "name": "合并练习列表",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        -140,
        -140
      ],
      "parameters": {
        "options": {
          "mergeLists": true
        },
        "fieldsToAggregate": {
          "fieldToAggregate": [
            {
              "fieldToAggregate": "exercise_templates"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "291e75d6-a372-4a15-ad66-92043cfc107b",
      "name": "匹配练习并构建日常锻炼",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        80,
        -140
      ],
      "parameters": {
        "text": "=# GOAL\nYour task is to analyze the provided OCR data of a workout routine, interpret its contents, and convert it into a structured JSON object. You must strictly adhere to the provided JSON schema.\n\n# CONTEXT\n- The OCR data is imperfect and may contain typos or formatting quirks.\n- You will be given a list of available exercises from an application database (`Base Exercise Data`).\n\n# INPUT DATA\n1.  **OCR Data:**\n    ```\n    {{ $('Extract Text from PDF via AI').item.json.choices[0].message.content }}\n    ```\n2.  **Base Exercise Data:**\n    ```json\n    {{ $json.exercise_templates.toJsonString() }}\n    ```\n\n# EXTRACTION RULES & SPECIFICS\nThis section contains specific instructions to guide the extraction process.\n\n- **Exercise Matching:** For each exercise name found in the OCR data, you MUST find the most semantically similar exercise in the `Base Exercise Data`. Use its `id` for the `exercise_template_id` in the final JSON. Do not invent new IDs.\n- **Default Folder:** If no folder is specified, use the default `folder_id` of `1352963`.\n- **Interpreting Sets:** A line like \"3x10 @ 50kg\" means 3 sets of 10 repetitions with 50 kilograms.\n- **Rest Times:** Look for terms like \"Pause,\" \"Rest,\" or time values (e.g., \"90s,\" \"1 min\") between exercises to determine the `rest_seconds`.\n- **Supersets:** If exercises are grouped with labels like \"A1, A2\" or listed together without a rest period, they are a superset. Assign them the same, incrementing `superset_id` (e.g., the first superset pair gets `superset_id: 1`, the next pair gets `superset_id: 2`).\n- **Tempo Information (optional):** Look for a 3 or 4-digit number (e.g., `4010`, `31X0`, `311`), often labeled \"Tempo\". If found for an exercise, capture this and include it in that exercise's `notes` field (e.g., `notes: \"Tempo: 4010\"`).\n\n\n\n# OUTPUT INSTRUCTIONS\n- Produce ONLY the final JSON object.\n- Do not include any explanatory text, markdown formatting, or apologies in your response.\n- The output must be a single, valid JSON object conforming to the schema.\n",
        "batching": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.7
    },
    {
      "id": "7d710a1d-7e86-4da1-bda1-741d8008cb02",
      "name": "创建 Hevy 日常锻炼",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        456,
        -140
      ],
      "parameters": {
        "url": "https://api.hevyapp.com/v1/routines",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ $json.output.toJsonString() }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "wmbngFqWDYUxVqMb",
          "name": "Hevy Auth"
        }
      },
      "typeVersion": 4.2
    }
  ],
  "pinData": {},
  "connections": {
    "On form submission": {
      "main": [
        [
          {
            "node": "Convert PDF to Base64",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Combine Exercise List": {
      "main": [
        [
          {
            "node": "Match Exercises & Structure Routine",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert PDF to Base64": {
      "main": [
        [
          {
            "node": "Extract Text from PDF via AI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Exercise Names": {
      "main": [
        [
          {
            "node": "Combine Exercise List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "google/gemini-2.5-flash": {
      "ai_languageModel": [
        [
          {
            "node": "Match Exercises & Structure Routine",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Match Exercises & Structure Routine",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Get Exercise List from Hevy": {
      "main": [
        [
          {
            "node": "Format Exercise Names",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Text from PDF via AI": {
      "main": [
        [
          {
            "node": "Get Exercise List from Hevy",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Match Exercises & Structure Routine": {
      "main": [
        [
          {
            "node": "Create Hevy Routine",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

高级 - 个人效率, AI 摘要总结

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
高级
节点数量16
分类2
节点类型9
难度说明

适合高级用户,包含 16+ 个节点的复杂工作流

作者
Julian Kaiser

Julian Kaiser

@jksr

Full Stack Developer turned AI & Automation Engineer, implementing intelligent solutions with custom code, LLMs & n8n. Use my link to book a free 30-minute call to discuss your AI challenges and see if my services might be a good fit for your needs.

外部链接
在 n8n.io 查看

分享此工作流