ChatGPT销售找线索AI 评分 · 待评分AI 辅助编辑·未发现明显提示词注入风险n8n.io

用 Telegram 语音或文字触发 Apollo 线索抓取,经 GPT-4 解析后存入 Supabase

输入:Telegram 语音/文字指令 → 处理:Whisper 转录 + GPT 提取搜索参数 → Apify Apollo Scraper 抓取 → 验证并去重 → 输出:Supabase 新线索表 + Telegram 回执

经验丰富步骤流程提示词
给谁
增长黑客、SDR 团队、创始人——希望通过 Telegram 语音或文字指令自动获取并整理潜在客户线索
你会得到
将自然语言指令转化为经过验证、去重的结构化线索,直接写入 Supabase 数据库,并通过 Telegram 返回新增数量
你需要
n8n · telegram · apify · supabase · postgres

硬约束

需要 n8n v0.231+(自托管或 Cloud)、Telegram Bot Token、OpenAI API Key、Apify 账户及 Apollo-io Scraper Actor、Supabase 项目凭证(或替换为 Airtable/Sheets/Postgres)。凭证类型:telegramApi、openAiApi、apifyApi、postgres。workflow.json 可直接导入 n8n。

他们做了什么

作者 diagopl 在 n8n 上发布了一个官方模板(2025-07-02),展示如何通过 Telegram Bot 接收语音或文字指令,利用 OpenAI Whisper 和 GPT-4.1-nano 解析出搜索参数(地点、行业、职位),经 Code 节点生成 Apollo.io 搜索 URL,再通过 Apify 的 Apollo-io Scraper Actor 抓取最多 500 条联系人,过滤仅保留验证邮箱,与 Postgres 已有记录去重后,写入 Supabase 表 Leads_n-mail,最后通过 Telegram 返回新增数量。模板附带 sticky note 说明目标用户、设置步骤、自定义选项及所需凭证。

效果如何

作者报告称该流程可实现“语音到数据库 30 秒内完成”“95%+ 验证邮箱”“单次请求处理 500+ 线索”“100% 免手动操作”。这些均为作者自述(author_report),本站未实测验证。

值得知道

1. 模板中 Confirmation message 文本提到 'Google Sheet',但实际数据写入 Supabase 表 Leads_n-mail,属于模板遗留措辞,需用户自行修正。2. Chat ID 在模板中硬编码为 123456789,必须替换。3. Apify token 在模板中可能硬编码,建议改为环境变量。4. Keep only the new leads 节点的 mergeByFields 为空对象 {},去重逻辑可能无法正确匹配 emailAddress,需用户补全。5. Create rows with new leads 节点未映射 seniority 和 Number 字段,与 sticky-notes 声明的表结构不一致。6. businessIndustry 字段表达式引用了不存在的节点 'Apollo Scraper'(实际为 'Run an Actor'),将返回 null,需修正为正确节点引用。7. 来源未提供 workflow 运行日志或实际抓取样本,数据质量声明(95% 验证率)为作者自述。8. 若 Apollo Scraper Actor 参数或 Apify 定价变化,可能影响可用性。9. 可替换存储目标为 Airtable、Google Sheets、HubSpot 等,但需自行调整节点配置。

n8n 工作流模板

结构已检查 · 未实际运行

下载后在 n8n 选择“Import from File”,或复制 JSON 后粘贴到编辑器。先配置自己的账号,再用测试数据运行;模板默认未启用。

配置与测试清单

需要绑定的凭证

  • Download File1 节点:绑定Telegram API 凭证。
  • Transcribe1 节点:绑定OpenAI API 凭证。
  • OpenAI Chat Model1 节点:绑定OpenAI API 凭证。
  • Select already scraped mails 节点:绑定Postgres 凭证。
  • Confirmation message 节点:绑定Telegram API 凭证。
  • User message 节点:绑定Telegram API 凭证。
  • Run an Actor 节点:绑定apifyApi 凭证。

需要替换的配置

  • 源模板来自 n8n 公开库 #5611(约 28 个节点)。导入后先保持未启用,核对触发器、表达式与外部 API 端点。
  • Sticky Note 中的说明仅供参考;按自己的账号、表结构或频道 ID 替换占位配置。

