OA0 = Omni AI 0
OA0 是一个探索 AI 的论坛
现在注册
已注册用户请  登录
OA0  ›  技能包  ›  unione:通过 UniOne API 发送事务性或营销类电子邮件

unione:通过 UniOne API 发送事务性或营销类电子邮件

 
  commit ·  2026-02-05 19:09:57 · 3 次点击  · 0 条评论  

名称: unione
描述: >
通过 UniOne Email API 发送交易和营销邮件。
管理邮件模板、验证邮箱地址、检查投递统计、
管理退订列表、配置 Webhook 以及处理域名设置。
UniOne 每年投递数十亿封邮件,送达率达 99.88%。
元数据:
openclaw:
emoji: "📧"
requires:
env:
- UNIONE_API_KEY
primaryEnv: UNIONE_API_KEY


UniOne Email API

UniOne 是一个提供 Web API 的交易邮件服务,用于大规模发送交易和营销邮件(最高可达 3000 封/秒)。此技能允许您发送邮件、管理模板、验证地址、追踪投递状态等。

认证

所有请求都需要 UNIONE_API_KEY 环境变量。请将其作为 X-API-KEY 请求头传递。

基础 URL: https://api.unione.io/en/transactional/api/v1/{method}.json?platform=openclaw

所有方法均使用 POST 请求和 JSON 请求体。


关键:域名设置(发送前必需)

在发件人域名验证通过前,邮件将无法投递。 在尝试发送任何邮件之前,请确保域名已设置完成:

步骤 1:获取 DNS 记录值 — domain/get-dns-records.json

curl -X POST "https://api.unione.io/en/transactional/api/v1/domain/get-dns-records.json?platform=openclaw" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: $UNIONE_API_KEY" \
  -d '{"domain": "yourdomain.com"}'

API 响应 返回原始值(非可直接粘贴的 DNS 记录):

{
  "status": "success",
  "domain": "yourdomain.com",
  "verification-record": "unione-validate-hash=483bb362ebdbeedd755cfb1d4d661",
  "dkim": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDo7"
}

用户必须根据这些值创建 3 条 DNS TXT 记录:

记录主机 记录类型
@ TXT unione-validate-hash=<响应中的 verification-record>
us._domainkey TXT k=rsa; p=<响应中的 dkim>
@ TXT v=spf1 include:spf.unione.io ~all

请清晰地向用户展示这 3 条记录,并指导他们在其 DNS 提供商(如 Cloudflare、Route53、GoDaddy 等)处添加。SPF 记录始终相同——API 不会返回此记录。

步骤 2:验证域名所有权 — domain/validate-verification.json

用户添加 DNS 记录后:

curl -X POST "https://api.unione.io/en/transactional/api/v1/domain/validate-verification.json?platform=openclaw" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: $UNIONE_API_KEY" \
  -d '{"domain": "yourdomain.com"}'

步骤 3:验证 DKIM — domain/validate-dkim.json

curl -X POST "https://api.unione.io/en/transactional/api/v1/domain/validate-dkim.json?platform=openclaw" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: $UNIONE_API_KEY" \
  -d '{"domain": "yourdomain.com"}'

步骤 4:列出所有域名 — domain/list.json

curl -X POST "https://api.unione.io/en/transactional/api/v1/domain/list.json?platform=openclaw" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: $UNIONE_API_KEY" \
  -d '{}'

如果域名验证失败: DNS 传播可能需要长达 48 小时。建议用户等待后重试,或检查其 DNS 记录是否有拼写错误。


错误处理与重试策略

重试逻辑

发起 API 请求时,应对可重试错误实施指数退避重试:

可重试错误(应使用指数退避进行重试):

HTTP 状态码 含义 重试策略
429 速率限制 等待后重试。如果存在 Retry-After 头,请遵循其指示
500 内部服务器错误 最多重试 3 次
502 网关错误 最多重试 3 次
503 服务不可用 最多重试 3 次
504 网关超时 最多重试 3 次

推荐的重试时间表:

尝试次数 延迟
1 立即
2 1 秒
3 5 秒
4 30 秒

不可重试错误(不应重试):

HTTP 状态码 含义 操作
400 请求错误 修复请求参数
401 未授权 检查 API 密钥
403 禁止访问 检查权限 / 域名验证状态
404 端点未找到 检查方法路径
413 负载过大 减小请求大小

