企业微信机器人推送demo php
之前项目里需要对接企业微信机器人推送接口,然后去微信开发平台找接口文档。发现并没有php相关的demo。
下面是代码,仅供参考。
class WechatBotService
{
/**
* 错误信息
*
* @var string
*/
protected $error = '';
/**
* 企业微信推送地址
*
* @var string
*/
protected $url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send";
/**
* 企业微信文件上传地址
*
* @var string
*/
protected $uploadUrl = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media';
public function send()
{
$param = request()->param();
$type = $param['type'];
$token = $param['token'];
$msg = $param['msg'];
switch ($type)
{
case "text":
$where = ['token'=>$token,'status'=>1];
$group = new Group;
$key = $group->where($where)->field('url_key')->find()->toArray();
$this->sendText($key['url_key'],$msg);
break;
case "markdown":
$where = ['token'=>$token,'status'=>1];
$group = new Group;
$key = $group->where($where)->field('url_key')->find()->toArray();
$this->sendMarkDown($key['url_key'],str_replace(['\n','\\'],'',$msg));
break;
case "img":
$where = ['token'=>$token,'status'=>1];
$group = new Group;
$key = $group->where($where)->field('url_key')->find()->toArray();
$base64 = str_replace("data:image/jpeg;base64,","",$msg[0]);
$md5 = $msg[1];
$this->sendImg($key['url_key'],$base64,$md5);
break;
case "news":
$where = ['token'=>$token,'status'=>1];
$group = new Group;
$key = $group->where($where)->field('url_key')->find()->toArray();
$title = $_POST['title'];
$desc = $_POST['desc'];
$href = $_POST['href'];
$picUrl = $_POST['picUrl'];
$this->sendNews($key['url_key'],$title,$desc,$href,$picUrl);
break;
case "file":
$where = ['token'=>$token,'status'=>1];
$group = new Group;
$key = $group->where($where)->field('url_key')->find()->toArray();
$this->sendFile($key['url_key']);
break;
}
}
/**
* Date: 2021/8/10
* Notes: 推送文本
* @param [type] $key
* @param [type] $msg
* @return void
*/
public function sendText($key, $msg)
{
if (empty($key) || !is_string($key))
{
$this->error = 'key为空';
return false;
}
if (empty($msg) || !is_string($msg))
{
$this->error = '发送内容为空';
return false;
}
$urls = $this->url.'?key='.$key;
$content = ['msgtype'=>'text','text'=>['content'=>$msg]];
$res = $this->sendRquest($urls,$content);
if (!isset($res['errcode']) || $res['errcode'] != '0') {
$this->error = '推送失败, errmsg: ' . $res['errmsg'];
return false;
}
return dump(json_encode($res));
}
/**
* Date: 2021/8/10
* Notes: 推送markdown
* @param [type] $key
* @param [type] $msg
* @return void
*/
public function sendMarkDown($key,$msg)
{
if (empty($key) || !is_string($key)) {
$this->error = 'key为空';
return false;
}
if (empty($msg) || !is_string($msg)) {
$this->error = '发送内容为空';
return false;
}
$urls = $this->url.'?key='.$key;
$content = ['msgtype'=>'markdown','markdown'=>['content'=>$msg]];
$res = $this->sendRquest($urls,$content);
if (!isset($res['errcode']) || $res['errcode'] != '0') {
$this->error = '推送失败, errmsg: ' . $res['errmsg'];
return false;
}
return dump(json_encode($res));
}
/**
* Date: 2021/8/10
* Notes: 推送图片
* @param [type] $key
* @param [type] $base64
* @param [type] $md5
* @return void
*/
public function sendImg($key, $base64, $md5)
{
// var_dump($base64,$md5);die;
if (empty($key) || !is_string($key))
{
$this->error = 'key为空';
return false;
}
if (empty($md5) || !is_string($md5))
{
$this->error = '图片md5为空';
return false;
}
if (empty($base64) || !is_string($base64))
{
$this->error = '图片base64为空';
return false;
}
$urls = $this->url.'?key='.$key;
$content = ['msgtype'=>'image','image'=>['base64'=>$base64,'md5'=>$md5]];
$res = $this->sendRquest($urls,$content);
if (!isset($res['errcode']) || $res['errcode'] != '0') {
$this->error = '推送失败, errmsg: ' . $res['errmsg'];
return false;
}
return dump(json_encode($res));
}
/**
* Date: 2021/8/10
* Notes: 推送文章
* @param [type] $key 机器人的webhook地址的key值
* @param [type] $title 文章标题
* @param [type] $desc 描述
* @param [type] $href 点击后跳转的链接。
* @param [type] $picUrl 图文消息的图片链接,支持JPG、PNG格式
* @return void
*/
public function sendNews($key, $title, $desc, $href, $picUrl)
{
if (empty($key) || !is_string($key))
{
$this->error = 'key为空';
return false;
}
if (empty($title) || !is_string($title))
{
$this->error = '标题不能为空';
return false;
}
if (empty($desc) || !is_string($desc))
{
$this->error = '描述内容不能为空';
return false;
}
if (empty($href) || !is_string($href))
{
$this->error = '跳转链接不能未空';
return false;
}
if (empty($picUrl) || !is_string($picUrl))
{
$this->error = '图片链接不能未空';
return false;
}
$urls = $this->url.'?key='.$key;
$data = [
'msgtype' => 'news',
'news' => [
'articles' => [
[
'title' => $title,
'description' => $desc,
'url' => $href,
'picurl' => $picUrl,
]
],
],
];
$res = $this->sendRquest($urls,$data);
if (!isset($res['errcode']) || $res['errcode'] != '0') {
$this->error = '推送失败, errmsg: ' . $res['errmsg'];
return false;
}
return dump(json_encode($res));
}
/**
* Date: 2021/8/10
* Notes: 推送文文件
* @param [type] $key
* @param [type] $media_id
* @return void
*/
public function sendFile($key)
{
if (empty($key) || !is_string($key)) {
$this->error = 'key为空';
return false;
}
//拼接推送接口地址
$url = $this->url . '?key=' . $key;
//拼接文件上传接口地址
$up_url = $this->uploadUrl . '?key=' . $key . '&type=file';
//获取上传文件路径和文件名
$path = $this->uploadFile();
//创建一个CURLFile对象
$cfile = new \CURLFile($path['path'], '', $path['name']);
$files = ['file' => $cfile];
//请求企业微信上传接口获取media_id
$res = $this->sendRquest($up_url, $files, 'post', false);
$media_id = json_decode($res, true)['media_id'];
//准备推送数据
$data = ['msgtype' => 'file', 'file' => ['media_id' => $media_id]];
//请求推送接口
$res = $this->sendRquest($url, $data);
if (!isset($res['errcode']) || $res['errcode'] != '0') {
$this->error = '推送失败, errmsg: ' . $res['errmsg'];
return false;
}
return dump(json_encode($res));
}
/**
* Date: 2021/8/10
* Notes: 上传文件
* @param [type] $url
* @param [type] $path
* @param [type] $name
* @return array
*/
public function uploadFile()
{
//获取文件名
$filename = $_FILES['msg']['name'];
//获取文件临时路径
$temp_name = $_FILES['msg']['tmp_name'];
//获取大小
$size = $_FILES['msg']['size'];
//获取文件上传码,0代表文件上传成功
$error = $_FILES['msg']['error'];
//判断文件大小是否超过设置的最大上传限制
if ($size > 2*1024*1024*1024){
echo "<script>alert('文件大小超过2M大小');window.history.go(-1);</script>";
exit();
}
$arr = pathinfo($filename);
//文件保存路径
$url = ROOT_PATH . 'public' . DS . 'uploads\\';
//获取文件名
$file_name = iconv('utf-8', 'gbk', $arr['basename']);
//文件后缀
$ext_suffix = $arr['extension'];
//设置允许上传文件的后缀
$allow_suffix = array('txt','jpg','gif','jpeg','png','pdf','doc','xls','xlsx','ppt','csv');
//判断上传的文件是否在允许的范围内(后缀)==>白名单判断
if(!in_array($ext_suffix, $allow_suffix)){
//window.history.go(-1)表示返回上一页并刷新页面
echo "<script>alert('上传的文件类型只能是jpg,gif,jpeg,png');window.history.go(-1);</script>";
exit();
}
//检测存放上传文件的路径是否存在,如果不存在则新建目录
if (!file_exists($url)){
mkdir($url);
}
//取一个新名字
//$new_filename = date('YmdHi',time()).'.'.$ext_suffix;
//将文件从临时路径移动到磁盘
if (move_uploaded_file($temp_name, $url.$file_name)){
return ['path'=>$url.$file_name,'name'=>$file_name];
}else{
echo "<script>alert('文件上传失败,错误码:$error');</script>";
}
}
/**
* 发送请求
*
* @param [type] $url URL
* @param aarray $data 请求数据
* @return void
*/
protected function sendRquest($url, $data = [], $type = 'post', $toJson = true, $timeOut = 0)
{
// 判断是否为https请求
$ssl = substr($url, 0, 8) == "https://" ? TRUE : FALSE;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, ($type == 'post') ? true : false);
//判断是否发送josn格式数据
if($toJson == true)
{
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json; charset=utf-8',
));
}else{
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
// 设置内容以文本形式返回,而不直接返回
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if ($ssl) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
}
// 设置超时时间
if (!empty($timeOut)) {
curl_setopt($ch, CURLOPT_TIMEOUT, $timeOut);
}
// 发起请求
$html = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($html === false || $status != 200) {
var_dump(curl_error($ch), $status);
// 执行请求失败钩子
// HttpHook::listen('send_faild', ['url' => $url, 'status' => $status, 'error' => curl_error($ch), 'curl' => $ch]);
}
// 关于请求句柄
curl_close($ch);
$result = ($toJson) ? json_decode($html, true) : $html;
return $result;
}
}