Activepieces ClickSend 集成实战:SMS/MMS 发送、联系人管理与入站短信触发的实现解析
【免费下载链接】activepiecesAI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents项目地址: https://gitcode.com/GitHub_Trending/ac/activepieces
本篇以 Activepieces 仓库中 ClickSend 集成件(piece)的官方说明文档为骨架,结合packages/pieces/community/clicksend目录下的真实源码,完整讲解该集成如何配置 Basic 认证、如何实现 9 个动作(Actions)与 1 个触发器(Trigger)、底层统一的 API 调用层如何工作,以及它面向 AI Agent 的幂等性元数据设计。读完后你既能看懂 ClickSend 集成在 Activepieces 工作流中"能做什么",也能从源码级弄清它"是怎么做的"。
一、集成件定位与整体结构
ClickSend 是一个云端消息平台,提供 SMS、MMS、语音、邮件等消息发送能力。Activepieces 仓库中的这个集成件让自动化构建者和 AI Agent 可以发送消息、管理联系人、并监听通信状态。其包名为@activepieces/piece-clicksend(见 package.json),声明minimumSupportedRelease: '0.36.1',并在 index.ts 中注册到PieceCategory.COMMUNICATION分类下。
从源码结构看,该件由三部分组成:
- 入口:src/index.ts 定义认证(
clicksendAuth)并调用createPiece汇总 9 个内置动作 + 1 个自定义 API 调用动作 + 1 个触发器; - 公共层:src/lib/common/index.ts 提供统一的
callClickSendApiHTTP 封装和三个可复用的下拉属性(联系人列表、联系人 ID、发件人); - 动作与触发器:
src/lib/action/下 9 个动作文件一一对应 README 中列出的功能,src/lib/trigger/new-incoming-sms.ts实现入站短信触发器。
packages/pieces/community/clicksend/ ├── README.md ├── package.json # @activepieces/piece-clicksend └── src/ ├── index.ts # 认证 + createPiece 注册 ├── i18n/ # 10 种语言翻译 └── lib/ ├── common/index.ts # callClickSendApi + 公共下拉属性 ├── action/ # 9 个动作 └── trigger/new-incoming-sms.ts二、认证配置:BasicAuth 与凭据校验
README 声明使用 ClickSend 需要两个凭据:Username(ClickSend 用户名)与API Key(API 密钥)。在源码中,这两项通过框架的PieceAuth.BasicAuth实现,即用户名 + API Key 会被组装成 HTTP Basic 认证头:
export const clicksendAuth = PieceAuth.BasicAuth({ description: `You can get your API credentials by clicking 'API Credentials' on the top right of the dashboard.`, required: true, username: { displayName: 'Username', description: 'Your ClickSend username' }, password: { displayName: 'API Key', description: 'Your ClickSend API key' }, validate: async ({ auth }) => { try { await callClickSendApi({ method: HttpMethod.GET, path: '/account', username: auth.username, password: auth.password, }); return { valid: true }; } catch { return { valid: false, error: 'Invalid Credentials.' }; } }, });(代码见 src/index.ts)
值得注意的是validate回调:用户在 Activepieces 界面保存连接时,系统会实际调用GET /account接口探测凭据是否有效,无效则提示 "Invalid Credentials."。这意味着凭据错误会在配置阶段就被拦截,而不是拖到工作流运行时报错。
三、统一 API 调用层:callClickSendApi
所有动作和触发器都不直接发 HTTP 请求,而是共用 src/lib/common/index.ts 中的callClickSendApi:
export async function callClickSendApi<T extends HttpMessageBody>(params: clickSendApiParams) { return await httpClient.sendRequest<T>({ method: params.method, url: `https://rest.clicksend.com/v3${params.path}`, authentication: { type: AuthenticationType.BASIC, username: params.username, password: params.password, }, headers: { 'Content-Type': 'application/json' }, body: params.body, queryParams: params.query, }); }三个关键实现事实:
- Base URL 固定为
https://rest.clicksend.com/v3,所有动作的路径都是相对该前缀拼接,例如/sms/send、/lists/{list_id}/contacts; - 认证方式为
AuthenticationType.BASIC,由框架自动将用户名/密钥转成 Authorization 头; - 请求头固定
Content-Type: application/json,查询参数通过queryParams传入——这正是联系人分页查询的基础。
同一文件还定义了三个被多个动作复用的下拉属性(src/lib/common/index.ts):
contact_list_id:调用GET /lists分页拉取(每页limit: 100,按next_page_url翻页)所有列表,以list_name为标签、list_id为值渲染下拉框;未连接账号时显示 "Please connect your account first." 占位提示。contact_id:依赖上文的contact_list_id(refreshers: ['contact_list_id']),对GET /lists/{contact_list_id}/contacts做同样的全量分页遍历,以联系人email为标签、contact_id为值。sender_id:调用GET /account返回当前账号的user_id,作为发送消息时的from默认候选项。
这种"服务端动态拉取选项"的模式保证了用户在界面上选择的是 ClickSend 账号内真实存在的 ID,避免了手填 ID 导致的 404。
四、发送类动作:Send SMS 与 Send MMS
4.1 Send SMS(批量文本消息)
README 将 Send SMS 描述为向客户、线索或内部用户发送一条或多条短信,核心属性为to(含国家码的号码,必填)、body(消息正文,必填)、from(需在 ClickSend 审核通过的发送者,必填)及可选的定时参数。
从源码实现看(src/lib/action/send-sms.ts),实际入参是一个messages数组(Property.Array),每个元素可携带的字段比 README 的简表更完整:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
to | 短文本 | 是 | 收件号码(含国家码,如 +1234567890) |
body | 短文本 | 是 | 消息正文 |
from | 短文本 | 否 | 发送者名称或号码(需在 ClickSend 审核通过) |
custom_string | 短文本 | 否 | 自定义追踪字符串 |
country | 短文本 | 否 | 国家码(合规用途) |
message_expiry | 数字 | 否 | 消息有效期(分钟) |
priority | 复选框 | 否 | 是否高优先级发送 |
运行逻辑(send-sms.ts#L63-L104):
- 校验
messages必须是非空数组,否则抛出At least one message must be provided.; - 对每条消息做字段裁剪——只有用户填写了才并入请求体(
...(from && { from })这类条件展开),保证不向 API 发送空字段; - 以
POST /sms/send提交{ messages: [...] },并原样返回 ClickSend 的响应体。
动作同时声明了classification: 'WRITE',且aiMetadata.idempotent: false——源码注释明确指出"每次调用都会再次派发消息,重复调用会产生重复短信"。这一点在把它接入 AI Agent 工具调用或重试逻辑时尤其重要。
4.2 Send MMS(多媒体消息)
Send MMS 用于发送活动海报、产品图等媒体内容(src/lib/action/send-mms.ts)。其属性为:
to(必填):收件号码,含国家码;body(必填):消息正文;subject(必填):主题;from(必填):复用公共层clicksendCommon.sender_id下拉属性,从GET /account动态获取;media_url(必填):媒体文件 URL(图片、视频等)。
运行时先做前置校验(to、body、media_url三者缺一即抛错),然后组装 ClickSend 要求的请求结构并以POST /mms/send发送:
body: { media_file: media_url, // 注意:字段名映射为 media_file messages: [{ subject, from, body, to }], }一个易错点:入参叫media_url,但提交给 ClickSend 的字段名是media_file,源码在此做了显式映射。错误处理上,MMS 动作会捕获 API 错误并优先抛出ClickSend API error: {response_msg},把 ClickSend 侧的错误消息透出到工作流日志中,便于定位是号码无效、媒体不可达还是配额问题。aiMetadata同样标记idempotent: false。
五、联系人管理动作:CRUD 与搜索
README 列出的联系人相关功能在源码中均有对应实现,且都内置了参数校验和错误码翻译。
5.1 Create Contact
向指定列表添加联系人(src/lib/action/create-contact.ts)。属性与 README 一致:contact_list_id(必填,下拉)、phone_number(必填)以及可选的email、first_name、last_name、company_name、address_line_1/2、city、state、postal_code、country。
源码在发请求前执行两段本地校验:
function isValidPhone(phone: string) { return /^\+?[1-9]\d{1,14}$/.test(phone); // E.164 风格的号码格式 } function isValidEmail(email: string) { return /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email); }号码不合法直接抛A valid phone number is required.;填了email但格式不对则抛Invalid email address.。请求体只包含非空字段,最终POST /lists/{contact_list_id}/contacts。若 API 返回response_code === 'ALREADY_EXISTS',动作翻译为可读错误Contact already exists in this list.——对 README 中"把网络研讨会报名录入 SMS 列表"这类场景,这可以避免静默产生重复联系人。aiMetadata.idempotent: false,重复调用会被 API 拒绝。
5.2 Update Contact
更新已有联系人(src/lib/action/update-contact.ts)。属性为contact_list_id+contact_id(两者均为依赖下拉)加一组全可选的字段。与创建不同,更新走PUT /lists/{contact_list_id}/contacts/{contact_id},只提交用户填写的字段(部分更新语义)。错误处理区分了 HTTP 状态码:404 →Contact not found.,403 →Permission denied.。其aiMetadata标注idempotent: true:重复提交相同值不改变状态。
5.3 Delete Contact
从列表中删除联系人(src/lib/action/delete-contact.ts),仅需contact_list_id与contact_id。该动作分类为DESTRUCTIVE(区别于其他动作的WRITE),执行DELETE /lists/{contact_list_id}/contacts/{contact_id},成功后返回{ success: true, message: 'Contact deleted.' },同样处理 404/403。aiMetadata将其描述为"实质上幂等":联系人一旦删除,重复调用只是再收到一次 not-found 而不产生新副作用——对应 README 中"用户退订时自动 opt-out"的使用场景。
5.4 Create Contact List 与联系人查询
- Create Contact List(src/lib/action/create-contact-list.ts):唯一必填属性
list_name,空名称会被本地拒绝(List name must not be empty.),随后POST /lists;重名时 API 的ALREADY_EXISTS被翻译为A contact list with this name already exists.。适合"自动建分组营销列表"的自动化前置步骤。 - Search Contact by Email(src/lib/action/search-contact-by-email.ts):输入
contact_list_id与email,对GET /lists/{contact_list_id}/contacts做整列表分页遍历(每页 100 条,直到没有next_page_url),找到精确匹配的邮箱即返回{ found: true, data },遍历完未找到则返回{ found: false, data: {} }。只读且幂等,适合在更新或发信前"先查后做"。 - Search Contact by Phone(src/lib/action/search-contact-by-phone.ts):按手机号在列表内做同样的分页查找。
- Search Contact Lists(src/lib/action/search-contact-lists.ts):无入参,返回账号下全部联系人列表,用于"添加联系人前确认列表是否存在"。
六、附加能力:自定义 API 调用动作
除了上述内置动作,src/index.ts 还通过框架的createCustomApiCallAction注册了一个通用动作:允许用户在界面上自由指定对https://rest.clicksend.com/v3的方法与路径,认证头自动按Basic base64(username:apiKey)填充。这为内置动作未覆盖的 ClickSend v3 接口(如语音、邮件、余额查询等)提供了逃生通道,无需修改件代码。
七、触发器:New Incoming SMS
README 将"New Incoming SMS"描述为接收新短信时触发。从源码实现看(src/lib/trigger/new-incoming-sms.ts),该触发器实际上采用TriggerStrategy.WEBHOOK策略,通过 ClickSend 的入站自动化规则把消息推到 Activepieces 的 webhook 地址:
- 启用时(
onEnable):调用POST /automations/sms/inbound创建一条名为AP Incoming SMS的入站规则,dedicated_number设为'*'(监听账号下所有专用号码),action为URL、action_address为 Activepieces 分配的context.webhookUrl,webhook_type为json;返回的inbound_rule_id存入触发器的context.store。 - 禁用时(
onDisable):从 store 取出规则 ID,调用DELETE /automations/sms/inbound/{ruleId}清理规则,避免在 ClickSend 侧遗留死规则。 - 触发时(
run):直接返回context.payload.body,即 ClickSend 推送的 JSON 消息体。
触发器输出的示例数据结构(源码sampleData,new-incoming-sms.ts#L67-L90):
{ "message_id": "12345678", "status": "RECEIVED", "message_timestamp": 1644321600, "message_time": "2022-02-08 01:00:00", "message_to": "+1234567890", "message_from": "+0987654321", "message_body": "Hello from ClickSend!", "message_direction": "in", "message_type": "sms", "message_parts": 1, "message_cost": "0.0250", "country": "US", "carrier": "Verizon", "first_name": "John", "last_name": "Doe", "email": "john.doe@example.com" }(README 中给出的样例数据与此一致,另外源码还包含from_email、list_id、custom_string、contact_id、user_id、subaccount_id等字段。)
由此可以构成一条完整的"进-出"闭环:入站触发器捕获客户回复 → 工作流处理(如 AI Agent 分类、写表)→ 用 Send SMS 动作回发通知。
八、面向 AI Agent 的设计:aiMetadata 与 audience
与项目"AI Agents & AI Workflow Automation"的定位呼应,ClickSend 件中的每个动作都携带audience: 'both'(人类构建者与 AI Agent 均可用)和aiMetadata。aiMetadata.description用自然语言描述了动作的语义、适用场景与替代选择(例如 Send MMS 的描述中明确提示"消息需要携带媒体时才选它而不是 Send SMS"),idempotent标志则告诉 Agent 框架重试是否安全:
- 非幂等(重复调用有副作用):Send SMS、Send MMS、Create Contact、Create Contact List;
- 幂等(可安全重试):Update Contact、Delete Contact、各类 Search。
这些元数据是该件能被 Agent 安全编排的关键依据,也为其他集成件的编写提供了可参考的模式。
九、使用场景与延伸阅读
README 给出的典型场景(README.md)可直接映射到上述能力:
- 客户支持:工单创建时自动发短信(触发器 + Send SMS);
- 线索管理:表单线索入 SMS 营销列表(Create Contact);
- 活动营销:短信/彩信发送活动提醒(Send SMS / Send MMS + media_url);
- 订单通知:订单状态与配送更新;
- 预约提醒:确认与提醒自动化;
- 营销活动:分组列表管理(Create Contact List + 各 Search 动作)。
此外,src/i18n/目录提供了 de、es、fr、ja、nl、pt、ru、vi、zh 等 10 种语言的界面翻译(见 i18n/translation.json 所在目录),说明该集成件在国际化界面上的完整性。更细粒度的 ClickSend v3 接口行为以官方 API 文档为准;而在 Activepieces 仓库中,本文引用的全部文件——README、认证与注册、公共层、动作目录 与 触发器——均可直接打开核对,作为二次开发或仿写其他消息类集成的参考基线。
【免费下载链接】activepiecesAI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents项目地址: https://gitcode.com/GitHub_Trending/ac/activepieces
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考