通过 SMS API 将 SMS 服务集成到 Yeastar P 系列 IPPBX

Yeastar P 系列 IPPBX 允许 SMS 运营商使用 SMS API 将其短信服务与 PBX 系统集成。本文介绍 SMS 运营商如何通过 API 实现与 Yeastar PBX 的 SMS 服务交互,并介绍 PBX 管理员如何在 PBX 管理网页上为 SMS 运营商设置消息渠道。

使用要求

要实现 SMS 服务与 Yeastar P 系列 IPPBX 的集成,PBX 和 SMS 运营商两个平台必须满足以下要求。

平台 要求
Yeastar PBX
  • 固件版本37.14.0.24 或更高版本
  • 订阅服务隧道服务视频会议,保证 FQDN 功能可用
  • FQDN:确保 PBX 可通过 FQDN 访问。
    注: 由于第三方平台限制,FQDN 域名中不能包含下划线,否则消息渠道会出现验证失败或无法接收消息的问题。

    有关 FQDN 配置的具体信息,请参见 通过 Yeastar FQDN 远程访问 PBX

SMS 运营商
  • API:SMS 运营商需提供以下 API 接口。
    • 用于验证鉴权信息的 HTTPS REST API

    • 用于对外发送消息的 HTTPS REST API

  • 用户门户功能:SMS 运营商的用户门户需支持以下功能。
    • 可提供 API key (API 密钥),用于验证 PBX 发送的 API 请求。
    • 可提供安全的 Secret (密钥),供 PBX 验证 SMS 运营商发送的 Webhook 请求。
    • 可通过用户界面配置 Webhook
  • 号码格式:号码需支持 E.164 格式。

验证请求

SMS 服务集成通过 API 交互实现,因此,SMS 运营商需提供 API keySecret,用于验证集成中的 API 请求和 Webhook 请求。
  • API key

    API key 用于验证 PBX 向 SMS 运营商发送的 API 请求。

    PBX 将在每个 API 请求的头部中通过 Authorization 字段传递此 API key,如下所示:

    Authorization: Bearer {api_key}
    收到 API 请求后,SMS 运营商会验证请求头中的 API key。如果 API key 有效,SMS 运营商需执行请求中指定的相应操作。否则,API 请求将失败。
    关于具体 API 请求的说明,请参见以下章节:
  • Secret

    Secret 用于验证 SMS 运营商向 PBX 发送的 Webhook 请求。

    在通过 Webhook 向 PBX 发送消息时,SMS 运营商需使用此 Secret 通过 SHA256 算法对 Webhook 请求体数据生成一个签名,并在每个 Webhook 请求的头部中通过 X-Signature-256 字段传递此签名,如下所示:
    重要: 传递的签名必须全为小写字母。
    X-Signature-256: sha256={signature}
    收到 Webhook 请求后,PBX 将使用 Secret 通过 SHA256 算法对收到的 Webhook 请求体数据计算一个签名,并将计算结果与从请求头中提取的签名进行比较。如果两个值匹配,表示 Webhook 请求成功,PBX 会将从请求体中获取的消息内容传递给消息接收者。否则,Webhook 请求将被拒绝。

    关于具体 Webhook 请求的说明,请参见 接收来自 SMS 运营商的消息

验证 SMS 短信渠道的连接状态

在 PBX 管理网页上设置了 SMS 短信渠道后,PBX 将使用 SMS 运营商提供的 验证鉴权信息的 API 接口地址API key,定期向其发送 API 请求,从而验证渠道的连接状态。

交互流程

渠道连接状态验证的过程如下所示:

  1. PBX 发送 API 请求,并包含了一个随机生成的验证码 (challenge_code)。
  2. 收到 API 请求时,SMS 运营商验证请求中的 API key。
  3. 如果 API key 有效,SMS 运营商需返回状态码 200,并将验证码附在响应体中。
  4. 收到响应时,PBX 会检查返回的验证码是否与其发送的验证码一致。

    如果验证码匹配,则表明渠道连接成功。

