ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Botpress 中通过 Postmark 收发邮件:配置、Webhook 与线程会话机制详解

Botpress 中通过 Postmark 收发邮件:配置、Webhook 与线程会话机制详解 AI 应用后端【免费下载链接】botpressThe open-source hub to build deploy GPT/LLM Agents ⚡️项目地址https://gitcode.com/gh_mirrors/bo/botpress点击查看免费下载本篇技术指南以开源仓库 Botpress 的 Postmark 官方集成为主体围绕其 hub.md 文档展开系统讲解如何在 Botpress 中通过mail 频道接入 Postmark 收发邮件从 Server Token、From Email、Webhook Secret 三个核心配置项入手深入 Webhook 入站消息的鉴权与线程会话归组原理再到出站邮件的回复式发送与消息类型映射最后给出已知限制与源码级依据。读完本文你将掌握该集成的完整配置流程、线程会话的底层实现以及各消息类型在邮件中的实际渲染方式。集成概览一条基于 mail 频道的双向邮件通道Postmark 集成定义于 integration.definition.ts其核心职责是通过 Postmark 收发电子邮件Send and receive emails through Postmark。它不依赖任何 Botpress 之外的聊天频道而是暴露一个名为mail的频道见 integration.definition.tsBot 通过该频道即可把邮件作为普通会话消息处理。集成整体代码结构如下目录 integrations/postmarksrc/index.ts —— 集成主体注册/注销逻辑、入站 webhook 处理、出站sendEmail动作src/messages.ts —— mail 频道各消息类型的发送处理器src/send-email.ts —— 底层邮件发送、线程头In-Reply-To / References构造src/inbound-webhook.ts —— Postmark 入站 webhook 载荷的 Zod 校验 schemaintegration.definition.ts —— 集成配置、动作、频道与实体定义。集成在安装时还通过 package.json 依赖两个 Botpress 接口proactive-conversation与proactive-user用于支持从 Bot 侧主动创建会话和用户详见 proactive-conversation/interface.definition.ts 与 proactive-user。这正是机器人主动发起的会话能力的接口基础。配置项三项配置即可启用根据 hub.md 的配置表集成共需要或可选三个配置字段其定义可在 integration.definition.ts 中逐一核对字段说明定义要点源码Server Token你的 Postmark Server API Token在 Postmark 服务器的 API Tokens 页签中获取必填sdk.z.string().secret().min(1)以密文形式存储From Email默认发件人邮箱地址必须是 Postmark 中已验证的发送签名Sender Signature必填sdk.z.string().email().min(1)Webhook Secret可选。用于校验入站 webhook 的共享密钥可选sdk.z.string().secret()与 webhook URL 拼接使用这三个字段全部在集成安装时由用户在 Botpress 控制台中填写。其中Server Token与Webhook Secret均被标记为.secret()意味着它们会作为敏感配置处理不会以明文出现在集成运行时上下文中可被 Bot 逻辑读取的普通位置之外。安装时的自动校验与钩子配置源码级细节从 src/index.ts 可以看到集成在register阶段并非简单保存配置而是做了三件事校验 Token用pm.ServerClient(ctx.configuration.serverToken)调用getServer()若返回 401/403则抛出Invalid Postmark Server Token. Please check your configuration.其他错误则包装为Failed to verify Postmark Server Token。检查冲突如果 Postmark 服务器上已配置了指向其他地址的 Inbound Hook URL会抛出Postmark server already has an Inbound Hook URL set to ...要求先在 Postmark 控制台清空再安装。自动设置 Inbound Hook URL将 Postmark 服务器的入站钩子指向集成自身的 webhook URL若设置了 Webhook Secret则自动追加?secret...。若 URL 已相同则直接跳过。相应地unregister阶段会读取当前服务器配置仅当 Inbound Hook URL 与集成写入的 URL 一致时才将其清空避免误删他人配置。接收邮件入站 Webhook 与线程会话归组配置入站 Webhook按 hub.md 的说明在 Postmark 控制台将Inbound webhook指向集成安装后生成的 webhook URL入站邮件就会自动创建 Botpress 会话与消息。得益于register阶段的自动配置只要 Server Token 有效且服务器未占用其他 Inbound Hook URL这一步通常无需手工填写。如果配置了Webhook Secret需要将其以 query 参数形式拼接到 webhook URL 上https://your-webhook-url?secretYOUR_SECRET请求鉴权恒定时间比较在 src/index.ts 的handler中若配置了webhookSecret集成会从 query 参数取出secret与配置值通过 Node 的timingSafeEqual做长度与内容的恒定时间比较不匹配直接返回401 Unauthorized。这避免了普通字符串比较带来的时序侧信道问题。载荷校验与消息落库webhook 载荷首先经 src/inbound-webhook.ts 中基于 Zod 定义的postmarkInboundWebhookSchema校验非法载荷返回400。schema 覆盖了 Postmark 入站事件的典型字段From/FromFull、To/ToFull、Cc/CcFull、Bcc/BccFull、Subject、MessageID、TextBody/HtmlBody、Headers与Attachments等。校验通过后src/index.ts集成会为发件人及所有收件人To/Cc/Bcc创建或复用用户用户以emailAddress标签区分见 integration.definition.ts依据邮件头计算rfcMessageId与threadRootMessageId以threadRootMessageId为判别标签创建会话getOrCreateConversationdiscriminateByTags: [threadRootMessageId]写入一条 text 消息正文取TextBody为空时回退HtmlBody并将subject、cc、bcc、spamScore等写入消息标签逐个处理Attachments先经uploadAttachment上传到 Botpress 文件存储10MB 上限见 src/index.ts再按 Content-Type 映射为 image/audio/video/file 消息映射函数见 src/index.ts文件名会被sanitizeFilename清洗。线程会话如何归组这是 hub.md 中最值得展开的原理。文档指出hub.md会话以邮件线程为键由References与In-Reply-To头推断线程中的第一封邮件创建新会话共享同一线程根 Message-ID 的回复加入同一会话主题保留在每条消息的subject标签上。源码将这一逻辑落实为extractParentHeaderssrc/index.ts优先取References头的第一个 Message-ID 作为线程根否则取In-Reply-To头作为父邮件 ID。extractThreadRootsrc/index.tsroot ?? parent ?? fallbackId其中 fallbackId 即本邮件的 Message-ID——即没有任何引用信息的第一封邮件以自身作为新线程根。getOrCreateConversation以threadRootMessageId为唯一判别键同一线程根的邮件必然落入同一会话。发送邮件以回复为中心的会话模型仅支持回复式发送hub.md 明确hub.md集成只向由入站邮件创建的会话发送回复邮件Bot 主动发起、不挂接任何入站邮件的会话不被支持。这一限制在 src/send-email.ts 中有硬性校验发送前必须存在postmarkEmailAddress与userEmailAddress两个会话标签否则抛出Cannot send email: conversation is missing the postmarkEmailAddress tag...。这两个标签正是在入站 webhook 处理时写入会话的见 src/index.ts因此先有入站邮件、后有出站回复是数据模型上的必然。线程头的正确构造为了保证回复在收件人邮箱中仍然归属原线程src/send-email.ts 会通过collectEmailThread分页拉取该会话下所有带emailMessageId标签的消息按时间排序得到邮件 ID 列表生成新的 RFC 5322 Message-IDgenerateRfcMessageId格式为UUID发件域名见 src/send-email.ts以最后一封邮件 ID作为In-Reply-To以全部历史邮件 ID 拼接作为References头。这样就确保了回复的回复能够沿着References链找到最初的线程根与入站归组逻辑取 References 首元素严格对称。sendEmail 动作Bot 主动开新线程的唯一入口除 mail 频道外集成还暴露sendEmail动作integration.definition.ts允许 Bot 以开新线程的方式向指定邮箱发送首封邮件输入含userEmailAddress必填、userName、cc/bcc对象数组{ email, name? }、subject、text必填最小长度 1以及conversationInformation可选含rootEmailId/lastEmailId。其内部流程src/index.ts先getOrCreateUser再尝试resolveExistingConversation——若提供了conversationInformation且能找到已存在会话则在该会话内按回复发送若提供了线索但找不到会话抛出No Botpress conversation found for thread root ...若无任何线索则以自定义 Message-ID 发送首封邮件并创建以threadRootMessageId为新线程根的新会话。输出为{ conversationId }。同时集成通过proactive-conversation接口扩展出getOrCreateReplyThreadConversation动作通过proactive-user接口扩展出getOrCreateUser动作见 integration.definition.ts实现均在 src/index.ts前者根据rootEmailId/lastEmailId解析既有会话后者按邮箱幂等创建/复用用户。消息类型与邮件渲染映射hub.md 列出 mail 频道支持的全部标准消息类型hub.md其实现全部位于 src/messages.ts且这些类型在 integration.definition.ts 中通过扩展 Botpress 默认消息 schema 统一追加cc、bcc、subject三个可选字段消息类型邮件中的渲染方式源码位置Text作为邮件正文发送纯文本经textToHtml转义换行后同时作为 HtmlBodymessages.tsImage / Audio / Video / File作为邮件附件发送先fetchAsAttachment下载远程 URL30 秒超时、10MB 上限正文显示(attachment: 文件名)占位messages.tsLocation渲染为 Google Maps 链接https://www.google.com/maps?qlat,lng标题/地址按需加入messages.tsCard标题、副标题、动作链接仅 http/https URL 会被渲染为可点击链接其他动作仅显示文本标签可选图片作为附件messages.tsCarousel多个卡片之间以hrHTML/---纯文本分隔messages.tsChoice / Dropdown渲染为编号列表1. 选项messages.tsBloc混合内容文本、图片、音频、视频、文件、位置合并为一封邮件messages.ts几个值得注意的实现细节附件文件名根据 URL 路径最后一段推断无扩展名时按 Content-Type 查表补全如image/jpeg → jpg、application/pdf → pdf映射表见 messages.ts。附件下载失败时如卡片/轮播中的图片集成采用尽力而为策略tryFetchAttachment记录 warning 并跳过该附件而不是让整封邮件发送失败见 messages.ts。所有类型都支持可选的cc、bcc、subject字段收件人格式化formatRecipients会把{name, email}渲染为name email形式见 send-email.ts。文本正文经escapeHtml转义、、、后把换行替换为br生成 HTML 版本见 messages.ts。已知限制与运行前提hub.md 在末尾明确了集成当前唯一的限制hub.md集成不追踪投递事件退信、打开、点击。此外结合上述源码分析还可以补充以下与使用直接相关的边界条件均为实现事实仅回复式发送出站邮件只能发往由入站邮件创建的会话新线程必须通过sendEmail动作由 Bot 主动开启附件大小上限 10MB入站上传与出站下载均受 10MB 上限约束见 src/index.ts 与 messages.ts入站超限附件会被拒绝并记录 warning安装前置条件Postmark 服务器不能已配置其他 Inbound Hook URL否则安装会失败并要求先在 Postmark 控制台清理运行时依赖ServerToken必须对安装该集成时的目标 Postmark Server 有效fromEmail必须是 Postmark 已验证的发送签名地址构建方式集成使用 Botpress CLI 构建脚本为bp add -y bp build见 package.json依赖官方postmarknpm 包^4.0.7。小结一条以线程为会话的邮件闭环Postmark 集成的设计核心可以概括为一句话把邮件线程等价为 Botpress 会话。入站方向通过References/In-Reply-To头推导线程根并以threadRootMessageId标签归组会话出站方向在会话内按历史邮件 ID 构造In-Reply-To/References头维持线程。整套闭环入站 webhook 鉴权 → 会话/用户创建 → 消息落库 → 出站回复发送在 src/index.ts 与 src/messages.ts 中均可逐行验证为在 Botpress 中构建基于邮件的客服、通知或工单式 Agent 提供了可直接复用的通道能力。赞分享AI 应用后端【免费下载链接】botpressThe open-source hub to build deploy GPT/LLM Agents ⚡️项目地址https://gitcode.com/gh_mirrors/bo/botpress点击查看免费下载相关推荐GravitySlider 项目推荐GravitySlider 项目推荐 项目基础介绍和主要编程语言 GravitySlider 是一个轻量级的动画流布局库专为 UICollectionView后端网络运维数据可视化Open CoDesign Decompose to UI Kit揭秘12项布尔Rubric如何验证AI设计视觉一致性Open CoDesign Decompose to UI Kit揭秘12项布尔Rubric如何验证AI设计视觉一致性 Open CoDesign open人工智能AI 应用桌面应用Apereo CAS SSO 会话通知SSO Notifications配置指南邮件与短信模板详解Apereo CAS SSO 会话通知SSO Notifications配置指南邮件与短信模板详解 在 Apereo CAS 中当用户完成一次成功的登录后端认证鉴权单点登录上一篇Helion与PyTorch集成教程无缝加速你的机器学习模型训练下一篇Vue.js 源码分析$emit 方法与事件冒泡机制创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表