PHP 服务端友盟推送
以前也用过友盟推送,但是整合的方法当时没整理
结果前段时间在使用的时候,找不到了诶
友盟推送文档地址:https://developer.umeng.com/docs/67966/detail/68343
于是再次百度了一番
找到了现在这篇,整合的比较不错,适合我这种面向百度编程的
废话不多说
直接开始
首先对应配置
在友盟 的 应用中找到对应Android与ios的 AppKey 和 App Master Secret
或者对应配置信息并在配置中配置
'umeng' => [ 'android_app_key' => '####', //友盟android AppKey 'android_app_secret' => '####', //友盟android App Master Secret 'ios_app_key' => '####', //友盟ios AppKey 'ios_app_secret' => '####', //友盟android App Master Secret ],
然后推送核心类库
代码如下:
<?php namespace umeng; /** * 友盟消息 安卓 IOS 推送类 * */ class Push { protected $host; //发送地址 protected $app_key; //appkey protected $appMasterSecret; //app secret protected $description; //app secret // public function __construct($options = null) { if (is_array($options)) { $this->host = 'https://msgapi.umeng.com/api/send'; $this->app_key = $options['app_key']; $this->appMasterSecret = $options['appMasterSecret']; $this->description = "友盟接口推送"; } else { return false; } } /** * @param $info * @param $device_token * @return mixed|string * 用户单播 和 列播 */ public function Android_Device_Push($info, $device_token) { $data['appkey'] = $this->app_key; $data['timestamp'] = time(); //时间戳 if (is_array($device_token)) { //批量用户列播 $data['type'] = 'listcast'; $data['device_tokens'] = implode(',', $device_token); //数组转字符串 } else { //一个用户单播 $data['type'] = 'unicast'; $data['device_tokens'] = $device_token; } //payload内容 $data['payload']['display_type'] = 'notification'; //通知消息 //payload body内容 $data['payload']['body']['after_open'] = "go_custom"; //后续操作打开app $data['payload']['body']['ticker'] = $info['ticker']; $data['payload']['body']['title'] = $info['title']; $data['payload']['body']['text'] = $info['title']; //广播通知不能为空补填 //这里可以写附加字段 $data['payload']['extra']['type'] = $info['type']; //附加字段类型 $data['production_mode'] = $info['production_mode']; $data['description'] = $this->description; return $this->send($data, $this->host, $this->appMasterSecret); } /** * @param $info * @return mixed|string * 广播 */ public function Android_Broadcast($info) { $data['appkey'] = $this->app_key; $data['timestamp'] = time(); //时间戳 //广播消息 $data['type'] = 'broadcast'; //payload内容 $data['payload']['display_type'] = 'notification'; //通知消息 //payload body内容 $data['payload']['body']['after_open'] = "go_custom"; //后续操作打开app $data['payload']['body']['ticker'] = $info['ticker']; $data['payload']['body']['title'] = $info['title']; $data['payload']['body']['text'] = $info['title']; //广播通知不能为空补填 $data['payload']['extra']['type'] = $info['type']; //附加字段类型1 跳转消息详情 $data['payload']['extra']['prod_id'] = $info['prod_id']; //附加字段消息详情id $data['payload']['extra']['text'] = $info['text']; // $data['production_mode'] = $info['production_mode']; $data['description'] = $this->description; return $this->send($data, $this->host, $this->appMasterSecret); } /** * @param $info * @param $device_token * @return mixed|string * 单播 和 列播 */ public function Ios_Device_Push($info, $device_token) { $data = array(); $data['appkey'] = $this->app_key; $data['timestamp'] = time(); //时间戳 if (is_array($device_token)) { //批量用户列播 $data['type'] = 'listcast'; $data['device_tokens'] = implode(',', $device_token); //数组转字符串 } else { //一个用户单播 $data['type'] = 'unicast'; $data['device_tokens'] = $device_token; } //payload内容 $data['payload']['aps']['alert'] = $info['text']; //消息主体 $data['payload']['aps']['sound'] = 'default'; //声音 $data['payload']['type'] = $info['type']; //消息类型 0打开消息详情 $data['payload']['prod_id'] = $info['prod_id']; //消息id $data['payload']['title'] = $info['title']; $data['payload']['text'] = $info['text']; // $data['production_mode'] = $info['production_mode']; $data['description'] = $this->description; return $this->send($data, $this->host, $this->appMasterSecret); } public function Ios_Broadcast($info) { $data = array(); $data['appkey'] = $this->app_key; $data['timestamp'] = time(); //时间戳 //广播消息 $data['type'] = 'broadcast'; //payload内容 $data['payload']['aps']['alert'] = $info['title']; //消息主体 $data['payload']['aps']['sound'] = 'chime'; //声音 $data['payload']['aps']['badge'] = 1; //显示角标 $data['payload']['type'] = $info['type']; //消息类型 0打开消息详情 $data['payload']['prod_id'] = $info['prod_id']; //消息id $data['payload']['title'] = $info['title']; $data['payload']['text'] = $info['ticker']; // $data['production_mode'] = $info['production_mode']; $data['description'] = $this->description; return $this->send($data, $this->host, $this->appMasterSecret); } /** * @param $data * @param $url_s * @param $appMasterSecret * @return mixed|string * curl 请求 */ private function send($data, $url_s, $appMasterSecret) { $postBody = json_encode($data); //加密 $sign = md5("POST" . $url_s . $postBody . $appMasterSecret); $url = $url_s . "?sign=" . $sign; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_setopt($ch, CURLOPT_POSTFIELDS, $postBody); $result = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $curlErrNo = curl_errno($ch); $curlErr = curl_error($ch); curl_close($ch); // print_r($result); // exit; if ($httpCode == "0") { // Time out return ("Curl error number:" . $curlErrNo . " , Curl error details:" . $curlErr . "\r\n"); } else if ($httpCode != "200") { return ("Http code:" . $httpCode . " details:" . $result . "\r\n"); } else { return $result; } } } ?>
调用方法示例:
use umeng\Push; function umengsend($device_token) { $info['ticker'] = '推送测试提示栏'; #提示栏文字 $info['title'] ='推送测试标题'; #通知标题 $info['text'] = '推送测试文字描述'; #文字描述 $info['type'] = 4; //附加字段类型1 跳转消息详情 $info['production_mode'] = 'false'; $info['prod_id'] = ""; #IOS 单播与广播 $options_ios = [ 'app_key' => config('umeng.ios_app_key'), 'appMasterSecret' => config('umeng.ios_app_secret'), ]; $ios_umeng = new Push($options_ios); #IOS单播 $ios_umeng->Ios_Device_Push($info,$device_token); #IOS广播 $ios_umeng->Ios_Broadcast($info); #Android 单播与广播 $options_android = [ 'app_key' => config('umeng.android_app_key'), 'appMasterSecret' => config('umeng.android_app_secret'), ]; $android_umeng = new Push($options_android); #安卓单播 $android_umeng->Android_Device_Push($info,$device_token); #安卓广播 $android_umeng->Android_Broadcast($info); }
自己使用:
#推送相关设定 use umeng\Push; #公共测试 #$title 通知标题 #$text 文字描述 #$type 类型 1单播2广播 #$userlist device_token 列表 function umengpublic($title,$text,$type="1",$userlist=[]) { $info = []; $info['ticker'] = $title; #提示栏文字 $info['title'] = $title; #通知标题 $info['text'] = $text; #文字描述 $info['type'] = 4; //附加字段类型1 跳转消息详情 $info['production_mode'] = 'false'; #false 测试 true 正式 $info['prod_id'] = ""; if($type == '1') { umengpushuser($info,$userlist); }else{ umengpushpublic($info); } return true; } #公共推送 -- 广播 function umengpushpublic($info) { #安卓广播 $android_umeng = new Push(['app_key' => config('umeng.android_app_key'),'appMasterSecret' => config('umeng.android_app_secret')]); $android_umeng->Android_Broadcast($info); ######################################### #IOS广播 $ios_umeng = new Push(['app_key' => config('umeng.ios_app_key'),'appMasterSecret' => config('umeng.ios_app_secret')]); $ios_umeng->Ios_Broadcast($info); return true; } #公共推送 -- 单播 function umengpushuser($info,$userlist) { #对应相关用户 $userlists = []; #获取device_token 列表 foreach($userlists as $key=>$val) { #安卓单推 if($val['ismodel'] == '1') { #安卓配置 $android_umeng = new Push(['app_key' => config('umeng.android_app_key'),'appMasterSecret' => config('umeng.android_app_secret')]); $android_umeng->Android_Device_Push($info,$val['device_token']); } #ios 单推 else if($val['ismodel'] == '2') { #IOS配置 $ios_umeng = new Push(['app_key' => config('umeng.ios_app_key'),'appMasterSecret' => config('umeng.ios_app_secret')]); $ios_umeng->Ios_Device_Push($info,$val['device_token']); } else { // return } } return true; }
附录::
推送相关参数
Android:
{ "appkey":"xx", // 必填,应用唯一标识 "timestamp":"xx", // 必填,时间戳,10位或者13位均可,时间戳有效期为10分钟 "type":"xx", // 必填,消息发送类型,其值可以为: // unicast-单播 // listcast-列播,要求不超过500个device_token // filecast-文件播,多个device_token可通过文件形式批量发送 // broadcast-广播 // groupcast-组播,按照filter筛选用户群, 请参照filter参数 // customizedcast,通过alias进行推送,包括以下两种case: // - alias: 对单个或者多个alias进行推送 // - file_id: 将alias存放到文件后,根据file_id来推送 "device_tokens":"xx", // 当type=unicast时, 必填, 表示指定的单个设备 // 当type=listcast时, 必填, 要求不超过500个, 以英文逗号分隔 "alias_type": "xx", // 当type=customizedcast时, 必填 // alias的类型, alias_type可由开发者自定义, 开发者在SDK中 // 调用setAlias(alias, alias_type)时所设置的alias_type "alias":"xx", // 当type=customizedcast时, 选填(此参数和file_id二选一) // 开发者填写自己的alias, 要求不超过500个alias, 多个alias以英文逗号间隔 // 在SDK中调用setAlias(alias, alias_type)时所设置的alias "file_id":"xx", // 当type=filecast时,必填,file内容为多条device_token,以回车符分割 // 当type=customizedcast时,选填(此参数和alias二选一) // file内容为多条alias,以回车符分隔。注意同一个文件内的alias所对应 // 的alias_type必须和接口参数alias_type一致。 // 使用文件播需要先调用文件上传接口获取file_id,参照"文件上传" "filter":{}, // 当type=groupcast时,必填,用户筛选条件,如用户标签、渠道等,参考附录G。 // filter的内容长度最大为3000B) "payload": { // 必填,JSON格式,具体消息内容(Android最大为1840B) "display_type":"xx", // 必填,消息类型: notification(通知)、message(消息) "body": { // 必填,消息体。 // 当display_type=message时,body的内容只需填写custom字段。 // 当display_type=notification时,body包含如下参数: // 通知展现内容: "ticker":"xx", // 必填,通知栏提示文字 "title":"xx", // 必填,通知标题 "text":"xx", // 必填,通知文字描述 // 自定义通知图标: "icon":"xx", // 可选,状态栏图标ID,R.drawable.[smallIcon], // 如果没有,默认使用应用图标。 // 图片要求为24*24dp的图标,或24*24px放在drawable-mdpi下。 // 注意四周各留1个dp的空白像素 "largeIcon":"xx", // 可选,通知栏拉开后左侧图标ID,R.drawable.[largeIcon], // 图片要求为64*64dp的图标, // 可设计一张64*64px放在drawable-mdpi下, // 注意图片四周留空,不至于显示太拥挤 "img": "xx", // 可选,通知栏大图标的URL链接。该字段的优先级大于largeIcon。 // 该字段要求以http或者https开头。 // 自定义通知声音: "sound": "xx", // 可选,通知声音,R.raw.[sound]。 // 如果该字段为空,采用SDK默认的声音,即res/raw/下的 // umeng_push_notification_default_sound声音文件。如果 // SDK默认声音文件不存在,则使用系统默认Notification提示音。 // 自定义通知样式: "builder_id": xx, // 可选,默认为0,用于标识该通知采用的样式。使用该参数时, // 开发者必须在SDK里面实现自定义通知栏样式。 // 通知到达设备后的提醒方式,注意,"true/false"为字符串 "play_vibrate":"true/false", // 可选,收到通知是否震动,默认为"true" "play_lights":"true/false", // 可选,收到通知是否闪灯,默认为"true" "play_sound":"true/false", // 可选,收到通知是否发出声音,默认为"true" // 点击"通知"的后续行为,默认为打开app。 "after_open": "xx", // 可选,默认为"go_app",值可以为: // "go_app": 打开应用 // "go_url": 跳转到URL // "go_activity": 打开特定的activity // "go_custom": 用户自定义内容。 "url": "xx", // 当after_open=go_url时,必填。 // 通知栏点击后跳转的URL,要求以http或者https开头 "activity":"xx", // 当after_open=go_activity时,必填。 // 通知栏点击后打开的Activity "custom":"xx"/{} // 当display_type=message时, 必填 // 当display_type=notification且 // after_open=go_custom时,必填 // 用户自定义内容,可以为字符串或者JSON格式。 }, extra:{ // 可选,JSON格式,用户自定义key-value。只对"通知" // (display_type=notification)生效。 // 可以配合通知到达后,打开App/URL/Activity使用。 "key1": "value1", "key2": "value2", ... } }, "policy":{ // 可选,发送策略 "start_time":"xx", // 可选,定时发送时,若不填写表示立即发送。 // 定时发送时间不能小于当前时间 // 格式: "yyyy-MM-dd HH:mm:ss"。 // 注意,start_time只对任务类消息生效。 "expire_time":"xx", // 可选,消息过期时间,其值不可小于发送时间或者 // start_time(如果填写了的话), // 如果不填写此参数,默认为3天后过期。格式同start_time "max_send_num": xx, // 可选,发送限速,每秒发送的最大条数。最小值1000 // 开发者发送的消息如果有请求自己服务器的资源,可以考虑此参数。 "out_biz_no": "xx" // 可选,消息发送接口对任务类消息的幂等性保证。 // 强烈建议开发者在发送任务类消息时填写这个字段,友盟服务端会根据这个字段对消息做去重避免重复发送。 // 同一个appkey下面的多个消息会根据out_biz_no去重,不同发送任务的out_biz_no需要保证不同,否则会出现后发消息被去重过滤的情况。 // 注意,out_biz_no只对任务类消息有效。 }, "production_mode":"true/false", // 可选,正式/测试模式。默认为true // 测试模式只对“广播”、“组播”类消息生效,其他类型的消息任务(如“文件播”)不会走测试模式 // 测试模式只会将消息发给测试设备。测试设备需要到web上添加。 // Android: 测试设备属于正式设备的一个子集。 "description": "xx", // 可选,发送消息描述,建议填写。 //系统弹窗,只有display_type=notification生效 "mipush": "true/false", // 可选,默认为false。当为true时,表示MIUI、EMUI、Flyme系统设备离线转为系统下发 "mi_activity": "xx", // 可选,mipush值为true时生效,表示走系统通道时打开指定页面acitivity的完整包路径。 "channel_properties":{ //可选,厂商通道相关的特殊配置 "xiaomi_channel_id":"",//小米channel_id,具体使用及限制请参考小米推送文档 https://dev.mi.com/console/doc/detail?pId=2086 "vivo_classification":"1" , //vivo消息分类:0 运营消息,1 系统消息, 需要到vivo申请,具体使用及限制参考[vivo消息推送分类功能说明]https://dev.vivo.com.cn/documentCenter/doc/359 "oppo_channel_id":"xx" //可选, android8以上推送消息需要新建通道,否则消息无法触达用户。push sdk 6.0.5及以上创建了默认的通道:upush_default,消息提交厂商通道时默认添加该通道。如果要自定义通道名称或使用私信,请自行创建通道,推送消息时携带该参数 具体可参考 [oppo通知通道适配] https://open.oppomobile.com/wiki/doc#id=10289 } }
IOS相关参数:
{ "appkey":"xx", // 必填,应用唯一标识 "timestamp":"xx", // 必填,时间戳,10位或者13位均可,时间戳有效期为10分钟 "type":"xx", // 必填,消息发送类型,其值可以为: // unicast-单播 // listcast-列播,要求不超过500个device_token // filecast-文件播,多个device_token可通过文件形式批量发送 // broadcast-广播 // groupcast-组播,按照filter筛选用户群, 请参照filter参数 // customizedcast,通过alias进行推送,包括以下两种case: // - alias: 对单个或者多个alias进行推送 // - file_id: 将alias存放到文件后,根据file_id来推送 "device_tokens":"xx", // 当type=unicast时, 必填, 表示指定的单个设备 // 当type=listcast时, 必填, 要求不超过500个, 以英文逗号分隔 "alias_type": "xx", // 当type=customizedcast时, 必填 // alias的类型, alias_type可由开发者自定义, 开发者在SDK中 // 调用setAlias(alias, alias_type)时所设置的alias_type "alias":"xx", // 当type=customizedcast时, 选填(此参数和file_id二选一) // 开发者填写自己的alias, 要求不超过500个alias, 多个alias以英文逗号间隔 // 在SDK中调用setAlias(alias, alias_type)时所设置的alias "file_id":"xx", // 当type=filecast时,必填,file内容为多条device_token,以回车符分割 // 当type=customizedcast时,选填(此参数和alias二选一) // file内容为多条alias,以回车符分隔。注意同一个文件内的alias所对应 // 的alias_type必须和接口参数alias_type一致。 // 使用文件播需要先调用文件上传接口获取file_id,参照"2.4文件上传接口" "filter":{}, // 当type=groupcast时,必填,用户筛选条件,如用户标签、渠道等,参考附录G。 "payload": // 必填,JSON格式,具体消息内容(iOS最大为2012B) { "aps": // 必填,严格按照APNs定义来填写 { "alert":""/{ // 当content-available=1时(静默推送),可选; 否则必填。 // 可为JSON类型和字符串类型 "title":"title", "subtitle":"subtitle", "body":"body" } "badge": xx, // 可选 "sound": "xx", // 可选 "content-available":1 // 可选,代表静默推送 "category": "xx", // 可选,注意: ios8才支持该字段。 }, "key1":"value1", // 可选,用户自定义内容, "d","p"为友盟保留字段, // key不可以是"d","p" "key2":"value2", ... }, "policy": // 可选,发送策略 { "start_time":"xx", // 可选,定时发送时间,若不填写表示立即发送。 // 定时发送时间不能小于当前时间 // 格式: "yyyy-MM-dd HH:mm:ss"。 // 注意,start_time只对任务生效。 "expire_time":"xx", // 可选,消息过期时间,其值不可小于发送时间或者 // start_time(如果填写了的话), // 如果不填写此参数,默认为3天后过期。格式同start_time "out_biz_no": "xx" // 可选,消息发送接口对任务类消息的幂等性保证。 // 强烈建议开发者在发送任务类消息时填写这个字段,友盟服务端会根据这个字段对消息做去重避免重复发送。 // 同一个appkey下面的多个消息会根据out_biz_no去重,不同发送任务的out_biz_no需要保证不同,否则会出现后发消息被去重过滤的情况。 // 注意,out_biz_no只对任务类消息有效。 "apns_collapse_id": "xx" // 可选,多条带有相同apns_collapse_id的消息,iOS设备仅展示 // 最新的一条,字段长度不得超过64bytes }, "production_mode":"true/false" // 可选,正式/测试模式。默认为true // 测试模式只对“广播”、“组播”类消息生效,其他类型的消息任务(如“文件播”)不会走测试模式 // 测试模式只会将消息发给测试设备。测试设备需要到web上添加。 "description": "xx" // 可选,发送消息描述,建议填写。 }
分享完毕..
漫漫人生路,终究还是要找合得来的人...
2020年08月28日