PBX 发送的 API 请求

以下为 PBX 发送的用于验证渠道连接状态的 API 请求的结构和说明。

请求方式
GET
请求 URL
{api_address_for_verifying_authentication}
例如:
https://service-provider.example.com/verify
请求头
参数 类型 说明
Authorization String 在请求头中传递 API key。

格式:Bearer {api_key}

查询参数
参数 类型 说明
challenge String 验证码 (challenge_code)。由 PBX 生成的随机字符串。
请求示例
GET /verify?challenge=mAWpGnyeTZgguOPYlWitGPlRJYIhoLMy HTTP/1.1
Host: service-provider.example.com
Authorization: Bearer {api_key}
SMS 运营商返回的 API 响应
SMS 运营商需以 JSON 格式返回 API 响应。
成功响应
如果请求成功,SMS 运营商需在响应中返回以下信息:
  • HTTP 状态码 200
  • PBX 在请求中发送的验证码
以下为成功响应的示例:
HTTP/1.1 200 OK 
Body: mAWpGnyeTZgguOPYlWitGPlRJYIhoLMy
若响应体中的验证码与 PBX 发送的一致,则渠道连接成功,PBX 管理网页上的渠道状态显示为 (已连接)。
异常响应
如果请求失败,SMS 运营商需在响应中根据以下格式返回错误信息。
参数 类型 说明
code String 错误码
title String 错误类型 (可自定义)。
detail String 详细的错误信息 (可自定义)。
以下为渠道连接验证失败的响应示例。
HTTP/1.1 401 Unauthorized
{
    "errors": [
        {
            "code": "10004",     
            "title": "Authentication failed",    
            "detail": "No key found matching the ID with the provided secret."
        }
    ]
}
异常问题排查
如果渠道连接验证失败,PBX 管理网页上的渠道状态会显示异常。SMS 运营商可以通过检查错误码或响应体排查导致异常的原因。
  • 错误码

    下表列举了 PBX 中定义的错误码。

    错误码 错误信息 说明
    10001 channel.ErrInvalidPhoneNumber 无效号码。
    10002 channel.ErrInvalidParam 请求带有无效参数。
    10003 channel.ErrUnsupportMedia 资源类型不支持 (MMS)。
    10004 channel.ErrAuthFail 认证失败。
    10005 channel.ErrAuthFail 没有权限。
    10006 channel.ErrTooManyRequest 请求过于频繁 。
    10007 channel.ErrServiceUnavailable 服务不可用。
    10008 channel.ErrExceedsSizeLimit 文件过大。
  • 异常场景

    下表提供了可能出现的异常渠道状态以及对应的触发条件。

    渠道状态 触发条件
    未授权
    • 鉴权失败,SMS 运营商返回的 HTTP 状态码为 401/403/404
    • 返回的验证码 (challenge code) 与请求中发送的验证码不匹配。
    第三方服务不可用 SMS 运营商返回的 HTTP 状态码为 500
    未知来源 SMS 运营商返回除 401/403/404/500 外的 HTTP 状态码,并在响应体中根据 PBX 定义的格式返回了错误信息。
    请求失败
    • SMS 运营商未返回状态码 (可能由于 TCP 连接异常或域名不存在等情况导致)。
    • SMS 运营商返回除 401/403/404/500 外的状态码,且未返回响应体,或返回的响应体不符合 JSON 格式。

通过 SMS 运营商发送消息

当 PBX 用户发送消息时,PBX 会使用 SMS 运营商提供的 发送消息的 API 接口地址API key 向运营商发送 API 请求,从而通过 SMS 运营商将此消息发送给外部消息接收者。

