|
@@ -2,12 +2,14 @@
|
|
|
package jgpush
|
|
|
|
|
|
import (
|
|
|
+ "container/list"
|
|
|
"encoding/base64"
|
|
|
"encoding/json"
|
|
|
"io/ioutil"
|
|
|
"net/http"
|
|
|
qu "qfw/util"
|
|
|
"strings"
|
|
|
+ "sync"
|
|
|
"time"
|
|
|
|
|
|
"github.com/donnie4w/go-logger/logger"
|
|
@@ -17,6 +19,7 @@ type jgconfig struct {
|
|
|
Pushurl, Appid, AppSecret string
|
|
|
Alter map[string]interface{}
|
|
|
Config config
|
|
|
+ Titlelen int
|
|
|
}
|
|
|
type config struct {
|
|
|
Platform string
|
|
@@ -26,14 +29,16 @@ type config struct {
|
|
|
Options map[string]interface{}
|
|
|
}
|
|
|
|
|
|
-var pushchan chan bool
|
|
|
+var lock *sync.Mutex
|
|
|
+var jpushList *list.List
|
|
|
var Jgconfig jgconfig
|
|
|
|
|
|
func init() {
|
|
|
logger.SetConsole(false)
|
|
|
logger.SetRollingDaily("./logs", "jpush.log")
|
|
|
qu.ReadConfig("./jgpush.json", &Jgconfig)
|
|
|
- pushchan = make(chan bool, 20000)
|
|
|
+ jpushList = list.New()
|
|
|
+ lock = new(sync.Mutex)
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -45,16 +50,16 @@ ids:极光id组
|
|
|
extras:自定义字段
|
|
|
broadcast:是否广播,广播ids作废
|
|
|
*/
|
|
|
-func JgpushNc(title, infotype string, ids []string, extras map[string]interface{}, isbroadcast bool) (bool, map[string]interface{}) {
|
|
|
+func JgpushNc(title, infotype string, ids []string, extras map[string]interface{}, isbroadcast bool) {
|
|
|
temp := &Jgconfig.Config
|
|
|
temp.Audience["registration_id"] = ids
|
|
|
android := temp.Notification["android"]
|
|
|
if tmp, ok := android.(map[string]interface{}); ok {
|
|
|
tmp["alert"] = Jgconfig.Alter[infotype]
|
|
|
- tmp["title"] = title
|
|
|
+ tmp["title"] = shorTitle(title, Jgconfig.Titlelen)
|
|
|
tmp["extras"] = map[string]interface{}{
|
|
|
"type": infotype,
|
|
|
- "list": extras,
|
|
|
+ "info": extras,
|
|
|
}
|
|
|
}
|
|
|
ios := temp.Notification["ios"]
|
|
@@ -62,7 +67,7 @@ func JgpushNc(title, infotype string, ids []string, extras map[string]interface{
|
|
|
tmp["alert"] = Jgconfig.Alter[infotype]
|
|
|
tmp["extras"] = map[string]interface{}{
|
|
|
"type": infotype,
|
|
|
- "list": extras,
|
|
|
+ "info": extras,
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -71,14 +76,52 @@ func JgpushNc(title, infotype string, ids []string, extras map[string]interface{
|
|
|
"audience": temp.Audience,
|
|
|
"notification": temp.Notification,
|
|
|
"options": temp.Options,
|
|
|
- //"message": temp.Message,
|
|
|
}
|
|
|
if isbroadcast {
|
|
|
sendcon["audience"] = "all"
|
|
|
}
|
|
|
- bs, _ := json.Marshal(sendcon)
|
|
|
- pushchan <- true
|
|
|
- return push(string(bs))
|
|
|
+ bs, err := json.Marshal(sendcon)
|
|
|
+ if err == nil {
|
|
|
+ defer lock.Unlock()
|
|
|
+ lock.Lock()
|
|
|
+ jpushList.PushBack(string(bs))
|
|
|
+ } else {
|
|
|
+ logger.Error("json Marshal ", err.Error())
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//直接推送,非队列
|
|
|
+func JgpushD_Nc(title, infotype string, ids []string, extras map[string]interface{}, isbroadcast bool) map[string]interface{} {
|
|
|
+ temp := &Jgconfig.Config
|
|
|
+ temp.Audience["registration_id"] = ids
|
|
|
+ android := temp.Notification["android"]
|
|
|
+ if tmp, ok := android.(map[string]interface{}); ok {
|
|
|
+ tmp["alert"] = Jgconfig.Alter[infotype]
|
|
|
+ tmp["title"] = shorTitle(title, Jgconfig.Titlelen)
|
|
|
+ tmp["extras"] = map[string]interface{}{
|
|
|
+ "type": infotype,
|
|
|
+ "info": extras,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ios := temp.Notification["ios"]
|
|
|
+ if tmp, ok := ios.(map[string]interface{}); ok {
|
|
|
+ tmp["alert"] = Jgconfig.Alter[infotype]
|
|
|
+ tmp["extras"] = map[string]interface{}{
|
|
|
+ "type": infotype,
|
|
|
+ "info": extras,
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ sendcon := map[string]interface{}{
|
|
|
+ "platform": temp.Platform,
|
|
|
+ "audience": temp.Audience,
|
|
|
+ "notification": temp.Notification,
|
|
|
+ "options": temp.Options,
|
|
|
+ }
|
|
|
+ if isbroadcast {
|
|
|
+ sendcon["audience"] = "all"
|
|
|
+ }
|
|
|
+ return pushD(sendcon)
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -90,13 +133,42 @@ ids:极光id组
|
|
|
extras:自定义字段
|
|
|
broadcast:是否广播,广播ids作废
|
|
|
*/
|
|
|
-func JgpushMsg(msg_title, msg_con, msg_type string, ids []string, extras map[string]interface{}, isbroadcast bool) (bool, map[string]interface{}) {
|
|
|
+func JgpushMsg(msg_title, msg_con, msg_type string, ids []string, extras map[string]interface{}, isbroadcast bool) {
|
|
|
+ temp := Jgconfig.Config
|
|
|
+ temp.Audience["registration_id"] = ids
|
|
|
+ message := temp.Message
|
|
|
+ message["msg_content"] = msg_con
|
|
|
+ message["content_type"] = msg_type
|
|
|
+ message["title"] = shorTitle(msg_title, Jgconfig.Titlelen)
|
|
|
+ message["extras"] = extras
|
|
|
+
|
|
|
+ sendcon := map[string]interface{}{
|
|
|
+ "platform": temp.Platform,
|
|
|
+ "audience": temp.Audience,
|
|
|
+ "options": temp.Options,
|
|
|
+ "message": temp.Message,
|
|
|
+ }
|
|
|
+ if isbroadcast {
|
|
|
+ sendcon["audience"] = "all"
|
|
|
+ }
|
|
|
+ bs, err := json.Marshal(sendcon)
|
|
|
+ if err == nil {
|
|
|
+ defer lock.Unlock()
|
|
|
+ lock.Lock()
|
|
|
+ jpushList.PushBack(string(bs))
|
|
|
+ } else {
|
|
|
+ logger.Error("json Marshal ", err.Error())
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//直接推送,非队列
|
|
|
+func JgpushD_Msg(msg_title, msg_con, msg_type string, ids []string, extras map[string]interface{}, isbroadcast bool) map[string]interface{} {
|
|
|
temp := Jgconfig.Config
|
|
|
temp.Audience["registration_id"] = ids
|
|
|
message := temp.Message
|
|
|
message["msg_content"] = msg_con
|
|
|
message["content_type"] = msg_type
|
|
|
- message["title"] = msg_title
|
|
|
+ message["title"] = shorTitle(msg_title, Jgconfig.Titlelen)
|
|
|
message["extras"] = extras
|
|
|
|
|
|
sendcon := map[string]interface{}{
|
|
@@ -108,22 +180,43 @@ func JgpushMsg(msg_title, msg_con, msg_type string, ids []string, extras map[str
|
|
|
if isbroadcast {
|
|
|
sendcon["audience"] = "all"
|
|
|
}
|
|
|
- bs, _ := json.Marshal(sendcon)
|
|
|
- pushchan <- true
|
|
|
- return push(string(bs))
|
|
|
+ return pushD(sendcon)
|
|
|
+}
|
|
|
+
|
|
|
+func pushD(data map[string]interface{}) map[string]interface{} {
|
|
|
+ bs, err := json.Marshal(data)
|
|
|
+ tmp := map[string]interface{}{}
|
|
|
+ if err == nil {
|
|
|
+ req, _ := http.NewRequest("POST", Jgconfig.Pushurl, strings.NewReader(string(bs)))
|
|
|
+ req.Header.Add("Content-Type", "application/json")
|
|
|
+ req.Header.Add("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(Jgconfig.Appid+":"+Jgconfig.AppSecret)))
|
|
|
+ resp, err := http.DefaultClient.Do(req)
|
|
|
+ defer resp.Body.Close()
|
|
|
+ if err != nil {
|
|
|
+ tmp["err"] = err.Error()
|
|
|
+ logger.Error(err.Error(), "data ", data)
|
|
|
+ } else {
|
|
|
+ bs, _ := ioutil.ReadAll(resp.Body)
|
|
|
+ json.Unmarshal(bs, &tmp)
|
|
|
+ logger.Info(string(bs))
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ tmp["err"] = err.Error()
|
|
|
+ }
|
|
|
+ return tmp
|
|
|
}
|
|
|
|
|
|
//通知、消息推送、广播
|
|
|
-func JgpushNcAndMsg(title, infotype string, msg_title, msg_con, msg_type string, ids []string, extras, msg_extras map[string]interface{}, isbroadcast bool) (bool, map[string]interface{}) {
|
|
|
+func JgpushNcAndMsg(title, infotype string, msg_title, msg_con, msg_type string, ids []string, extras, msg_extras map[string]interface{}, isbroadcast bool) {
|
|
|
temp := Jgconfig.Config
|
|
|
temp.Audience["registration_id"] = ids
|
|
|
android := temp.Notification["android"]
|
|
|
if tmp, ok := android.(map[string]interface{}); ok {
|
|
|
tmp["alert"] = Jgconfig.Alter[infotype]
|
|
|
- tmp["title"] = title
|
|
|
+ tmp["title"] = shorTitle(title, Jgconfig.Titlelen)
|
|
|
tmp["extras"] = map[string]interface{}{
|
|
|
"type": infotype,
|
|
|
- "list": extras,
|
|
|
+ "info": extras,
|
|
|
}
|
|
|
}
|
|
|
ios := temp.Notification["ios"]
|
|
@@ -131,14 +224,14 @@ func JgpushNcAndMsg(title, infotype string, msg_title, msg_con, msg_type string,
|
|
|
tmp["alert"] = Jgconfig.Alter[infotype]
|
|
|
tmp["extras"] = map[string]interface{}{
|
|
|
"type": infotype,
|
|
|
- "list": extras,
|
|
|
+ "info": extras,
|
|
|
}
|
|
|
}
|
|
|
temp.Audience["registration_id"] = ids
|
|
|
message := temp.Message
|
|
|
message["msg_content"] = msg_con
|
|
|
message["content_type"] = msg_type
|
|
|
- message["title"] = msg_title
|
|
|
+ message["title"] = shorTitle(msg_title, Jgconfig.Titlelen)
|
|
|
message["extras"] = extras
|
|
|
|
|
|
sendcon := map[string]interface{}{
|
|
@@ -151,38 +244,65 @@ func JgpushNcAndMsg(title, infotype string, msg_title, msg_con, msg_type string,
|
|
|
if isbroadcast {
|
|
|
sendcon["audience"] = "all"
|
|
|
}
|
|
|
- bs, _ := json.Marshal(sendcon)
|
|
|
- pushchan <- true
|
|
|
- return push(string(bs))
|
|
|
+ bs, err := json.Marshal(sendcon)
|
|
|
+ if err == nil {
|
|
|
+ defer lock.Unlock()
|
|
|
+ lock.Lock()
|
|
|
+ jpushList.PushBack(string(bs))
|
|
|
+ } else {
|
|
|
+ logger.Error("json Marshal ", err.Error())
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-func push(content string) (bool, map[string]interface{}) {
|
|
|
- defer func() {
|
|
|
- <-pushchan
|
|
|
- }()
|
|
|
- req, _ := http.NewRequest("POST", Jgconfig.Pushurl, strings.NewReader(content))
|
|
|
- req.Header.Add("Content-Type", "application/json")
|
|
|
- req.Header.Add("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(Jgconfig.Appid+":"+Jgconfig.AppSecret)))
|
|
|
- b := false
|
|
|
- tmp := map[string]interface{}{}
|
|
|
- for i := 0; i < 10; i++ {
|
|
|
- resp, err := http.DefaultClient.Do(req)
|
|
|
- defer resp.Body.Close()
|
|
|
- if err != nil {
|
|
|
- tmp["err"] = err.Error()
|
|
|
- logger.Error(content)
|
|
|
- } else {
|
|
|
- bs, _ := ioutil.ReadAll(resp.Body)
|
|
|
- json.Unmarshal(bs, &tmp)
|
|
|
+func JPush() {
|
|
|
+ plist := getplist()
|
|
|
+ var n *list.Element
|
|
|
+ for e := plist.Front(); e != nil; e = n {
|
|
|
+ req, _ := http.NewRequest("POST", Jgconfig.Pushurl, strings.NewReader(qu.ObjToString(e.Value)))
|
|
|
+ req.Header.Add("Content-Type", "application/json")
|
|
|
+ req.Header.Add("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(Jgconfig.Appid+":"+Jgconfig.AppSecret)))
|
|
|
+ b := false
|
|
|
+ tmp := map[string]interface{}{}
|
|
|
+ for i := 0; i < 5; i++ {
|
|
|
+ resp, err := http.DefaultClient.Do(req)
|
|
|
+ defer resp.Body.Close()
|
|
|
+ if err != nil {
|
|
|
+ tmp["err"] = err.Error()
|
|
|
+ } else {
|
|
|
+ bs, _ := ioutil.ReadAll(resp.Body)
|
|
|
+ json.Unmarshal(bs, &tmp)
|
|
|
+ }
|
|
|
+ if qu.Int64All(tmp["sendno"]) == 0 {
|
|
|
+ b = true
|
|
|
+ break
|
|
|
+ }
|
|
|
+ time.Sleep(5 * time.Second)
|
|
|
}
|
|
|
- if qu.Int64All(tmp["sendno"]) == 0 {
|
|
|
- logger.Info(tmp)
|
|
|
- b = true
|
|
|
- break
|
|
|
+ if !b {
|
|
|
+ logger.Warn("jpush fail ", tmp, e.Value)
|
|
|
} else {
|
|
|
- logger.Warn(tmp)
|
|
|
+ logger.Info(tmp, "jpush success ", e.Value)
|
|
|
}
|
|
|
- time.Sleep(5 * time.Second)
|
|
|
+ n = e.Next()
|
|
|
+ plist.Remove(e)
|
|
|
+ time.Sleep(2 * time.Millisecond)
|
|
|
}
|
|
|
- return b, tmp
|
|
|
+ time.AfterFunc(30*time.Second, JPush)
|
|
|
+}
|
|
|
+
|
|
|
+func shorTitle(title string, l int) string {
|
|
|
+ lg := len([]rune(title))
|
|
|
+ if lg > l {
|
|
|
+ return string([]rune(title)[:l])
|
|
|
+ } else {
|
|
|
+ return title
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func getplist() list.List {
|
|
|
+ defer lock.Unlock()
|
|
|
+ lock.Lock()
|
|
|
+ tmp := *jpushList
|
|
|
+ jpushList = list.New()
|
|
|
+ return tmp
|
|
|
}
|