微信公众号服务
# 微信公众号服务
TaskRunner中内置微信公众号服务的开发框架,用户可以通过TaskRunner的开发,实现微信公众号中的自动回复消息的功能,接下来将详细说明微信公众号开发的实现方法。
# 基本配置
微信推送服务器需要使用到备案的域名以及包含公网IP可访问的服务器,在设置后续的项目前,请先提前准备好。
设置微信服务器配置,注意下方的配置项要与微信公众平台中的服务器配置一致。


# 使用方法
TaskRunner提供了推送接收消息的接口,通过向此接口发送消息,可以实现自定义配置的功能。
http://域名/WeixinServer/PushMessage
1
TaskRunner中微信服务器的功能实现逻辑在自定程序ReplyWechatMessage
中,用户可以在该自定程序中编写代码,实现微信公众号自定义回复功能。支持回复的消息文本类型如下:
消息类型 | 说明 |
---|---|
text | 接收到的内容格式为文本消息 |
image | 接收到的内容格式为图片消息 |
location | 接收到的内容格式为位置信息 |
link | 接收到的内容格式为链接 |
event | 接收到的内容格式为事件(用户订阅公众号等事件) |
以下是ReplyWechatMessage
的功能结构,将在其中进行注释说明。
var
docout: TNativeXml;
Articles,node:TXmlNode;
MsgType,MsgText:string;
touser, fromuser, msg: string;
url:String;
picurl:String;
var
event:string;
//使用文本回复消息的功能函数
function ReplyMsgText(Amsg:String):string;
begin
Result := '';
docout := TNativeXml.CreateName('xml',nil);
try
docout.Root.NodeNew('ToUserName').NodeAdd(docout.NodeNewTextType('ToUserName', touser, xeCData));
docout.Root.NodeNew('FromUserName').NodeAdd(docout.NodeNewTextType('FromUserName', fromuser, xeCData));
docout.Root.NodeNew('CreateTime').NodeAdd(docout.NodeNewTextType('CreateTime', IntToStr(DateTimeToUnix(now,false)), xeCData));
docout.Root.NodeNew('MsgType').NodeAdd(docout.NodeNewTextType('MsgType', 'text', xeCData));
docout.Root.NodeNew('Content').NodeAdd(docout.NodeNewTextType('Content', Amsg, xeCData));
Result := docout.WriteToString;
finally
FreeAndNil(docout);
end;
end;
begin
//获取要发送的用户信息,发送的消息类型
touser := UGParams.Values['FromUserName'];
fromuser := UGParams.Values['ToUserName'];
msgtype := UGParams.Values['msgtype'];
if msgtype = 'event' then
begin
event := UGParams.Values['event'];
//用户订阅公众号事件
if event = 'subscribe' then
begin
docout := TNativeXml.CreateName('xml',nil);
try
msg := '亲爱好朋友,感谢您的关注!';
docout.Root.NodeNew('ToUserName').NodeAdd(docout.NodeNewTextType('ToUserName', touser, xeCData));
docout.Root.NodeNew('FromUserName').NodeAdd(docout.NodeNewTextType('FromUserName', fromuser, xeCData));
docout.Root.NodeNew('CreateTime').NodeAdd(docout.NodeNewTextType('CreateTime', IntToStr(DateTimeToUnix(now,false)), xeCData));
docout.Root.NodeNew('MsgType').NodeAdd(docout.NodeNewTextType('MsgType', 'text', xeCData)); //
docout.Root.NodeNew('Content').NodeAdd(docout.NodeNewTextType('Content', msg, xeCData));
MsgText := docout.WriteToString;
finally
FreeAndNil(docout);
end;
end
//用户取消订阅公众号事件
else if event = 'unsubscribe' then
begin
docout := TNativeXml.CreateName('xml',nil);
try
msg := '感谢您的支持与厚爱,期待再次合作!';
docout.Root.NodeNew('ToUserName').NodeAdd(docout.NodeNewTextType('ToUserName', touser, xeCData));
docout.Root.NodeNew('FromUserName').NodeAdd(docout.NodeNewTextType('FromUserName', fromuser, xeCData));
docout.Root.NodeNew('CreateTime').NodeAdd(docout.NodeNewTextType('CreateTime', IntToStr(DateTimeToUnix(now,false)), xeCData));
docout.Root.NodeNew('MsgType').NodeAdd(docout.NodeNewTextType('MsgType', 'text', xeCData));
docout.Root.NodeNew('Content').NodeAdd(docout.NodeNewTextType('Content', msg, xeCData));
MsgText := docout.WriteToString;
finally
FreeAndNil(docout);
end;
end
//用户点击菜单按钮事件
else if event = 'CLICK' then
begin
msg := '无内容';
if UGParams.Values['EventKey'] = 'about' then
msg := '您点击了联系方式';
docout := TNativeXml.CreateName('xml',nil);
try
docout.Root.NodeNew('ToUserName').NodeAdd(docout.NodeNewTextType('ToUserName', touser, xeCData));
docout.Root.NodeNew('FromUserName').NodeAdd(docout.NodeNewTextType('FromUserName', fromuser, xeCData));
docout.Root.NodeNew('CreateTime').NodeAdd(docout.NodeNewTextType('CreateTime', IntToStr(DateTimeToUnix(now,false)), xeCData));
docout.Root.NodeNew('MsgType').NodeAdd(docout.NodeNewTextType('MsgType', 'text', xeCData));
docout.Root.NodeNew('Content').NodeAdd(docout.NodeNewTextType('Content', msg, xeCData));
MsgText := docout.WriteToString;
finally
FreeAndNil(docout);
end;
end
//用户调用微信扫码事件
else if (event = 'scancode_push') or (event = 'scancode_waitmsg') then
begin
docout := TNativeXml.CreateName('xml',nil);
try
msg := '扫码结果:'+ UGParams.Values['ScanType']+UGParams.Values['ScanResult'];
docout.Root.NodeNew('ToUserName').NodeAdd(docout.NodeNewTextType('ToUserName', touser, xeCData));
docout.Root.NodeNew('FromUserName').NodeAdd(docout.NodeNewTextType('FromUserName', fromuser, xeCData));
docout.Root.NodeNew('CreateTime').NodeAdd(docout.NodeNewTextType('CreateTime', IntToStr(DateTimeToUnix(now,false)), xeCData));
docout.Root.NodeNew('MsgType').NodeAdd(docout.NodeNewTextType('MsgType', 'text', xeCData));
docout.Root.NodeNew('Content').NodeAdd(docout.NodeNewTextType('Content', msg, xeCData));
MsgText := docout.WriteToString;
finally
FreeAndNil(docout);
end;
end;
end
//用户发送的内容为文本消息
else if msgtype = 'text' then
begin
msg := UGParams.Values['Content'];
//以下为一个示例,通过在微信公众号中发送文本消息JS001,触发JS001自定程序的执行
if msg = 'JS001' then
begin
try
UGCM.RunScript(msg);
MsgText := ReplyMsgText(msg+'自定程序执行成功!');
except
MsgText := ReplyMsgText(msg+'自定程序执行失败!'+ExceptionMessage);
end;
end
//以下为一个示例,向用户发送一个带预览图片的链接
else if Pos(UpperCase('操作手册'),UpperCase(msg)) > 0 then
begin
docout := TNativeXml.CreateName('xml',nil);
try
url := UGCM.RunScript('printreport',nil,'s');
docout.Root.NodeNew('ToUserName').NodeAdd(docout.NodeNewTextType('ToUserName', touser, xeCData));
docout.Root.NodeNew('FromUserName').NodeAdd(docout.NodeNewTextType('FromUserName', fromuser, xeCData));
docout.Root.NodeNew('CreateTime').NodeAdd(docout.NodeNewTextType('CreateTime', IntToStr(DateTimeToUnix(now,false)), xeCData));
docout.Root.NodeNew('MsgType').NodeAdd(docout.NodeNewTextType('MsgType', 'news', xeCData));
docout.Root.NodeAdd(docout.NodeNewInt('ArticleCount', 1));
Articles := docout.Root.NodeNew('Articles');
node := Articles.NodeNew('item');
node.NodeNew('Title').NodeAdd(docout.NodeNewTextType('Title', '爱招飞纺织印染业操作手册', xeCData));
node.NodeNew('Description').NodeAdd(docout.NodeNewTextType('Description', '爱招飞纺织印染业操作手册、使用说明', xeCData));
node.NodeNew('PicUrl').NodeAdd(docout.NodeNewTextType('PicUrl', 'https://www.isoface.cn/isoface/images/logo/isoface_02.png', xeCData));
node.NodeNew('Url').NodeAdd(docout.NodeNewTextType('Url', UGMM.BaseHost + url, xeCData));
MsgText := docout.WriteToString;
finally
FreeAndNil(docout);
end;
end
else
begin
MsgText := ReplyMsgText('已收到您的消息:['+msg+']')
end
end
end.
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
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