交互流程
通过 SMS 运营商发送消息的流程如下所示:

  1. PBX 用户发送消息。
  2. PBX 发送 API 请求,请求通过 SMS 运营商发送消息。
  3. 收到 API 请求时,SMS 运营商验证请求中的 API key。
  4. 如果 API key 有效,SMS 运营商需返回状态码 200,并返回一个 data.id,用于传递此消息的唯一 ID。
  5. SMS 运营商将消息传送给消息接收者。
PBX 发送的 API 请求

以下为 PBX 发送的用于发送消息的 API 请求的结构和说明。

请求方式
POST
请求 URL
{api_address_for_sending_message}
例如:
POST https://service-provider.example.com/sendmessage
请求头
参数 类型 说明
Content-Type String 定义请求中负载的内容类型。

有效值:application/json

Authorization String 在请求头中传递 API key。

格式:Bearer {api_key}

请求体
PBX 将在请求正文中传递出站信息。
参数 类型 说明
from String 消息发送者的号码。
注: 此参数必须符合 E.164 格式。例如,+8618012121222
to String 消息接收者的号码。
注: 此参数必须符合 E.164 格式。例如,+8618012121222
text String 消息的文本内容。
media_urls Array<String> 指向消息的多媒体内容的 URL。
请求示例
以下是通过 SMS 运营商向某个电话号码发送 SMS/MMS 消息的示例。
  • 发送 SMS 消息
    POST /sendmessage HTTP/1.1
    Host: service-provider.example.com
    Content-Type: application/json
    Authorization: Bearer {api_key}
    
    {
        "from": "+8618012121222",  
        "text": "Hello, World!",   
        "to": "+8618012121223"     
    }
  • 发送 MMS 消息
    POST /sendmessage HTTP/1.1
    Host: service-provider.example.com
    Content-Type: application/json
    Authorization: Bearer {api_key}
    
    {
        "from":"+8618012121222",
        "to":"+8618012121223",
        "media_urls":["https://yeastardocs.ras.yeastar.com/api/chat/70dee7e2f95041ca890f222ace06c2dc"]
    }
SMS 运营商返回的 API 响应
SMS 运营商需以 JSON 格式返回 API 响应。
成功响应
如果请求成功,SMS 运营商需在响应中返回以下信息:
  • HTTP 状态码 200
  • 参数 data.id,用于传递此消息的唯一 ID
