本文最后更新于 2023年9月17日 上午
推送服务
推送服务(函数),或者说推送服务器功能。有些抽象,一些人可能并不知道具体含义。其实,就是搭建好一个接口,应用调用这个接口,可以给预先设置的开发者微信、开发者团队微信发送消息。
本篇文章,是基于方糖推送生态下的开源项目,搭建自己的推送服务。
详解推送
可能简介并不是很懂什么是推送服务。我们先以Server酱为例,进而解释本文要达到的目的。
Server酱
Server酱,英文名「ServerChan」,是一款「手机」和「服务器」、「智能设备」之间的通信软件。
通俗地说:就是从服务器、路由器等设备上推消息到手机的工具:
自建推送
Server酱,作为一款推送服务,因为其易于使用、部署简单,用户数也越来越多,甚至有时候服务器奔溃维护。所以,自建推送也就有其必要,这个自建推送项目,本身也是基于方糖推送生态下的开源项目:
- 向个人微信、团队企业微信推送消息
- 无API响应次数限制(Server酱免费版本开始限制单日响应次数)
本身这个推送,不受限于任何语言,只是:本次图文使用PHP语言编写API。
镜像教程
本文章,为了更方便大家阅读,同步发布在腾讯云社区和腾讯云计算内,具体地址:
如果小伙伴有上诉平台账号,不要忘记点赞嗷。当然,如果特别想支持我们,可以请我们喝奶茶,给我们充充电->->
效果演示
场景1:评论回复通知
在我们搭建Hexo静态博客过程中,使用自己的推送服务(搭建在腾讯云轻量应用服务器上的PHP应用)在其他用户评论时,对博主进行提醒。实际效果:
场景2:服务告罄通知
一般,我们开发项目,比如:图形识别、文字识别等,都是使用第三方平台提供的API接口,比如:腾讯云人工智能-图像识别,可以直接使用其API放到我们的项目中:
零基础基于PHP搭建推送服务函数,轻松推送消息至个人(团队)微信
腾讯云API接口实现
当我们API使用次数用完,我们也可以使用我们的推送服务,推送到我们自己的微信,提醒我们及时续费:
申请微信接口
我们需要申请微信接口,也就是微信API,用于对个人(团队)微信进行推送,注意:
- 微信接口申请,实际上是申请企业微信的接口。但是个人也可以申请。
- 后期可以选择微信接收推送,实际使用不需要多下载安装一个企业微信在手机上。
1. 应用创建
进入企业微信官网,注册一个企业微信。创建好后。我们选择应用管理,并创建一个应用:
2. 获取AgentId和Secret
创建好后,我们获取应用AgentId和Secret:
3. 获取企业ID
进入我的企业页面,拉到最下边,可以看到企业ID:
4. 绑定个人微信
如果你并不想保留企业微信在手机上,想直接推送消息到自己的个人微信,可以进入「我的企业」 → 「微信插件」,拉到下边扫描二维码,关注以后即可收到推送的消息:
5. 小结
通过以上过程,你将获得的参数:
WECOM_CID
:步骤3中获取的企业ID
WECOM_SECRET
:步骤2中获取的应用Secret
WECOM_AID
:步骤2中获取的应用AgentId
这些参数将在下文使用到。
PHP函数
方法介绍
有两种方法构建PHP函数:
Web Function
本次使用腾讯云的Serverless作为演示,很简单,简单地说:申请PHP函数
-编辑函数
1. PHP函数
我们进入Web Function页面,第一次使用需要给你当前账户权限(实际开发过程中,应该是一个腾讯云主号,按需分配子账户来权限管理)。之后,选择PHP Web Function:
2. 编辑函数
现在,我们进入我们刚刚创建的Web Function,重命名hello.php
为index.php
,并更改引导接口:
之后,我们在index.php
内填写:
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
| <?php
define('SENDKEY', 'set_a_sendkey'); define('WECOM_CID', '企业微信公司ID'); define('WECOM_SECRET', '企业微信应用Secret'); define('WECOM_AID', '企业微信应用ID'); define('WECOM_TOUID', '@all');
define('REDIS_ON', false); define('REDIS_HOST', '127.0.0.1'); define('REDIS_PORT', '6379'); define('REDIS_EXPIRED', '7000'); define('REDIS_KEY', 'wecom_access_token');
if (strlen(@$_REQUEST['sendkey']) < 1 || strlen(@$_REQUEST['text']) < 1 || @$_REQUEST['sendkey'] != SENDKEY ) { die('bad params'); }
header("Content-Type: application/json; charset=UTF-8"); echo send_to_wecom(@$_REQUEST['text'], WECOM_CID, WECOM_SECRET, WECOM_AID, WECOM_TOUID);
function redis() { if (!isset($GLOBALS['REDIS_INSTANCE']) || !$GLOBALS['REDIS_INSTANCE']) { $GLOBALS['REDIS_INSTANCE'] = new Redis(); $GLOBALS['REDIS_INSTANCE']->connect(REDIS_HOST, REDIS_PORT); }
return $GLOBALS['REDIS_INSTANCE']; }
function send_to_wecom($text, $wecom_cid, $wecom_secret, $wecom_aid, $wecom_touid = '@all') { $access_token = false; if (REDIS_ON) { $access_token = redis()->get(REDIS_KEY); }
if (!$access_token) { $info = @json_decode(file_get_contents("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=".urlencode($wecom_cid)."&corpsecret=".urlencode($wecom_secret)), true); if ($info && isset($info['access_token']) && strlen($info['access_token']) > 0) { $access_token = $info['access_token']; } } if ($access_token) { $url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token='.urlencode($access_token); $data = new \stdClass(); $data->touser = $wecom_touid; $data->agentid = $wecom_aid; $data->msgtype = "text"; $data->text = ["content"=> $text]; $data->duplicate_check_interval = 600;
$data_json = json_encode($data); $ch = curl_init(); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_setopt($ch, CURLOPT_POSTFIELDS, $data_json);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $response = curl_exec($ch); if ($response !== false && REDIS_ON) { redis()->set(REDIS_KEY, $access_token, ['nx', 'ex'=>REDIS_EXPIRED]); } return $response; } return false; }
|
同时,注意更改:
其中的参数:
- SENDKEY:自定义内容,类似token验证
- WECOM_CID:上文步骤中获取的企业ID
- WECOM_SECRET:上文步骤中获取的应用Secret
- WECOM_AID:上文步骤中获取的应用AgentId
- WECOM_TOUID:发送对象
3. 部署和使用
完成上述步骤后,我们点击部署即可:
之后,即可使用:
打包实现绑定的微信,即可看到已经推送:
这样的API就算搭建完成了,大家可以应用到自己的项目里了(比如:Vue内
、Springboot接口
等)
Server
大部分人都是会直接购买云服务器进行操作,尤其是学生群体,使用Serverless虽然便宜,但是综合来说,还是学生机更便宜.
我推荐可以使用腾讯云轻量应用服务器,不管用于生产还是开发,甚至是入门(方便重置服务器),都是性价比极高的服务器:
在部署好后,我建议使用宝塔面板进行Nginx和PHP的一键部署:
之后的内容也很简单,简单地说:新建网站
-编辑函数
-测试使用
:
1. 新建网站
打开网站的根目录:
其中:
- 域名:有域名解析到服务器则填域名,否则填服务器IP即可
- PHP版本:使用PHP7以上版本的PHP
之后,进入网站目录,等待后续操作:
2. 编辑函数
之后,在网站目录内,新建index.php
:
根据wecomchan项目,我们编辑函数index.php
函数:
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
| <?php
define('SENDKEY', 'set_a_sendkey'); define('WECOM_CID', '企业微信公司ID'); define('WECOM_SECRET', '企业微信应用Secret'); define('WECOM_AID', '企业微信应用ID'); define('WECOM_TOUID', '@all');
define('REDIS_ON', false); define('REDIS_HOST', '127.0.0.1'); define('REDIS_PORT', '6379'); define('REDIS_EXPIRED', '7000'); define('REDIS_KEY', 'wecom_access_token');
if (strlen(@$_REQUEST['sendkey']) < 1 || strlen(@$_REQUEST['text']) < 1 || @$_REQUEST['sendkey'] != SENDKEY ) { die('bad params'); }
header("Content-Type: application/json; charset=UTF-8"); echo send_to_wecom(@$_REQUEST['text'], WECOM_CID, WECOM_SECRET, WECOM_AID, WECOM_TOUID);
function redis() { if (!isset($GLOBALS['REDIS_INSTANCE']) || !$GLOBALS['REDIS_INSTANCE']) { $GLOBALS['REDIS_INSTANCE'] = new Redis(); $GLOBALS['REDIS_INSTANCE']->connect(REDIS_HOST, REDIS_PORT); }
return $GLOBALS['REDIS_INSTANCE']; }
function send_to_wecom($text, $wecom_cid, $wecom_secret, $wecom_aid, $wecom_touid = '@all') { $access_token = false; if (REDIS_ON) { $access_token = redis()->get(REDIS_KEY); }
if (!$access_token) { $info = @json_decode(file_get_contents("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=".urlencode($wecom_cid)."&corpsecret=".urlencode($wecom_secret)), true); if ($info && isset($info['access_token']) && strlen($info['access_token']) > 0) { $access_token = $info['access_token']; } } if ($access_token) { $url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token='.urlencode($access_token); $data = new \stdClass(); $data->touser = $wecom_touid; $data->agentid = $wecom_aid; $data->msgtype = "text"; $data->text = ["content"=> $text]; $data->duplicate_check_interval = 600;
$data_json = json_encode($data); $ch = curl_init(); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_setopt($ch, CURLOPT_POSTFIELDS, $data_json);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $response = curl_exec($ch); if ($response !== false && REDIS_ON) { redis()->set(REDIS_KEY, $access_token, ['nx', 'ex'=>REDIS_EXPIRED]); } return $response; } return false; }
|
其中,注意修改题头:
SENDKEY
:自定义内容,类似token验证
- WECOM_CID:上文步骤中获取的企业ID
- WECOM_SECRET:上文步骤中获取的应用Secret
- WECOM_AID:上文步骤中获取的应用AgentId
更改好参数,即可使用。
3. 测试使用
因为PHP是JIT语言,所以我们保持之后即可使用,正常情况下,应该是代码工程内对我们搭建的这个API接口进行Get、Post操作,而我们这次测试使用,就直接使用浏览器对API接口进行Get操作:
其中:
- SENDKEY:为上文定义内容,类似于token
- text:为要推送的消息
END
这样,我们的服务器又多了一个新功能,项目也多了可以选择的功能模块。但是这样的操作,并不是最佳的。因为,我们还可以使用Redis去存Token,进而加快接口响应时间,不过这都是后话了。有机会给大家分享。
另外,也可以使用Springboot去实现PHP的逻辑,有机会也分享给大家。
PS:大家搭建这个推送服务,会用于自己的什么项目里呢?