VbotLib.php
7.1 KB
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
<?php
namespace addons\vbot\library;
/**
*
*/
class VbotLib
{
// 模板数据
public $template;
// 要覆盖的模板数据 (参见:\application\admin\controller\dinghorn\Example.php 的 example2 方法)
public $tpl_data;
// 模板变量键值对,若模板变量已预先定义,则会自动获取值,无需在此传递
public $tpl_variable;
/**
* 构造方法
* @param array $template 模板数据
* @param array $tpl_data 要覆盖的模板数据
* @param array $tpl_variable 模板变量键值对
*/
public function __construct($template = array(), $tpl_data = array(), $tpl_variable = array())
{
$this->template = $template;
$this->tpl_data = $tpl_data;
$this->tpl_variable = $tpl_variable;
}
/**
* 发起请求
*
* @param string $access_token 机器人的 access_token
* @param array post_data 请求数据
* @return array 请求结果
*/
/**
* 发起请求
* @param string $webhook 机器人的 WebHook地址
* @param array $post_data 请求数据
* @return array 请求结果
*/
public function msgSend($webhook, $post_data)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $webhook);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json;charset=utf-8'));
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$ret = curl_exec($ch);
if (false == $ret) {
// curl_exec failed
$result = ['errcode' => -2, 'errmsg' => curl_error($ch)];
} else {
$rsp = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (200 != $rsp) {
$result = ['errcode' => -1, 'errmsg' => $rsp . ' ' . curl_error($ch)];
} else {
$result = json_decode($ret, true);
if (!$result) {
$result = ['errcode' => -3, 'errmsg' => '转换请求结果数据失败!'];
}
}
}
curl_close($ch);
return $result;
}
/**
* 组装消息数据
* @return array 组装结果
*/
public function deal_with_msg()
{
$msg_data = array();
$msgtype = $msg_data['msgtype'] = $this->template['typelist'];
$content = isset($this->tpl_data['content']) ? $this->analysis_variable($this->tpl_data['content']) : $this->analysis_variable($this->template['content']);
if ($msgtype == 'text') {
$msg_data['text'] = [
'content' => $content,
'mentioned_mobile_list' => $this->deal_with_at($this->template)
];
} elseif ($msgtype == 'markdown') {
$msg_data['markdown'] = [
'content' => $content
];
} elseif ($msgtype == 'image') {
$picurl_image = isset($this->tpl_data['picurl_image']) ? $this->tpl_data['picurl_image'] : request()->domain() . $this->template['picurl_image'];
$base64 = base64_encode(@file_get_contents($picurl_image));
$msg_data['image'] = [
'base64' => $base64,
'md5' => md5(@file_get_contents($picurl_image))
];
} elseif ($msgtype == 'news') {
$news = isset($this->tpl_data['news']) ? $this->tpl_data['news'] : json_decode($this->template['news'], true);
foreach ($news as $key => $value) {
$news[$key]['title'] = $this->analysis_variable($news[$key]['title']);
$news[$key]['description'] = '';
}
$news[0]['description'] = $content;
$msg_data['news'] = array(
'articles' => $news
);
}
return $msg_data;
}
/**
* 分析字符串中的自定义变量
* @param string $str 要分析的字符串
* @return string 解析过变量的字符串
*/
public function analysis_variable($str)
{
if (!$str) {
return '';
}
$variables = array();
$match = array();
preg_match_all('/\${(.*?)}/', $str, $match);// 匹配到所有变量
// 读取数据库中的模板变量
$variable_tmp = \think\Db::name('vbot_variable')->where('deletetime', null)->select();
foreach ($variable_tmp as $key => $value) {
$value['variable_type'] = 'predefined';// 标记为预定义
$variable_arr[$value['name']] = $value;
}
unset($variable_tmp);
// 准备传递过来的模板变量
foreach ($this->tpl_variable as $key => $value) {
$variable_arr[$key] = [
'variable_type' => 'definition_now',// 标记为现在定义
'variable_value' => $value,
];
}
foreach ($match[1] as $key => $value) {
if (array_key_exists($value, $variable_arr)) {
if ($variable_arr[$value]['variable_type'] == 'definition_now') {
$str = str_replace($match[0][$key], $variable_arr[$value]['variable_value'], $str);
} else if ($variable_arr[$value]['variable_type'] == 'predefined') {
$variable_value = $this->get_variable_value($variable_arr[$value]);
$str = str_replace($match[0][$key], $variable_value, $str);
}
}
}
return $str;
}
/**
* 获取数据库中的模板变量的值
* @param string $var 变量数据
* @return string 变量值
*/
public function get_variable_value($var)
{
if ($var['value_source'] == 0) {
$var['sql'] = str_replace('__PREFIX__', config('database.prefix'), $var['sql']);
$res = \think\Db::query($var['sql']);
if ($res) {
if (is_array($res[0])) {
foreach ($res[0] as $key => $value) {
return $value;
}
} else {
return $res[0];
}
} else {
return false;
}
} elseif ($var['value_source'] == 1) {
return \think\Hook::exec($var['namespace'] . '\\' . $var['class'], $var['function'], $var['params']);
}
}
/**
* 组装at数据
* @return array 组装结果
*/
public function deal_with_at()
{
if (isset($this->tpl_data['is_atall']) || isset($this->tpl_data['at_mobiles'])) {
$this->template['is_atall'] = $this->tpl_data['is_atall'];
$this->template['at_mobiles'] = $this->tpl_data['at_mobiles'];
}
if ($this->template['is_atall']) {
return ['', "@all"];
} else {
$at_mobiles = explode(',', rtrim($this->template['at_mobiles'], ','));
return $at_mobiles;
}
}
}