以下为成功响应的示例:
HTTP/1.1 200 OK 
{
    "data": {
        "id":"b301ed3f-1490-491f-995f-6e64e69674d4",  // 消息的唯一 ID (必填)
        "from": {                                     // 消息发送者的信息
            "carrier": "PBX",                      
            "line_type": "VoIP",                   
            "phone_number": "+8618012121222"       
        },
        "text": "Hello world!",                    // 消息的文本内容
        "media": [                                    // 消息的多媒体内容
            {
                "content_type": null,                 // 多媒体内容的类型
                "sha256": null,                       // 多媒体内容的 SHA256 值
                "size": null,                         // 文件大小
                "url": "https://yeastardocs.ras.yeastar.com/profile_images/1142168442042118144/AW3F4fFD_400x400.png"  // 指向多媒体内容的 URL
            }
        ],
        "to": [                                       // 消息接收者的信息
            {
                "carrier": "T-MOBILE USA, INC.",     
                "line_type": "Wireless",            
                "phone_number": "+8618012121223",    
                "status": "queued"                  
            }
         ],
        ...
        } 
}
异常响应
如果请求失败,SMS 运营商需在响应中根据以下格式返回错误信息。
参数 类型 说明
code String 错误码
title String 错误类型 (可自定义)。
detail String 详细的错误信息 (可自定义)。
以下为消息发送失败的响应示例。
HTTP/1.1 400 Bad Request
{
    "errors": [
        {
            "code": "10001",     
            "title": "Invalid 'to' address",    
            "detail": "The 'to' address should be a single valid number."
        }
    ]
}
异常问题排查
消息发送失败时,PBX 用户的 Linkus 客户端上会展示错误提示信息,SMS 运营商可以通过检查错误码或响应体排查原因。
  • 错误码
    错误码 错误信息 说明
    10001 channel.ErrInvalidPhoneNumber 无效号码。
    10002 channel.ErrInvalidParam 请求带有无效参数。
    10003 channel.ErrUnsupportMedia 资源类型不支持 (MMS)。
    10004 channel.ErrAuthFail 认证失败。
    10005 channel.ErrAuthFail 没有权限。
    10006 channel.ErrTooManyRequest 请求过于频繁 。
    10007 channel.ErrServiceUnavailable 服务不可用。
    10008 channel.ErrExceedsSizeLimit 文件过大。
  • 异常场景

    下表提供了 PBX 用户的 Linkus 客户端上可能展示的错误提示信息,以及对应的触发条件。

    异常提示 触发条件
    发送失败
    • SMS 运营商未返回 data.id
    • SMS 运营商返回的 HTTP 状态码为 404,并提示服务未找到。
    • 消息发送失败。SMS 运营商根据 PBX 定义的格式返回错误信息,此错误信息将展示在异常提示中。
    • 消息发送失败,且 SMS 运营商未返回错误信息,或返回的格式不正确。
    鉴权失败
    • SMS 运营商返回的 HTTP 状态码为 401。
    • SMS 运营商返回的错误码为 10004 或 10005。
    第三方平台的服务不可用
    • SMS 运营商返回的 HTTP 状态码为 403。
    • SMS 运营商返回的错误码为 10007。
    无效号码 SMS 运营商返回错误码 10001。
    参数无效 SMS 运营商返回错误码 10002。
    根据第三方平台限制,无法发送该类型消息 SMS 运营商返回错误码 10003。
    操作频繁,请稍后再试 SMS 运营商返回错误码 10006。
    文件大小超过第三方平台的限制 SMS 运营商返回错误码 10008。

接收来自 SMS 运营商的消息

PBX 可通过 SMS 运营商提供的电话号码接收外部消息发送者传入的消息。当外部的消息发送者向此电话号码发送信息时,SMS 运营商可向 PBX 的 Webhook URL 发送请求,从而将此消息发送到 PBX 上。

交互流程
PBX 接收来自 SMS 运营商消息的流程如下所示:

  1. 外部的消息发送者向 SMS 运营商提供的号码发送消息。
  2. SMS 运营商需向 PBX 的 Webhook URL 发送请求,将入站消息包含在请求体中,并在请求头中附上 SHA256 签名
  3. 在收到 Webhook 请求时,PBX 使用 SMS 运营商提供的 Secret 对收到的 Webhook 请求体内容计算 SHA256 签名,并将计算结果与从请求头中获取的签名进行比较。

    如果签名匹配,则表示 Webhook 请求有效,PBX 会向 SMS 运营商返回状态码 204

  4. PBX 将消息发送给 PBX 用户。
SMS 运营商发送的 Webhook 请求

以下是 SMS 运营商发送 Webhook 请求时需遵循的结构要求和参数说明。

请求方式
POST
请求 URL
{webhook_url_provided_by_pbx}
例如:
https://yeastardocs.ras.yeastar.com/api/v1.0/webhook/general/429ced149ff9437695be795aff38407b
请求头
参数 类型 说明
Content-Type String 定义请求中负载的内容类型。

有效值:application/json

X-Signature-256 String

传递用于 Webhook 验证的签名 (signature),其中 {signature} 是使用 SHA256 算法对正文内容和密文进行加密后生成的小写结果。

格式:sha256={signature}

请求体
SMS 运营商需在请求体中传递要发送到 PBX 的消息。
注: 此处只列出了必填参数。如果需要,SMS 运营商可以增加其他数据来扩展该信息。
参数 是否必填 类型 说明
data.event_type String 事件类型。

有效值message.received