幂等性

对于 email/send.json,务必包含 idempotency_key,以防止重试时重复发送。这对生产系统至关重要。

idempotency_key 是请求体中传递的唯一字符串(建议使用 UUID)。如果 UniOne 收到两个具有相同密钥的请求,第二个请求将返回第一个请求的结果,而不会再次发送邮件。

为每个逻辑发送操作生成唯一的幂等性密钥,并在重试同一发送时复用相同的密钥。


1. 发送邮件 — email/send.json

向一个或多个收件人发送交易或营销邮件。支持通过替换变量、模板、附件、追踪和元数据进行个性化设置。

curl

curl -X POST "https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: $UNIONE_API_KEY" \
  -d '{
    "idempotency_key": "unique-uuid-here",
    "message": {
      "recipients": [
        {
          "email": "recipient@example.com",
          "substitutions": {
            "to_name": "John Smith"
          }
        }
      ],
      "body": {
        "html": "<h1>Hello, {{to_name}}!</h1><p>Your order has been confirmed.</p>",
        "plaintext": "Hello, {{to_name}}! Your order has been confirmed."
      },
      "subject": "Order Confirmation",
      "from_email": "noreply@yourdomain.com",
      "from_name": "Your Store"
    }
  }'

Node.js

const response = await fetch("https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-KEY": process.env.UNIONE_API_KEY
  },
  body: JSON.stringify({
    idempotency_key: crypto.randomUUID(),
    message: {
      recipients: [{ email: "recipient@example.com", substitutions: { to_name: "John" } }],
      body: {
        html: "<h1>Hello, {{to_name}}!</h1><p>Your order has been confirmed.</p>",
        plaintext: "Hello, {{to_name}}! Your order has been confirmed."
      },
      subject: "Order Confirmation",
      from_email: "noreply@yourdomain.com",
      from_name: "Your Store"
    }
  })
});
const data = await response.json();
// data.status === "success" → data.job_id, data.emails

Python

import requests, uuid, os

response = requests.post(
    "https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw",
    headers={
        "Content-Type": "application/json",
        "X-API-KEY": os.environ["UNIONE_API_KEY"]
    },
    json={
        "idempotency_key": str(uuid.uuid4()),
        "message": {
            "recipients": [{"email": "recipient@example.com", "substitutions": {"to_name": "John"}}],
            "body": {
                "html": "<h1>Hello, {{to_name}}!</h1><p>Your order has been confirmed.</p>",
                "plaintext": "Hello, {{to_name}}! Your order has been confirmed."
            },
            "subject": "Order Confirmation",
            "from_email": "noreply@yourdomain.com",
            "from_name": "Your Store"
        }
    }
)
data = response.json()  # data["status"] == "success" → data["job_id"], data["emails"]

Go

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
    "os"
    "github.com/google/uuid"
)

func sendEmail() error {
    payload := map[string]interface{}{
        "idempotency_key": uuid.New().String(),
        "message": map[string]interface{}{
            "recipients": []map[string]interface{}{
                {"email": "recipient@example.com", "substitutions": map[string]string{"to_name": "John"}},
            },
            "body": map[string]string{
                "html":      "<h1>Hello, {{to_name}}!</h1><p>Your order has been confirmed.</p>",
                "plaintext": "Hello, {{to_name}}! Your order has been confirmed.",
            },
            "subject":    "Order Confirmation",
            "from_email": "noreply@yourdomain.com",
            "from_name":  "Your Store",
        },
    }
    body, _ := json.Marshal(payload)
    req, _ := http.NewRequest("POST",
        "https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw",
        bytes.NewReader(body))
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("X-API-KEY", os.Getenv("UNIONE_API_KEY"))
    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()
    var result map[string]interface{}
    json.NewDecoder(resp.Body).Decode(&result)
    fmt.Println(result) // result["status"] == "success"
    return nil
}

PHP