测试输入与预期结果

  • 在测试环境手动执行一次主路径,确认每个需凭证的节点已连接且无鉴权错误。
  • 用一条合成/脱敏样例数据跑通,核对输出字段与下游写入目标,再考虑生产启用。

模板处理说明

  • 已移除原作者凭证绑定、webhookId 与执行数据,工作流设为未启用;节点、连线与原文提示词保持原样。未在 n8n 中实际运行。
  • 未改业务逻辑;运行前请自行核对密钥、配额与隐私合规。

模板获取日期: 2026-10-24

步骤

  1. 设置 Telegram 触发并接收语音或文字消息

    在 n8n 中导入 workflow 后,确认 Telegram Trigger 节点(User message)已配置 Bot Token。向该 Bot 发送文字消息或语音消息。若是语音,流程会经 Download File 节点获取音频文件;若是文字,直接进入下一步。

  2. 用 Whisper 转录语音,并由 GPT 提取结构化搜索参数

    语音消息经 OpenAI Whisper 节点(Transcribe1)转录为文字;文字消息直接传入。随后,AI Agent 节点(Scraper agent)使用 GPT-4.1-nano 模型,根据 systemMessage 将自然语言指令解析为固定格式的 JSON 数组。该 JSON 包含 location、business、job_title 三个字段,值需为小写、空格替换为加号。Structured Output Parser 节点约束输出格式,Simple Memory 提供对话上下文。Generate query payload 节点将 JSON 包装为 {"query": {{ $json.output }}}。

    运行提示词 · 来源原文。Scraper agent 节点的 systemMessage 字段(AI Agent 节点 → Options → System Message)

    =# Role
    You are LeadChat. Your single job is to return a **JSON array of one object** that tells the sub-workflow what to scrape.
    
    # Required JSON schema
    ```json
    [
      {
        "location": ["city+country"],      // lowercase, spaces→+
        "business": ["industry"],          // lowercase, words→+
        "job_title": ["role"]              // lowercase, words→+
      }
    ]
  3. 生成 Apollo 搜索 URL 并调用 Apify Scraper 抓取线索

    Create URL 节点(Code 节点)读取 {"query": ...} 结构,拼接 Apollo.io 人物搜索 URL,参数包括 personTitles[]、personLocations[]、qOrganizationKeywordTags[] 等。随后 Run an Actor 节点调用 Apify 的 Apollo-io Scraper Actor(ID: jljBwyyQakqrL1wae),传入生成的 URL,设置 totalRecords=500、getPersonalEmails=true、getWorkEmails=true、timeout=10000、waitForFinish=60。

    运行提示词 · 来源原文。Create URL 节点的 JS Code 字段(Code 节点 → JavaScript)

    /************************************************************
     * Build Apollo People-search URL from parser output
     * Handles both shapes:
     *   { query: [ { … } ] }      ← array
     *   { query: { … } }          ← object
     ************************************************************/
    
    // 1. Obtener el JSON que llega del nodo anterior
    const inputData = $json;
    
    // 2. Normalizar para que paramsData siempre sea un objeto
    let paramsData;
    
    if (Array.isArray(inputData.query)) {
      // Caso antiguo: query es un array
      paramsData = inputData.query[0];
    } else if (inputData.query) {
      // Caso nuevo: query es un objeto
      paramsData = inputData.query;
    } else {
      throw new Error('Falta la propiedad "query" en el input');
    }
    
    // 3. URL base de Apollo (interfaz web)
    //    Para llamar a la API REST cambia a https://api.apollo.io/v1/mixed_people/search
    const baseURL = 'https://app.apollo.io/#/people';
    
    // 4. Construir los parámetros dinámicos
    const queryParts = [
      'sortByField=recommendations_score',
      'sortAscending=false',
      'page=1',
    ];
    
    // Helper para arrays → personTitles[]=ceo
    const addArrayParams = (paramName, values) => {
      values.forEach((val) => {
        const decoded = val.replace(/\+/g, ' ');          // “barcelona+spain” ⇒ “barcelona spain”
        queryParts.push(`${paramName}[]=${encodeURIComponent(decoded)}`);
      });
    };
    
    // job_title → personTitles[]
    if (Array.isArray(paramsData.job_title)) {
      addArrayParams('personTitles', paramsData.job_title);
    }
    
    // location → personLocations[]
    if (Array.isArray(paramsData.location)) {
      addArrayParams('personLocations', paramsData.location);
    }
    
    // business → qOrganizationKeywordTags[]
    if (Array.isArray(paramsData.business)) {
      addArrayParams('qOrganizationKeywordTags', paramsData.business);
    }
    
    // campos estáticos
    queryParts.push('includedOrganizationKeywordFields[]=tags');
    queryParts.push('includedOrganizationKeywordFields[]=name');
    
    // 5. Montar la URL final
    const finalURL = `${baseURL}?${queryParts.join('&')}`;
    
    // 6. Devolver resultado
    return [{ json: { finalURL } }];
  4. 提取字段、过滤仅验证邮箱,并与已有记录去重

    Apify 返回的数据经 Extract Info 节点映射为统一字段:firstName、lastName、emailAddress、linkedInURL、jobTitle、companyName、location、country、websiteURL、businessIndustry、seniority、Number、emailStatus。Only Keep Verified Emails 节点过滤 emailStatus='verified' 的条目。Select already scraped mails 节点从 Postgres 的 Leads_n-mail 表读取已有 emailAddress。Keep only the new leads 节点(Compare Datasets)的 mergeByFields 在模板中为空对象 {},去重匹配逻辑可能无法按预期工作,需用户自行修正。

  5. 将新线索插入 Supabase 数据库

    Create rows with new leads 节点(Supabase)将去重后的新线索写入表 Leads_n-mail。字段映射使用上一步提取的变量。注意:businessIndustry 字段的表达式引用了不存在的节点 'Apollo Scraper'(实际节点名为 'Run an Actor'),该表达式将返回 null,需用户修正。另,模板 sticky-notes 声明的列包括 seniority 和 number,但插入节点未映射这两个字段,也属于模板缺陷。需提前在 Supabase 中创建对应列。

  6. 限制数量并通过 Telegram 发送确认消息

    Limit 节点控制最终回执数量。Set Telegram message 节点构造文本。Confirmation message 节点(Telegram)向指定 chatId 发送该消息。注意:模板中 chatId 硬编码为 123456789,需替换为实际聊天 ID;消息文本中的 'Google Sheet' 为模板遗留措辞,实际写入的是 Supabase 表。

    运行提示词 · 来源原文。Confirmation message 节点的 Text 字段(Telegram 节点 → Message → Text)及 Set Telegram message 节点的 assignments[0].value

    ={{ $input.all().length }} new contacts have been added to the Google Sheet!

可复制提示词

搭建指导 · 本站建议版本。交给搭建助手,先确认输入和权限

这一段是提示词,页面不会在这里插入广告。

你是一个 n8n 工作流搭建助手。用户想要复现一个 Telegram 驱动的 AI 线索抓取流程。请按以下顺序协助:1) 确认用户已准备 n8n 实例及所需凭证(Telegram Bot Token、OpenAI API Key、Apify API Token、Supabase/Postgres 凭证);2) 指导导入 workflow.json;3) 逐节点检查凭证配置,特别是 Apollo Scraper 的 Actor 参数与 Supabase 表名;4) 提醒修正模板缺陷:补全 Keep only the new leads 的 mergeByFields、修正 businessIndustry 的节点引用、补全 seniority/number 字段映射;5) 建议先用文字消息测试,再测试语音消息;6) 提醒将硬编码的 chatId 和 Apify token 改为环境变量或凭证引用。

搭建前请确认所有 API 凭证已配置,并先在 Supabase 创建 Leads_n-mail 表及对应列。特别注意修正模板中缺失的 mergeByFields 和错误的节点引用。

来源

AI-powered lead generation with Apollo, GPT-4, and Telegram to database · diagopl · n8n.io · 2025-07-02

留言与反馈

试过这个方法吗?分享效果、遇到的问题或改进建议。留言审核后公开,请勿填写敏感信息。

正在加载…

    相关用例