data.payload.id String 消息 ID。
注: 最大字符长度为 255。
data.payload.from.phone_number String 消息发送者的电话号码。
注: 此参数必须符合 E.164 格式。例如,+8618012121222
data.payload.to.phone_number String 消息接收者的电话号码。
注: 此参数必须符合 E.164 格式。例如,+8618012121222
data.payload.text String 消息的文本内容。
注: data.payload.textdata.payload.media 二者必填一个。
data.payload.media Array<media> 消息的多媒体内容。
注: data.payload.textdata.payload.media 二者必填一个。
data.payload.received_at String 收到信息的时间 (ISO 8601 格式)。

格式YYYY-MM-DDTHH:MM:SS.mmm+/-HH:MM

示例:2019-12-09T20:16:07.588+08:00。

data.payload.record_type String 记录类型。

有效值message

media
参数 是否必填 类型 说明
content_type String 媒体文件类型。
提示: 可参见 MIME 类型 了解常见的媒体文件类型。
sha256 String 媒体文件的 SHA256 签名。
size Integer 文件大小。
url String 指向多媒体内容的 URL。
请求示例
以下提供了一个 SMS 运营商向 PBX 发送消息的请求示例。
POST /api/v1.0/webhook/general/429ced149ff9437695be795aff38407b HTTP/1.1
Host: yeastardocs.ras.yeastar.com
Content-Type: application/json
X-Signature-256: sha256={signature}

{
    "data": {
        "event_type": "message.received",
        "id": "b301ed3f-1490-491f-995f-6e64e69674d4",             //事件 ID
        "occurred_at": "2019-12-09T20:16:07.588+00:00",
        "payload": {
            "completed_at": null,
            "cost": null,
            "direction": "inbound",
            "encoding": "GSM-7",
            "errors": [],
            "from": {                                             //消息发送者的信息
                "carrier": "T-Mobile USA",
                "line_type": "long_code",
                "phone_number": "+8618012121222",
                "status": "webhook_delivered"
            },
            "id": "84cca175-9755-4859-b67f-4730d7f58aa3",         //消息 ID
            "media": [{                                           //消息的多媒体内容
                    "content_type": null,
                    "sha256": null,
                    "size": null,
                    "url": "https://pbs.twimg.com/profile_images/1142168442042118144/AW3F4fFD_400x400.png"
                }],
            "messaging_profile_id": "740572b6-099c-44a1-89b9-6c92163bc68d",
            "organization_id": "47a530f8-4362-4526-829b-bcee17fd9f7a",
            "parts": 1,
            "received_at": "2019-12-09T20:16:07.503+00:00",        //接收到消息的时间
            "record_type": "message",                              //记录类型
            "sent_at": null,
            "tags": [],
            "text": "Hello from PBX!",                             //消息的文本内容
            "to": [                                                //消息接收者的信息
                {
                    "carrier": "PBX",
                    "line_type": "Wireless",
                    "phone_number": "+8618012121223",
                    "status": "webhook_delivered"
                }
            ],
            "type": "SMS/MMS",
            "valid_until": null,
            "webhook_failover_url": null,
            "webhook_url": "http://webhook.site/04bbd2e3-09b5-4c9e-95de-a1debeb9e675"
        },
        "record_type": "event"
    },
    "meta": {
        "attempt": 1,
        "delivered_to": "http://webhook.site/04bbd2e3-09b5-4c9e-95de-a1debeb9e675"
    }
}
PBX 返回的 Webhook 响应
PBX 系统将在响应中返回一个状态码。
状态码 说明
204 成功。
400 请求参数错误,在签名不正确时返回。

为 SMS 运营商配置 SMS 短信渠道

在 SMS 运营商完成与 Yeastar PBX 的 SMS 服务集成后,PBX 管理员可在 PBX 管理网页上配置短信渠道。

