|
|
package umeng
|
|
|
|
|
|
import (
|
|
|
"crypto/md5"
|
|
|
"encoding/json"
|
|
|
"fmt"
|
|
|
"github.com/astaxie/beego/httplib"
|
|
|
"io/ioutil"
|
|
|
"net/http"
|
|
|
"openapi/internal/push"
|
|
|
"strings"
|
|
|
"time"
|
|
|
)
|
|
|
|
|
|
var (
|
|
|
Host = "http://msg.umeng.com"
|
|
|
ApiSend = "/api/send"
|
|
|
UploadPath = "/upload"
|
|
|
)
|
|
|
|
|
|
var FiledErrorFormat = "缺少字段:%v"
|
|
|
var FiledErrorFormatFunc = func(filed string) error {
|
|
|
return fmt.Errorf(FiledErrorFormat, filed)
|
|
|
}
|
|
|
|
|
|
const (
|
|
|
AppKey = "appkey"
|
|
|
Timestamp = "timestamp"
|
|
|
Type = "type"
|
|
|
ProductionMode = "production_mode"
|
|
|
DeviceTokens = "device_tokens"
|
|
|
Payload = "payload"
|
|
|
Policy = "policy"
|
|
|
Description = "description"
|
|
|
|
|
|
DisplayType = "displayType"
|
|
|
Body = "body"
|
|
|
Ticker = "ticker" // 必填,通知栏提示文字
|
|
|
Title = "title" // 必填,通知标题
|
|
|
Text = "text" //必填,通知文字描述
|
|
|
/*
|
|
|
// 可选,默认为"go_app",值可以为:
|
|
|
// "go_app": 打开应用
|
|
|
// "go_url": 跳转到URL
|
|
|
// "go_activity": 打开特定的activity
|
|
|
// "go_custom": 用户自定义内容。
|
|
|
*/
|
|
|
AfterOpen = "after_open"
|
|
|
Extra = "extra"
|
|
|
)
|
|
|
|
|
|
const (
|
|
|
Message = "message"
|
|
|
Notification = "notification"
|
|
|
)
|
|
|
const (
|
|
|
ExpireSpan = time.Second * 60 * 60 * 24
|
|
|
)
|
|
|
|
|
|
type SetPayload func(msg *UnicastMsg, option map[string]interface{}) error
|
|
|
|
|
|
type UmengNotification struct {
|
|
|
Auth *Auth
|
|
|
Request *httplib.BeegoHTTPRequest
|
|
|
}
|
|
|
|
|
|
func (notify *UmengNotification) Init(options ...push.Option) error {
|
|
|
return nil
|
|
|
}
|
|
|
func (notify *UmengNotification) Send(option map[string]interface{}) error {
|
|
|
var (
|
|
|
setPayload SetPayload = SetAndroidPayload
|
|
|
body []byte
|
|
|
err error
|
|
|
httpRsp *http.Response
|
|
|
ret = make(map[string]interface{})
|
|
|
data []byte
|
|
|
)
|
|
|
if option["DeviceType"].(int) == 1 {
|
|
|
setPayload = SetAndroidPayload
|
|
|
}
|
|
|
if body, err = notify.PostBody(option, setPayload); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
notify.Request = httplib.Post(notify.Url(ApiSend, body))
|
|
|
notify.Request.Body(body)
|
|
|
|
|
|
if httpRsp, err = notify.Request.DoRequest(); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
data, err = ioutil.ReadAll(httpRsp.Body)
|
|
|
defer httpRsp.Body.Close()
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
if err = json.Unmarshal(data, &ret); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
if status, ok := ret["ret"]; ok {
|
|
|
if strings.EqualFold(fmt.Sprintf("%v", status), "SUCCESS") {
|
|
|
return nil
|
|
|
}
|
|
|
return fmt.Errorf("response:%v fail", ret)
|
|
|
}
|
|
|
return fmt.Errorf("response:%v invaild", ret)
|
|
|
}
|
|
|
func (notify *UmengNotification) PostBody(option map[string]interface{}, setPayload SetPayload) (body []byte, err error) {
|
|
|
var postData = new(UnicastMsg)
|
|
|
postData.AppKey = notify.Auth.AppKey
|
|
|
postData.Timestamp = fmt.Sprintf("%v", time.Now().Unix())
|
|
|
postData.ProductionMode = fmt.Sprintf("%v", true)
|
|
|
postData.Type = fmt.Sprintf("%v", option[Type])
|
|
|
postData.DeviceTokens = fmt.Sprintf("%v", option[DeviceTokens])
|
|
|
postData.Policy = MsgPolicy{ExpireTime: time.Now().Add(ExpireSpan).Format("2006-01-02 15:04:05")}
|
|
|
if err = setPayload(postData, option); err != nil {
|
|
|
return
|
|
|
}
|
|
|
postData.Description = fmt.Sprintf("%v", option[Title])
|
|
|
if body, err = json.Marshal(postData); err != nil {
|
|
|
return
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
func (notify *UmengNotification) Url(method string, body []byte) string {
|
|
|
var url string = fmt.Sprintf("%v%v", Host, method)
|
|
|
sign := fmt.Sprintf("%x", md5.Sum([]byte("POST"+url+string(body)+notify.Auth.AppMasterSecret)))
|
|
|
url = fmt.Sprintf("%v?sign=%v", url, sign)
|
|
|
return url
|
|
|
}
|
|
|
|
|
|
type UnicastMsg struct {
|
|
|
AppKey string `json:"appkey"`
|
|
|
Timestamp string `json:"timestamp"`
|
|
|
Type string `json:"type"` //发送类型 单播 列播...
|
|
|
ProductionMode string `json:"production_mode"`
|
|
|
DeviceTokens string `json:"device_tokens"`
|
|
|
Payload MsgPayload `json:"payload"`
|
|
|
Policy MsgPolicy `json:"policy"`
|
|
|
Description string `json:"description"`
|
|
|
}
|
|
|
type MsgPayload map[string]interface{}
|
|
|
type MsgPolicy struct {
|
|
|
ExpireTime string `json:"expire_time"`
|
|
|
}
|
|
|
|
|
|
//设置payload
|
|
|
func SetAndroidPayload(msg *UnicastMsg, option map[string]interface{}) error {
|
|
|
msg.Payload = make(map[string]interface{})
|
|
|
var (
|
|
|
displayType string
|
|
|
ok bool
|
|
|
)
|
|
|
if _, ok = option[DisplayType]; !ok {
|
|
|
return FiledErrorFormatFunc(DisplayType)
|
|
|
}
|
|
|
displayType = option[DisplayType].(string)
|
|
|
switch displayType {
|
|
|
case Message:
|
|
|
break
|
|
|
case Notification:
|
|
|
var payloadBody = make(map[string]interface{})
|
|
|
//if _,ok =option[Title];!ok{
|
|
|
// return FiledErrorFormatFunc(Title)
|
|
|
//}
|
|
|
//if _,ok =option[Text];!ok{
|
|
|
// return FiledErrorFormatFunc(Text)
|
|
|
//}
|
|
|
//if _,ok =option[Extra];ok{
|
|
|
// payloadBody[Extra]=option[Extra]
|
|
|
//}
|
|
|
payloadBody[Ticker] = option[Title]
|
|
|
payloadBody[Title] = option[Title]
|
|
|
payloadBody[Text] = option[Text]
|
|
|
payloadBody[AfterOpen] = "go_app"
|
|
|
msg.Payload[Body] = payloadBody
|
|
|
break
|
|
|
default:
|
|
|
return FiledErrorFormatFunc(DisplayType)
|
|
|
break
|
|
|
}
|
|
|
return nil
|
|
|
} |
...
|
...
|
|