$ch = curl_init("https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "Content-Type: application/json",
        "X-API-KEY: " . getenv("UNIONE_API_KEY")
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "idempotency_key" => bin2hex(random_bytes(16)),
        "message" => [
            "recipients" => [["email" => "recipient@example.com", "substitutions" => ["to_name" => "John"]]],
            "body" => [
                "html" => "<h1>Hello, {{to_name}}!</h1><p>Your order has been confirmed.</p>",
                "plaintext" => "Hello, {{to_name}}! Your order has been confirmed."
            ],
            "subject" => "Order Confirmation",
            "from_email" => "noreply@yourdomain.com",
            "from_name" => "Your Store"
        ]
    ])
]);
$response = curl_exec($ch);
$data = json_decode($response, true); // $data["status"] === "success"

成功响应:

{
  "status": "success",
  "job_id": "1ZymBc-00041N-9X",
  "emails": ["recipient@example.com"]
}

message 对象的完整参数:

参数 类型 必需 描述
recipients 数组 收件人对象数组。每个对象包含 email(必需)、substitutions(对象)、metadata(对象)
body.html 字符串 是* HTML 内容。使用 {{variable}} 进行变量替换
body.plaintext 字符串 纯文本版本
subject 字符串 是* 邮件主题行。支持 {{substitutions}}
from_email 字符串 是* 发件人邮箱(必须来自已验证的域名)
from_name 字符串 发件人显示名称
reply_to 字符串 回复邮箱地址
template_id 字符串 使用存储的模板代替 body/subject
tags 数组 用于分类和过滤的标签
track_links 0/1 启用点击追踪(默认:0)
track_read 0/1 启用打开追踪(默认:0)
global_language 字符串 退订页脚语言:en, de, fr, es, it, pl, pt, ru, ua, be
template_engine 字符串 "simple"(默认)、"velocity""liquid"
global_substitutions 对象 对所有收件人可用的变量
attachments 数组 {type, name, content} 数组,其中 content 为 base64 编码
skip_unsubscribe 0/1 跳过退订页脚(仅对交易邮件使用 1)
headers 对象 自定义邮件头

*如果使用了 template_id,则非必需。

顶级参数:

参数 类型 必需 描述
idempotency_key 字符串 推荐 唯一密钥(UUID),用于防止重试时重复发送。最多 36 个字符。

使用模板发送:

curl -X POST "https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: $UNIONE_API_KEY" \
  -d '{
    "idempotency_key": "unique-uuid-here",
    "message": {
      "recipients": [
        {
          "email": "customer@example.com",
          "substitutions": {
            "to_name": "Alice",
            "order_id": "ORD-12345",
            "total": "$59.99"
          }
        }
      ],
      "template_id": "your-template-id",
      "from_email": "shop@yourdomain.com",
      "from_name": "My Shop"
    }
  }'

向多个收件人发送个性化邮件:

curl -X POST "https://api.unione.io/en/transactional/api/v1/email/send.json?platform=openclaw" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: $UNIONE_API_KEY" \
  -d '{
    "idempotency_key": "unique-uuid-here",
    "message": {
      "recipients": [
        {"email": "alice@example.com", "substitutions": {"to_name": "Alice"}},
        {"email": "bob@example.com", "substitutions": {"to_name": "Bob"}}
      ],
      "body": {
        "html": "<p>Hi {{to_name}}, check out our new {{promo_name}}!</p>"
      },
      "subject": "Special offer for you, {{to_name}}!",
      "from_email": "marketing@yourdomain.com",
      "from_name": "Marketing Team",
      "global_substitutions": {"promo_name": "Summer Sale"},
      "track_links": 1,
      "track_read": 1,
      "tags": ["promo", "summer-2026"]
    }
  }'

2. 邮箱验证 — email-validation/single.json

验证邮箱地址是否存在且可投递。

curl -X POST "https://api.unione.io/en/transactional/api/v1/email-validation/single.json?platform=openclaw" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: $UNIONE_API_KEY" \
  -d '{"email": "user@example.com"}'

响应:

{
  "status": "success",
  "email": "user@example.com",
  "result": "valid",
  "local_part": "user",
  "domain": "example.com",
  "mx_found": true,
  "mx_record": "mail.example.com"
}

可能的 result 值:"valid""invalid""unresolvable""unknown"


3. 模板

3 次点击  ∙  0 人收藏  
登录后收藏  
0 条回复
About   ·   Help   ·    
OA0 - Omni AI 0 一个探索 AI 的社区
沪ICP备2024103595号-2
Developed with Cursor