使用限制
项目 限制
支持的消息类型 SMS 短信渠道中支持发送的消息类型取决于 SMS 运营商。
重要: 发送多媒体消息 (例如图片) 时,SMS 运营商会通过 PBX 提供的链接下载文件。因此,如果你设置了 国家地区 IP 访问防御 安全规则,需确保 PBX 允许 SMS 运营商所在国家的 IP 访问,否则文件传输会失败。
文件大小 最大 100 MB
文件保留时间 24 小时
前提条件
  • 向 SMS 运营商获取以下信息:
    • 用于验证鉴权信息的 API 地址
    • 用于发送消息的 API 地址
    • 信息发送速率限制
  • 从 SMS 运营商的用户界面中获取以下信息:
    • API key (API 密钥)
    • Secret (密钥)
    • 用于发送和接收信息的电话号码
      注: 如果企业需要与美国客户联系,须确保此电话号码已经完成 10DLC 注册,以防止发送到美国号码的 SMS 消息被拦截。
操作步骤
  1. 登录 PBX 管理网页,进入 讯息管理 > 消息渠道
  2. 点击 添加 > SMS
  3. 鉴权信息 页签中,完成以下设置。

    • 名称:填写一个便于识别的名称。
    • 运营商:选择 通用
    • API Key:填写从 SMS 运营商用户界面中获取的 API key。
    • Secret:填写从 SMS 运营商用户界面中获取的 Secret 密钥。
    • 发送消息的API接口地址:填写 SMS 运营商提供的 API 地址。在本例中,填写 https://service-provider.example.com/sendmessage
    • 验证鉴权信息的API接口地址:填写 SMS 运营商提供的 API 地址。在本例中,填写 https://service-provider.example.com/verify
    • Webhook URL:复制此 Webhook URL,并粘贴到 SMS 运营商的用户界面中。
  4. 消息设置 页签,配置该渠道。
    1. 消息发送速率 栏,指定 PBX 每秒可发送多少条消息。
      注:
      • 如果消息发送的速率超过此处设置的值,PBX 会将消息排队,并按照设置的速率发送。
      • 如果设置的消息发送速率超过 SMS 运营商设置的速率,可能会导致消息发送失败。因此,请联系 SMS 运营商确认你的账户的发送速率限制,并根据需要提高限制。
    2. 可选: 如果你想要系统自动关闭在指定时间内无任何互动的会话,勾选 自动关闭会话,并在 会话超时时间 (天) 栏中设置超时时间。

    3. 号码 栏,点击 添加,添加消息路由规则。

      • 号码:以 E.164 格式填写购买的号码 ([+][国家区号][电话号码])。例如 +14102161183
      • 消息目的地:设置通过此号码送入的消息会被送往哪个目的地。
        选项 说明
        分机 若选择此项,需在 分机 下拉列表中选择接收消息的分机。

        只有此分机用户可以接收到通过此号码送入的消息。

        消息队列 若选择此项,需在 消息队列 下拉列表中选择接收消息的队列。

        所选队列中的所有坐席都会收到队列中新会话的消息,但只有接管了会话的用户可以接收并回复后续送入的消息。

      • 允许创建会话的分机:选择一个或多个分机,选择的分机可以向外部用户发送消息。
    4. 点击 保存
  5. 点击 保存
执行结果
  • 消息渠道已创建成功,可在列表中查看到此渠道的 状态 显示为

  • 系统自动追踪并记录该渠道上发送和接收的消息数量,其中 总发送量 包含了发送成功和发送失败的所有消息数量。
    注:
    • 对于发送消息,PBX 仅追踪坐席在其 Linkus UC 客户端上发送的消息数据。因此,如果你要计算准确的消息发送费用,需要和 SMS 运营商确认精准的消息发送数量,因为在发送的信息超过 160 个字符的情况下,运营商可能将消息拆分发送,并在到达客户手机时将消息整合,这会额外增加发送消息的数量。
    • 可通过时间筛选查看指定时间段内的消息数据。

后续操作
发送测试消息,确认指定的 PBX 用户是否可以在 Linkus 客户端上成功接收和发送消息。