项目需求:人员之间聊天,如果对方不在线,并且用APP登录过,则推送提示(此处主要是用单播)。
- 注:上次用了极光推送,因为项目的不同,这次项目用的是友盟推送。
1、安装包:
go get github.com/astaxie/beego/httplib
2、主体代码:
package tools
import (
"encoding/json"
"fmt"
"github.com/astaxie/beego/httplib"
"strconv"
"time"
)
//=========友盟的接口====固定值,一般不会变动=============
var hostUmengPush ="http://msg.umeng.com"
var uploadPath = "/upload"
var postPath = "/api/send"
//===========Android的APP Key和 秘钥,不同程序会不同=============
var appKeyAndroid ="xxx"
var masterSecreptAndroid ="xxx"
//===========IOS的APP Key和 秘钥,不同程序会不同===========
var appKeyIOS="xxx"
var masterSecretIOS="xxx"
// 推送是否是生成模式
var pushProductionMode = "true"
//设置前端收到通知后点击通知跳转的页面(这个是前端给的)
var pushAndroidActityChat = "xxx"
var pushAndroidActivityWeb = "xxx"
//========================================
type UmengAdroid struct {
Appkey string `json:"appkey"` // 必填项
Timestamp string `json:"timestamp"` // 必填项
Type string `json:"type"` // 必填项
DeviceTokens string `json:"device_tokens"` // 选填,用于给特定设备的推送
Production_mode string `json:"production_mode"`
Payload *PayloadAndroid `json:"payload"` // 必填项
Description string `json:"description"`
}
type PayloadAndroid struct {
Display_type string `json:"display_type"` // 必填项
Body *BodyAndroid `json:"body"` // 必填项
Extral map[string]string `json:"extra"`
}
type BodyAndroid struct {
Ticker string `json:"ticker"` // 必填项
Title string `json:"title"` // 必填项
Text string `json:"text"` // 必填项
After_open string `json:"after_open"` // 必填项
Activity string `json:"activity"` // 必填项
}
// android推送
// deviceToken:设备的编号,如果设置deviceToken,则是单播;如果未设置则是全播
func Push_android(title string, deviceToken string, extralDatas map[string]string) {
body := &BodyAndroid{}
// 必填 通知栏提示文字
body.Ticker = title
// 必填 通知标题
body.Title = "xxx"
// 必填 通知文字描述
body.Text = title
// 打开Android端的Activity
body.After_open = "go_activity"
payLoad := &PayloadAndroid{}
payLoad.Display_type = "notification"
payLoad.Body = body
/*
额外携带的信息
*/
payLoad.Extral = extralDatas
messageAndroid := UmengAdroid{}
messageAndroid.Appkey = appKeyAndroid
// 打开聊天
body.Activity = pushAndroidActityChat
if deviceToken == "" {
// 全播
messageAndroid.Type = "broadcast"
// 打开webview
body.Activity = pushAndroidActivityWeb
} else {
// 单播
messageAndroid.Type = "unicast"
messageAndroid.DeviceTokens = deviceToken
// 打开聊天
body.Activity = pushAndroidActityChat
}
timeInt64 := time.Now().Unix()
timestamp := strconv.FormatInt(timeInt64, 10)
messageAndroid.Timestamp = timestamp
messageAndroid.Production_mode = pushProductionMode
messageAndroid.Payload = payLoad
messageAndroid.Description = title
postBody, _ := json.Marshal(messageAndroid)
url := hostUmengPush + postPath
// MD5加密
sign := Md5("POST" + url + string(postBody) + masterSecreptAndroid)
url = url + "?sign=" + sign
req := httplib.Post(url)
req.JSONBody(messageAndroid)
byteData, err := req.Bytes()
if err != nil {
fmt.Println("android err back,", nil, err)
} else {
strData := string(byteData)
fmt.Println("android back,", strData)
fmt.Println("android send,", messageAndroid)
}
}
//=============================================================================================
/**
IOS推送必须项:
appkey
"timestamp":"xx", // 必填 时间戳,10位或者13位均可,时间戳有效期为10分钟
type //broadcast
"alert": "xx" // 必填
MasterSecret
"production_mode":"true/false" // 可选 正式/测试模式。测试模式下,只会将消息发给测试设备。
*/
var PushIOSTypeAdd = 1000
type UmengIOS struct {
Appkey string `json:"appkey"` // 必填项
Timestamp string `json:"timestamp"` // 必填项
Type string `json:"type"` // 必填项
Production_mode string `json:"production_mode"`
Payload *PayloadIOS `json:"payload"` // 必填项
Devicetokens string `json:"device_tokens"` // 选填项
Description string `json:"description"`
}
type PayloadIOS struct {
Aps *ApsIOS `json:"aps"`
Ptype int `json:"ptype"` // 1000:咨询,1001:政策法规;1004:法制宣传;1013:新闻
Purl string `json:"purl"`
}
type ApsIOS struct {
Alert string `json:"alert"` // 必填项
Content_available string `json:"content-available"`
}
//
// IOS推送
// deviceToken:设备的编号,如果设置deviceToken,则是单播;如果未设置则是全播
// ptype,purl:额外参数,非必选值
// ptype:区分类型
// purl:要打开的超链接的类型
//
func Push_IOS(title string, deviceToken string, ptype int, purl string) {
aps := &ApsIOS{}
aps.Alert = "xxx"
aps.Content_available = title
payLoad := &PayloadIOS{}
payLoad.Aps = aps
payLoad.Ptype = ptype
payLoad.Purl = purl
messageIOS := UmengIOS{}
messageIOS.Payload = payLoad
messageIOS.Appkey = appKeyIOS
timeInt64 := time.Now().Unix()
timestamp := strconv.FormatInt(timeInt64, 10)
messageIOS.Timestamp = timestamp
// 通过判断是否设置 deviceToken,来区分 单播 和 全播
if deviceToken == "" {
// 全播
messageIOS.Type = "broadcast"
} else {
// 单播
messageIOS.Type = "unicast"
messageIOS.Devicetokens = deviceToken
}
messageIOS.Production_mode = pushProductionMode
messageIOS.Description = title
postBody, _ := json.Marshal(messageIOS)
url := hostUmengPush + postPath
// MD5加密
sign := Md5("POST" + url + string(postBody) + masterSecretIOS)
url = url + "?sign=" + sign
req := httplib.Post(url)
req.JSONBody(messageIOS)
byteData, err := req.Bytes()
if err != nil {
fmt.Println("ios err back,", err, url)
} else {
strData := string(byteData)
fmt.Println(" ios back,", strData)
}
}
//md5加密
func Md5(str string) string {
h := md5.New()
h.Write([]byte(str))
sStr := hex.EncodeToString(h.Sum(nil))
return sStr
}
3、调用:
//客户不在线,查看客户是否用手机登录过,是就 用 友盟 推送手机消息提示 注意区分手机系统
if userClient.DeviceType == DeviceTypeAndroid {
extralDatas := map[string]string{
"userId":msg.ReceivedId,
}
//fmt.Println("map: ",extralDatas)
//Android推送
tools.Push_android(msg.MsgContext, userClient.DeviceToken, extralDatas)
} else {
//ios推送
tools.Push_IOS(msg.MsgContext, userClient.DeviceToken, tools.PushIOSTypeAdd, "")
}
//md5加密
func Md5(str string) string {
h := md5.New()
h.Write([]byte(str))
sStr := hex.EncodeToString(h.Sum(nil))
return sStr
}