mingyuanyun / yii2-imessage
消息发送组件,集成多渠道消息(邮件、企业微信、短信、APP)消息,内置重试机制、统一返回格式,支持下云(短信类支持公共组短信及阿里云短信)。
v1.0.211122
2021-11-22 08:54 UTC
Requires
- php: >=7.0
- alibabacloud/client: ^1.5
- mingyuanyun/iwechat: dev-master
- mingyuanyun/yii2-ilog: ^1.2
- yunchuang/push: ^1.1
This package is not auto-updated.
Last update: 2025-03-27 02:02:29 UTC
README
消息发送组件,集成多渠道消息(邮件、企业微信、短信、APP)消息,内置重试机制、统一返回格式,支持下云(短信类支持公共组短信及阿里云短信),短信支持主从服务商高可用。
安装方法
composer require mingyuanyun/yii2-imessage
配置
在配置文件中components中添加iMessage组件,以下是demo:
'iMessage' => [
'class' => 'iMessage\Message',
'config' => [
'channels'=>[
'mail' => [
'username' => 'yunlianadxxxxxxx',
'password' => 'uXXHLB7Zxxxxxx',
'class' => 'Swift_SmtpTransport',// 选填
'host' => 'smtp.exmail.qq.com',// 选填
'port' => '465',// 选填
'encryption' => 'ssl',// 选填
'charset' => 'UTF-8',// 选填
'from' => ['yunlianadmin@mingyuanyun.com' => '明源云链'],// 选填
],
'qy-wx' => [
'appId' => 'wxfe3aa6cxxxxxx',
'appSecret' => '1X1z8GwVEy7TBxxxxxx',
'agentId' => 1000050,
'compatId' => '企业微信登录',// 选填
],
'sms' => [// 公共组消息配置
'merchantType'=>'publicSms',
'host'=>'http://sms-test.myyscm.com',
'account'=>'jgtest',
'key'=>'xxxxxxx',
'slave' => [
'merchantType' => 'aliyunSms',
'accessKeyId' => 'xxxx',
'accessSecret' => 'xxxx',
],
'templateProvider' => '\services\SmsTemplateProvider' // 选填
],
'app' => [// 根据实际用到的设备选择性填写
'huawei' => [
'appPkgName' => '', // 包名
'clientId' => '', // 应用id
'clientSecret' => '' // 应用密钥
],
'huawei-v2' => [
'appPkgName' => '', // 包名
'clientId' => '', // 应用id
'clientSecret' => '' // 应用密钥
],
'meizu' => [
'appPkgName' => '', // 包名
'appId' => '', // 应用id
'appSecret' => '' // 应用密钥
],
'xiaomi' => [
'appPkgName' => '', // 包名
'appSecret' => '' // 应用密钥
],
'oppo' => [
'appPkgName' => '', // 包名
'appKey' => '', // 应用id
'masterSecret' => '' // 应用密钥
],
'vivo' => [
'appPkgName' => '', // 包名
'appId' => '', // 应用id
'appKey' => '', // 应用key
'appSecret' => '' // 应用密钥
],
'ios' => [
'isSandBox' => true, // 是否调试包
'certPath' => '', // pem格式推送证书本地绝对路径
'password' => '123', // 推送证书密码
],
'ios-token' => [
'isSandBox' => true,
'teamId' => 'D4GSYVE6CN', // 开发者帐号teamId
'keyId' => '99BYW4U4SZ', // token认证keyId
'secretContent' => $iosCertContent, // 密钥内容,有值时忽略secretFile
'secretFile' => 'xxx.p8', // token认证密钥文件本地绝对路径
'bundleId' => 'com.mysoft.mdev' // 应用ID
]
]
],
'eventHandler'=>'\services\MsgEventHandler', // 选填
]
]
以上sms配置部为公共组消息配置,下面是阿里云消息配置的demo:
'iMessage' => [
'class' => 'iMessage\Message',
'config' => [
'channels'=>[
.
.
.
'sms' => [// 阿里云消息配置
'merchantType'=>'aliyunSms',
'accessKeyId'=>'xxxxxx',
'accessSecret'=>'xxxxxx',
'regionId'=>'xxxxxxx',
'slave' => [
'merchantType' => 'publicSms',
'host'=>'http://sms-test.myyscm.com',
'account'=>'jgtest',
'key'=>'xxxxxxx',
],
'templateProvider' => '\services\SmsTemplateProvider' // 选填
],
]
]
]
详细配置参数说明:
属性 | 含义 | 说明 |
---|---|---|
channels.mail.class | 邮件类 | 选填,默认为 Swift_SmtpTransport |
channels.mail.host | 邮件host | 选填,默认为 'smtp.exmail.qq.com' |
channels.mail.username | 邮件账号 | 必填 |
channels.mail.password | 邮件密码 | 必填 |
channels.mail.port | 邮件端口 | 选填,默认为465 |
channels.mail.encryption | 邮件加密方式 | 选填,默认为 ssl |
channels.mail.charset | 邮件编码 | 选填,默认为 UTF-8 |
channels.mail.from | 邮件来源 | 选填 |
channels.qy-wx.appId | 企业微信appid | 必填 |
channels.qy-wx.appSecret | 企业微信密钥 | 必须 |
channels.qy-wx.agentId | 企业微信应用id | 必须 |
channels.qy-wx.compatId | 企业微信应用名称兼容id | 选填 |
channels.sms.merchantType | 商户类型 | 必须,publicSms 为公共组短信,aliyunSms 为阿里云短信 |
channels.sms.templateProvider | 短信模版数据,用于发送时根据code获取模版信息 | 选填 |
channels.sms.slave | 短信备用服务商 | 选填,主服务商发送失败会尝试从服务商(slave)进行发送 |
channels.sms.host | 公共组短信host | 商户类型为 publicSms 必填 |
channels.sms.account | 公共组短信账号 | 商户类型为 publicSms 必填 |
channels.sms.key | 公共组短信密钥 | 商户类型为 publicSms 必填 |
channels.sms.accessKeyId | 阿里云短信keyid | 商户类型 为aliyunSms 必填 |
channels.sms.accessSecret | 阿里云短信密钥 | 商户类型为 aliyunSms 必填 |
channels.sms.regionId | 区域id | 商户类型为 aliyunSms 选填,默认为 cn-hangzhou |
channels.app | APP消息配置 | 根据用到的设备类型填写即可 |
eventHandler | 事件监听类 | 选填 |
channels.qy-wx.compatId 配置说明:
如果项目之前已经应用了企业微信,并配置了应用名称参数,需要保证两边应用名称id(compatId)一致
channels.sms.templateProvider 配置说明:
由业务关联code为键,模版内容为内容体,可以直接以数组格式填入,也可以实现
\iMessage\interfaces\SmsTemplateProviderInterface 接口,以类的方式提供,推荐后种方式。
调用示例
1. 邮件消息
// 创建消息代理
$agent = \Yii::$app->iMessage->createClient();
// 注:详细参数说明请看README.md
// 视图模版消息
$mailMsg = new \iMessage\message\MailMessage();
$mailMsg->to = 'liuyx02@mingyuanyun.com'; // 发送对象邮件地址
$mailMsg->subject = '测试消息标题'; // 标题
$mailMsg->view = 'api-doc/create'; // 视图路径
$mailMsg->viewParams = ['account' => '张三', 'cn_name' => 'zhangs', 'code' => '123456']; // 视图参数
$mailMsg->cc = ['xx@qq.com', 'yy@qq.com']; // 复制接收者电子邮件地址
$mailMsg->attachments = ['./robots.txt','https://test-jgxl.oss-cn-shenzhen.aliyuncs.com/xxx/xxx.png']; // 附件(可选)
$agent->send($mailMsg);// 发送消息,直接返回true or false
$result = $agent->getLastResponse(); // 获取最后一次发送的结果
// 文本消息
$mailMsg = new \iMessage\message\MailMessage();
$mailMsg->to = 'liuyx02@mingyuanyun.com'; // 发送对象邮件地址
$mailMsg->subject = '测试消息标题'; // 标题
$mailMsg->textBody = '消息内容'; // 文本消息内容
$agent->send($mailMsg);// 发送消息,直接返回true or false
$result = $agent->getLastResponse(); // 获取最后一次发送的结果
// html消息
$mailMsg = new \iMessage\message\MailMessage();
$mailMsg->to = 'liuyx02@mingyuanyun.com'; // 发送对象邮件地址
$mailMsg->subject = '测试消息标题'; // 标题
$mailMsg->htmlBody = '<h1>消息内容</h1>'; // html消息内容
$agent->send($mailMsg);// 发送消息,直接返回true or false
$result = $agent->getLastResponse(); // 获取最后一次发送的结果
请求参数说明:
属性 | 含义 | 说明 |
---|---|---|
to | (邮件)发送对象邮件地址 | 邮件消息必填,可传字符串或数组 |
subject | (邮件)标题 | 邮件消息必填 |
view | (邮件)用于呈现消息正文的视图 | 邮件消息选填 |
viewParams | (邮件)消息参数 | 邮件消息选填 |
cc | (邮件)复制接收者电子邮件地址 | 邮件消息选填 |
textBody | (邮件)文本消息体 | 邮件消息选填 |
htmlBody | (邮件)html格式消息体 | 邮件消息选填 |
attachments | (邮件)附件 | 附件地址选填 |
--- |
2. 企业微信消息
// 创建消息代理
$agent = \Yii::$app->iMessage->createClient();
// 注:详细参数说明请看README.md
// 简单文本消息
$qywxMsg = new \iMessage\message\QywxMessage();
$qywxMsg->type = 'text'; // 消息类型
$qywxMsg->to = 'liuyx02'; // 发送对象
$qywxMsg->content = '消息内容'; // 消息内容体
$agent->send($qywxMsg);// 发送消息,直接返回true or false
$result = $agent->getLastResponse(); // 获取最后一次发送的结果
// markdown文本消息
$qywxMsg = new \iMessage\message\QywxMessage();
$qywxMsg->type = 'markdown'; // 消息类型
$qywxMsg->to = 'liuyx02'; // 发送对象
$qywxMsg->content = '# 消息内容'; // 消息内容体
$agent->send($qywxMsg);// 发送消息,直接返回true or false
$result = $agent->getLastResponse(); // 获取最后一次发送的结果
// 卡片消息
$qywxMsg = new \iMessage\message\QywxMessage();
$qywxMsg->type = 'textcard'; // 消息类型
$qywxMsg->to = 'liuyx02'; // 发送对象
$qywxMsg->content = '消息内容'; // 消息内容体
$qywxMsg->subject = '消息标题'; // 消息标题
$qywxMsg->url = 'http://baidu.com'; // 详情链接
$qywxMsg->btntxt = '详情'; // 按钮文字
$agent->send($qywxMsg);// 发送消息,直接返回true or false
$result = $agent->getLastResponse(); // 获取最后一次发送的结果
return $result;
请求参数说明:
属性 | 含义 | 说明 |
---|---|---|
to | (企业微信)发送对象 | 企业微信消息必填,可传字符串或数组 |
content | (企业微信)内容体 | 企业微信消息必填 |
type | (企业微信)消息类型 | 内容类型,默认text,可选text、markdown、textcard |
subject | (企业微信)标题 | 内容类型为 textcard 时必填 |
url | (企业微信)详情链接 | 内容类型为 textcard 时必填 |
btntxt | (企业微信)按钮文字 | 内容类型为 textcard 时必填 |
3. 短信(公共组消息中心)消息
// 创建消息代理
$agent = \Yii::$app->iMessage->createClient();
// 注:详细参数说明请看README.md
// 当应用配置短信消息渠道商户类型( merchantType )设置为 `publicSms`时,走公共组消息中心通道
// 1.模版消息
$smsMsg = new \iMessage\message\SmsMessage();
$smsMsg->contentType = 'template'; // 内容类型
$smsMsg->to = '15521155161'; // 发送对象
$smsMsg->templateId = '39edc15f-7b16-1536-c7f7-a40dc7bb6c0a'; // 模版id
$smsMsg->templateParam = ['432532']; // 模版参数
$smsMsg->options = ['tenantCode' => '34343', 'appCode' => '3444']; // 可选参数,默认发送到消息中心
$agent->send($smsMsg);// 发送消息,直接返回true or false
$result = $agent->getLastResponse(); // 获取最后一次发送的结果
// 2.自定义消息
$smsMsg = new \iMessage\message\SmsMessage();
$smsMsg->contentType = 'custom'; // 内容类型
$smsMsg->to = '15521155161'; // 发送对象
$smsMsg->templateId = '39ee5289-caf2-4b38-1c70-d59b3135f382'; // 模版id
$smsMsg->content = '首易自定义内容'; // 自定义消息内容
$agent->send($smsMsg);// 发送消息,直接返回true or false
$result = $agent->getLastResponse(); // 获取最后一次发送的结果
// 3.语音消息
$smsMsg = new \iMessage\message\SmsMessage();
$smsMsg->contentType = 'voice'; // 内容类型
$smsMsg->to = '15521155161'; // 发送对象
$smsMsg->templateId = '39edc27b-87d4-50aa-0936-be587038e9a4'; // 模版id
$smsMsg->voiceTemplateCode = '432532'; // 语音验证码
$agent->send($smsMsg);// 发送消息,直接返回true or false
$result = $agent->getLastResponse(); // 获取最后一次发送的结果
// 4.可通过在应用配置下配置 channels.sms.templateProvider 参数的方式,从配置文件获取配置,详情请看 \demo\DemoSmsTemplateProvider.php 文件,以下时调用demo
$smsMsg = new \iMessage\message\SmsMessage();
$smsMsg->code = 'yf-AppCheckRoom-ForgetPassword'; // 传入code后可以不写 templateId 及 signName 字段
$smsMsg->contentType = 'template'; // 内容类型
$smsMsg->to = '15521155161'; // 发送对象
$smsMsg->templateParam = ['432532']; // 模版参数
$smsMsg->options = ['code' => '432532', 'product' => 'liuyx02']; // 可选参数,默认发送到消息中心
$agent->send($smsMsg);// 发送消息,直接返回true or false
$result = $agent->getLastResponse(); // 获取最后一次发送的结果
// 5.应用配置加了slave的配置后如果主 master 短信服务发送失败,会尝试从 slave 短信服务发送。
// 短信消息还支持强制选定某个短信服务商进行发送
$agent = \Yii::$app->iMessage->createClient();
$smsMsg = new \iMessage\message\SmsMessage();
// 填master只发主短信服务商;填slave只发从短信服务商;默认为auto,主服务商发送失败尝试从服务商发送
$smsMsg->selected = 'slave';
$smsMsg->code = 'yf-AppCheckRoom-ForgetPassword'; // 传入code后可以不写 templateId 及 signName 字段
$smsMsg->contentType = 'template'; // 内容类型
$smsMsg->to = '15521155161'; // 发送对象
$smsMsg->options = ['tenantCode' => '34343', 'appCode' => '3444']; // 可选参数,默认发送到消息中心
$agent->send($smsMsg);// 发送消息,直接返回true or false
$result = $agent->getLastResponse(); // 获取最后一次发送的结果
请求参数说明:
属性 | 含义 | 说明 |
---|---|---|
to | (短信)发送对象手机号码 | 短信消息必填,可传字符串或数组 |
contentType | (短信)内容类型 | 可选 custom(自定义消息)、template(模版消息)、voice(语音消息);默认为 template(模版消息) |
templateId | (短信)消息模版id | 必填 |
templateParam | (短信)消息模版参数 | 内容类型为 template 时必填 |
code | (短信)模版数据 templateProvider 的键名 | 选填 |
voiceTemplateCode | (短信)语音验证码 | 内容类型为 voice 时必填 |
content | (短信)短信内容体 | 内容类型为 custom 时必填 |
options | (短信)默认发送到消息中心 | 选填 |
4. 短信(阿里云消息服务)消息
// 创建消息代理
$agent = \Yii::$app->iMessage->createClient();
// 注:详细参数说明请看README.md
// 当应用配置短信消息渠道商户类型( merchantType )设置为 `aliyunSms`时,走阿里云消息服务通道
// 一次请求中向多个不同的手机号码发送 同样内容 的短信
$smsMsg = new \iMessage\message\SmsMessage();
$smsMsg->to = '155211551xx'; // 发送对象
$smsMsg->templateId = 'SMS_66835xxxx'; // 模版id
$smsMsg->templateParam = ['code' => '432532', 'product' => '云链erp']; // 模版参数
$smsMsg->signName = '测试签名'; // 短信签名名称,当商户类型为aliyunSms是必填
$agent->send($smsMsg);// 发送消息,直接返回true or false
$result = $agent->getLastResponse(); // 获取最后一次发送的结果
// 一次请求中分别向多个不同的手机号码发送不同签名的短信。
$smsMsg = new \iMessage\message\SmsMessage();
$smsMsg->to = ['15521155xx', '135328650xx']; // 发送对象
$smsMsg->templateId = 'SMS_66835xxxx'; // 模版id
$smsMsg->templateParam = [['code' => '432532', 'product' => '云链erp'], ['code' => '432322', 'product' => '云链erp']]; // 模版参数
$smsMsg->signName = ['测试签名', '测试签名2']; // 短信签名名称,当商户类型为aliyunSms是必填
$agent->send($smsMsg);// 发送消息,直接返回true or false
$result = $agent->getLastResponse(); // 获取最后一次发送的结果
请求参数说明:
属性 | 含义 | 说明 |
---|---|---|
to | (短信)发送对象手机号码 | 短信消息必填,可传字符串或数组 |
templateId | (短信)消息模版id | 必填 |
templateParam | (短信)消息模版参数 | 必填,数组格式 |
signName | (短信)短信签名名称 | 当商户类型为aliyunSms是必填,可填字符串或数组 |
5. APP 消息
app消息调用了 yunchuang/push 扩展来发送app消息。
// 创建消息代理
$agent = \Yii::$app->iMessage->createClient();
$appMsg = new \iMessage\message\AppMessage();
$appMsg->gateway = 'xiaomi'; // 通道类型
$appMsg->to = 'lqMU8xjpFwgeDQzgFOeEhq/DXiDaHCKxqvDyZKYHUtUmOS9VR1SOJ6c42s190GyZ'; // 发送对象
$appMsg->businessId = 12345678; // 业务ID
$appMsg->title = 'test title'; // 标题
$appMsg->subTitle = 'subTitle'; // 内容
$appMsg->content = 'test content'; // 内容
$appMsg->extra = ['key1' => 'v1', 'key2' => 2]; // 自定义数据
$appMsg->options = ['token' => 'CFx88jTVr6adjsh6eVOLvhtqnDlhLxb7CljykbXxu7vLsnexatUJZM1lqXHPzfnurD0gknQnIu7SRvWhAPx/zQ=='];
$agent->send($appMsg);// 发送消息,直接返回true or false
$result = $agent->getLastResponse(); // 获取最后一次发送的结果
请求参数说明:
属性 | 含义 | 说明 |
---|---|---|
to | 目标设备id | 必填,可传可传字符串或数组 |
gateway | 网关渠道 | 必填,可填huawei(华为),huawei-v2(华为新版),xiaomi(小米),meizu(魅族),oppo(Oppo),vivo(Vivo),ios(苹果-基于推送证书认证),ios-token(苹果-基于token认证)及自定义网关名 |
businessId | 业务ID,相同业务ID只推送一次 | 必填 |
title | 标题 | 必填 |
subTitle | 副标题 | 选填 |
content | 内容 | 必填 |
badge | 角标 | 选填 |
extra | 服务端传给APP的自定义数据,数组格式 | 选填,建议转换为json字符串后长度不超过1024字节 |
callback | 送达回执地址 | 选填, 供推送厂商调用,最大128个字节,具体请查阅各厂商文档。华为仅支持在应用管理中心配置;魅族需在管理后台注册回执地址,每次推送时也需指定回执地址;苹果ios-token通道由SDK调用回执 |
callbackParam | 自定义回执参数 | 选填 |
notifyId | 聚合标签 | 选填,同标签消息在通知栏只显示一条。小米通道支持,字母、数字组合不超过8位 |
gatewayOptions | 厂商扩展参数 | 选填 |
options | 附加信息 | 选填 |
gatewayOptions 厂商扩展参数说明:
考虑到各厂商均有自己特有的参数,故提供此扩展参数来提供支持。如果扩展参数与通用参数有冲突,则取扩展参数中值。 参数类型为以厂商通道为键名的数组,格式如下:
[ "huawei": 与华为消息格式一致,下同, "xiaomi": xxx, "vivo": xxx, "oppo": xxx, "meizu": xxx, "ios-token": xxx ]
示例:
$appMsg->gatewayOptions = [
'xiaomi' => [
'extra.notify_foreground' => '1',
],
'huawei' => [
'hps' => [
'ext' => [
'badgeAddNum' => '1',
'badgeClass' => 'com.mysoft.core.activity.LauncherActivity',
]
]
]
];
options 附加信息说明:
参数 | 类型 | 说明 |
---|---|---|
token | string | 认证token |
push | MingYuanYun\Push\Support\ApnsPush | iOS证书推送实例,考虑到文件I/O问题,故此设计 |
5. 更多功能
// 1.支持绑定事件
// 在应用配置直接注入到 `eventHandler` 字段即可,然后继承 \iMessage\base\MsgEventHandlerBase 类进行
//个性化操作,可参考 demo 目录下 MsgEventHandler.php 文件。
// 2. 短信可通过在应用配置下配置 channels.sms.templateProvider 参数的方式,从配置文件获取配置,详情请看 \demo\DemoSmsTemplateProvider.php 文件,以下时调用demo
$agent = \Yii::$app->iMessage->createClient();
$smsMsg = new \iMessage\message\SmsMessage();
$smsMsg->contentType = 'template'; // 内容类型
$smsMsg->to = '15521155161'; // 发送对象
$smsMsg->code = 'yf-AppCheckRoom-ForgetPassword'; // 传入code后可以不写 templateId 及 signName 字段
$smsMsg->options = ['tenantCode' => '34343', 'appCode' => '3444']; // 可选参数,默认发送到消息中心
$agent->send($smsMsg); // 发送消息,直接返回true or false
$result = $agent->getLastResponse(); // 获取最后一次发送的结果
// 3. 短信高可用(支持master-slave),也支持强制选定某个短信服务商进行发送
// 可通过在应用配置下配置 channels.sms.slave 配置备用短信服务商
$agent = \Yii::$app->iMessage->createClient();
$smsMsg = new \iMessage\message\SmsMessage();
// 填master只发主短信服务商;填slave只发从短信服务商;默认为auto,主服务商发送失败尝试从服务商发送
$smsMsg->selected = 'slave';
$smsMsg->code = 'yf-AppCheckRoom-ForgetPassword'; // 传入code后可以不写 templateId 及 signName 字段
$smsMsg->contentType = 'template'; // 内容类型
$smsMsg->to = '15521155161'; // 发送对象
$smsMsg->options = ['tenantCode' => '34343', 'appCode' => '3444']; // 可选参数,默认发送到消息中心
$agent->send($smsMsg);// 发送消息,直接返回true or false
$result = $agent->getLastResponse(); // 获取最后一次发送的结果
返回结果
获取返回结果:
// 发送消息后,通过 getLastResponse 方法获取最后一次发送返回结果
$agent = \Yii::$app->iMessage->createClient();
$agent->send($smsMsg);
$result = $agent->getLastResponse(); // 获取返回结果
默认返回结果示例:
{
"msg_type": "sms",
"errcode": 0,
"errmsg": "ok",
"original": {
"code": 0,
"data": "39f634f1-cc46-baa3-f334-1203a2f1e4cd"
}
}
短信除了以上配置还会有商户类型字段返回,且如果配置了slave配置且调用了slave发送短信slave的结果会覆盖master的结果(除了original字段的数据不覆盖,而是增加slave的结果到original的slave字段),以下为结果示例:
{
"msg_type": "sms",
"errcode": -1,
"errmsg": "商户无响应",
"original": {
"code": -1,
"data": "39f65e46-c447-69af-13ab-87f26b221c8a",
"slave": {
"Message": "error",
"RequestId": "F007FD52-9AD7-4195-BC9D-E6609E86E9BE",
"BizId": "860507994709634306^0",
"Code": "error"
},
},
"merchantType": "publicsms"
}
返回结果参数说明:
属性 | 参数类型 | 含义 |
---|---|---|
msg_type | string | 消息类型 |
errcode | int | 错误码,0表示发送成功 |
errmsg | string | 错误信息 |
original | array | 消息原始返回结果 |
original.slave | array | 备选商户消息原始返回结果 |
merchantType | string | 短信商户类型 |
更多请查看 Demo 。