forked from esap/wechat
-
Notifications
You must be signed in to change notification settings - Fork 0
/
context.go
159 lines (142 loc) · 3.65 KB
/
context.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package wechat
import (
"encoding/xml"
"errors"
"net/http"
"strings"
"time"
)
// Context 消息上下文
type Context struct {
*Server
Timestamp string
Nonce string
Msg *WxMsg
MsgEnc *WxMsgEnc
Resp interface{}
Writer http.ResponseWriter
Request *http.Request
repCount int
}
// Reply 被动回复消息
func (c *Context) Reply() (err error) {
if c.Request.Method != "POST" || c.repCount > 0 {
return errors.New("Reply err: no reply")
}
Printf("Wechat <== %+v", c.Resp)
if c.SafeMode {
b, err := xml.MarshalIndent(c.Resp, "", " ")
if err != nil {
c.Writer.Write([]byte{})
return err
}
c.Resp, err = c.EncryptMsg(b, c.Timestamp, c.Nonce)
if err != nil {
c.Writer.Write([]byte{})
return err
}
}
c.Writer.Header().Set("Content-Type", "application/xml;charset=UTF-8")
c.repCount++
return xml.NewEncoder(c.Writer).Encode(c.Resp)
}
// ReplySuccess 如果不能在5秒内处理完,应该先回复success,然后通过客服消息通知用户
func (c *Context) ReplySuccess() (err error) {
if c.Request.Method != http.MethodPost || c.repCount > 0 {
return errors.New("Reply err: no reply")
}
_, err = c.Writer.Write([]byte("success"))
return
}
// Send 主动发送消息(客服)
func (c *Context) Send() *Context {
go c.SendMsg(c.Resp)
return c
}
// SendAdd 添加主动消息队列(客服)
func (c *Context) SendAdd() *Context {
c.MsgQueueAdd(c.Resp)
return c
}
func (c *Context) newResp(msgType string) wxResp {
return wxResp{
FromUserName: CDATA(c.Msg.ToUserName),
ToUserName: CDATA(c.Msg.FromUserName),
MsgType: CDATA(msgType),
CreateTime: time.Now().Unix(),
AgentId: c.Msg.AgentID,
Safe: c.Safe,
}
}
// NewText Text消息
func (c *Context) NewText(text ...string) *Context {
c.Resp = &Text{
wxResp: c.newResp(TypeText),
content: content{CDATA(strings.Join(text, ""))}}
return c
}
// NewImage Image消息
func (c *Context) NewImage(mediaId string) *Context {
c.Resp = &Image{
wxResp: c.newResp(TypeImage),
Image: media{CDATA(mediaId)}}
return c
}
// NewVoice Voice消息
func (c *Context) NewVoice(mediaId string) *Context {
c.Resp = &Voice{
wxResp: c.newResp(TypeVoice),
Voice: media{CDATA(mediaId)}}
return c
}
// NewFile File消息
func (c *Context) NewFile(mediaId string) *Context {
c.Resp = &File{
wxResp: c.newResp(TypeFile),
File: media{CDATA(mediaId)}}
return c
}
// NewVideo Video消息
func (c *Context) NewVideo(mediaId, title, desc string) *Context {
c.Resp = &Video{
wxResp: c.newResp(TypeVideo),
Video: video{CDATA(mediaId), CDATA(title), CDATA(desc)}}
return c
}
// NewTextcard Textcard消息
func (c *Context) NewTextcard(title, description, url string) *Context {
c.Resp = &Textcard{
wxResp: c.newResp(TypeTextcard),
Textcard: textcard{CDATA(title), CDATA(description), CDATA(url)}}
return c
}
// NewNews News消息
func (c *Context) NewNews(arts ...Article) *Context {
news := News{
wxResp: c.newResp(TypeNews),
ArticleCount: len(arts),
}
news.Articles.Item = arts
c.Resp = &news
return c
}
// NewMpNews News消息
func (c *Context) NewMpNews(mediaId string) *Context {
news := MpNewsId{
wxResp: c.newResp(TypeMpNews),
}
news.MpNews.MediaId = CDATA(mediaId)
c.Resp = &news
return c
}
// NewMusic Music消息
func (c *Context) NewMusic(mediaId, title, desc, musicUrl, hqMusicUrl string) *Context {
c.Resp = &Music{
wxResp: c.newResp(TypeMusic),
Music: music{CDATA(mediaId), CDATA(title), CDATA(desc), CDATA(musicUrl), CDATA(hqMusicUrl)}}
return c
}
// Id 返回消息的来源与去向,可作为多应用管理时的用户组Id
func (c *Context) Id() string {
return c.Msg.FromUserName + "|" + c.Msg.ToUserName
}