微信主动消息推送的编程实现


l 引言
使用 微信公众 号 ,借助微 信高级群 发接 口 ,进 行主动 消息推送 ,是现代移 动通信展 示 中常用 的手段 。直接应用
微信高级群发接 口,编程实现主 动消息推送 ,有一定难度 , 常常选用 一些封装微信 高级群发接 口的 J a v a工具包进行 软
We b交互页面 ,完成文本 、图片 、语音 、视频 、图文 等原始信息和最终消息的选择 、预览 、编辑 和群发 f 即主动
和g r o u p I d 。o p e n I d和 n i c k n a m e用作 预览 群发 的用 户 对 象 指 定 ,n i c k n a m e用在前 台页面作预 览对象指 定 ,o p e n I d用
x ml o
v a — c o m m o n和 w e i x i n - j a v a — mp的 m a i n部分 ,分 别按包形成
w e i x i n - j a v a — c o m mo n . j a r 和w e i x i n - j a v a — mp . j a r , 引 入 项 目 工
发送) ,如图 1 所示 。群发功能包 括 3种 :特定用 户的预览
群发 、特定用户组的执行 群发和面向全体用户的执行群发 。
4 群 发基础 构 造
4 . 1 服 务 调 用前 提
件 设 计 。如 f a s t We i x i n 、w e C h a t 、w e i x i n - j a v a — t o o l s 、w e i x —
摘 要 : 立 足 微 信 高 级 群 发接 口和 w e i x i n - j a v a — t o o l s 基础 i a r 包 , 紧 密结 合 后 台 J a v a 服 务 处理 和 前 台 J S约 束 限
制 ,逐步完成了复杂的微信公众号常 用文本、图片、语音 、视频 、图文等消息主动推送 的软件 实现 ,既丰富 了 w e i x i n - j a v a — t o o l s 工具的灵活运 用,叉完善 了微信高级群发接 口的 “ 含糊” ,简化 了微信群发功能的应用开发实践 关键词 :微信公众号;访 问令牌 ;用户信息提取 ;媒体/ 素材上传 ; J S页面约束;消息推送 ;预 览群发;执行群发
传输 服务 ,前 台 We b页 面交互 。实现文 本 、图片 、语 音 、
视频 、图文信息 的主动推 送 。针对 群发次数 的限制 , 便 于
使用 上的编辑调试起见 ,又特地实现 了预览群发。
2 w e i x i n - j a v a — t o o l s 运用
w e i x i n - j a v a — t o o l s _ T具 包 由 3部 分 组 成 :公 共 基 础 w e i x . i n - j a v a — c o m mo n 、公 众 号 w e i x i n - j a v a — mp和 企 业 号 w e i x i n —
k e n 。a c c e s s T o k e n 有效期是 2小时 ,之后需要 重新 获取 。相 应的接 口调用 如下 :
h  ̄ : / / a p i we , i x i n , q q , c o m/ c g i - - b i n / t o k e n ? g r a n t _ Wp o= c l i e n Lc r e d e n t i a l & a p p i d = a p p l d & s e c r e t = s e c l t
i n 4 j 、m p S d k 4 J等 。下 面采 用 w e i x i n - j a v a — t o o l s ,后 台 J a v a
申请公众号 ( 订阅号或服务号) ,取得认证 ,获得 a p p l d 和密钥 s e c r e t .再 由它们 获取微 信服务 访 问令 牌 a c c e s s T o —
程使用 。编程设 计 主要参考 t e s t 中d e m o例程 对 m a i n的引 用 ,d e m o部分非 常 “ 粗糙 ” ,既不 全面 ,又常 因代 码 “ 写 死”没灵活性 ,必须加以改造和丰富,才能应用 。
4 . 2 获 取 用 户 信 息
需要 从公众 号 的用户 信息 中提取 其 o p e n I d 、n i c k n a m e
w e i x i n - j a v a — t o o l s提供有 g e t A c c e s s T o k e n 0 函数 .可直 接拿来使用 ,它会 自动 判断有效性 ,只有失效 时才去重 新
获取 a c c e s s T o k e n 。
j a v a — c p ,每 部分 源码 又有两 部分 :主体 ma i n和测试 t e s t ,
…ቤተ መጻሕፍቲ ባይዱ
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
实用第一 智慧密集
… … , . … … … . … … … . … . … … , … … … … … … … … , 。 。
微信 主动消息推送 的编程 实现
怯肇 乾 ,孟 志远
( 恒升科创科技有限公司 ,北京 1 0 0 0 8 4 )
m a i n中含有 a p i 、b e a n 、u t i l 、s e s s i o n 、e x c e p t i o n等 ,是微信 高级 群发接 口应用的封装 。针对公众号应用 ,把 w e i x i n - j a —
a p p l d、s e c r e t 、a c c e s s T o k e n 、o p e n l d记 录在 文件 w x c f g . x ml 中 。可 参 考 w e i x i n - j a v a — t o o l s的模 板 文 件 构 造 w  ̄ c f g .
合集下载

websocket实现服务端主动给客户端推送消息

websocket实现服务端主动给客户端推送消息

websocket实现服务端主动给客户端推送消息websocket实现服务端主动给客户端推送消息HTTP协议中的四⼤特性中有⽆链接:⼀次请求⼀次响应后断开链接,因此基于HTTP协议实现服务端改客户端主动推送消息有点⿇烦1. 服务端给客户端主动推送消息有以下应⽤情景:⼤屏幕投票实时展⽰任务的执⾏流程群聊功能等等 ...2. 如何实现服务端给客户端主动推送消息⼤的⽅向有两种⽅式:1. 伪实现让客户端浏览器每隔⼀段时间偷偷的去服务器请求数据,这样能实现效果,但是内部本质还是客户端朝服务端发送消息轮询"""让浏览器定时(例如每隔5秒发⼀次)通过ajax朝服务端发送请求获取数据缺点:消息延迟严重请求次数多消耗资源过⼤"""长轮询"""服务端给每个浏览器创建⼀个队列,让浏览器通过ajax向后端偷偷的发送请求,去各⾃对应的队列中获取数据,如果没有数据则会有阻塞,但是不会⼀直阻塞,⽐如最多阻塞30秒(pending)后给⼀个响应,⽆论响应是否是真正的数据,都会再次通过回调函数调⽤请求数据的代码优点:消息基本没有延迟请求次数降低消耗资源减少"""# ⼤公司需要考虑兼容性问题追求兼容⽬前⽹页版本的微信和qq⽤的就是长轮询基于ajax、队列、异常处理实现长轮询简易版群聊功能1. ajax操作:异步提交,局部刷新,可以使⽤他来向服务端偷偷地发送请求$.ajax({url:'', # 控制后端提交路径type:'', # 控制请求⽅式data:{}, # 控制提交的数据dataType:"JSON", # django后端⽤HttpResponse返回json格式字符串,args不会⾃动反序列化,拿到的还是json格式字符串string字符类型,⽽如果是⽤JsonResponse返回的那么args会⾃动返序列化成前端js的对象类型 success:function(args){# 异步回调机制})def index(request):if request.method == 'POST':back_dic = {'msg':'hahaha'}return HttpResponse(json.dumps(back_dic)) # 需要return JsonResponse(back_dic) # 不需要return render(request,'index.html')# 后续在写ajax请求的时候建议你加上dataType参数ajax回顾2. 队列:先进先出,Python中有queue帮我们实现import queue# 创建⼀个队列q = queue.Queue()# 往队列中添加数据q.put(111)q.put(222)# 从队列中取数据v1 = q.get()v2 = q.get()# v3 = q.get() # 没有数据原地阻塞直到有数据# v4 = q.get_nowait() # 没有数据直接报错try:v5 = q.get(timeout=3) # 没有数据等待10s再没有就报错 queue.Emptyexcept queue.Empty as e:passprint(v1,v2)# 实际⽣产中不会使⽤上述的消息队列会使⽤功能更加的强⼤的"""消息队列rediskafkarebittMQ"""queue队列回顾基于ajax与队列其实就可以实现服务端给客户端推送消息的效果服务端给每⼀个客户端维护⼀个队列,然后再浏览器上⾯通过ajax请求朝对应队列获取数据,没有数据就原地阻塞(pending状态),有就直接拿⾛渲染即可群聊:获取群聊中某个⼈发送的消息,将该消息给每⼀个队列3. 递归:Python的递归深度官⽹是1000,是没有递归优化的,js中没有递归概念,可以⾃⼰调⾃⼰# python中有最⼤递归限制 997 998 官⽹给出的是1000"""在python中是没有尾递归优化的"""def func():func()func() # 不⾏# 在js中是没有递归的概念的函数可以⾃⼰调⽤⾃⼰属于正常的事件机制function func1(){$.ajax({url:'',type:'',data:'',dataType:'JSON',success:function({func1() # 可以})})}func1()js可以⾃⼰调⾃⼰,Python不⾏import queueq_dict = {} # {唯⼀标⽰:对应的队列,唯⼀标⽰:对应的队列}def home(request):# 获取客户端浏览器的唯⼀标识name = request.GET.get('name')# ⽣成⼀⼀对应关系q_dict[name] = queue.Queue()return render(request,'home.html',locals())def send_msg(request):if request.method == 'POST':# 获取⽤户发送的消息message = request.POST.get('content')print(message)# 将消息给所有的队列发送⼀份for q in q_dict.values():q.put(message)return HttpResponse('OK')def get_msg(request):# 获取⽤户唯⼀标⽰name = request.GET.get('name')# 回去对应的队列q = q_dict.get(name)back_dic = {'status':True,'msg':''}try:data = q.get(timeout=10)back_dic['msg'] = dataexcept queue.Empty as e:back_dic['status'] = Falsereturn JsonResponse(back_dic)后端代码实现长轮询群聊功能<h1>聊天室:{{ name }}</h1><input type="text" id="txt"><button onclick="sendMsg()">提交</button><h1>聊天记录</h1><div class="record"></div><script>function sendMsg() {// 朝后端发送消息$.ajax({url:'/send_msg/',type:'post',dataType:'JSON',data:{'content':$('#txt').val()},success:function (args) {}})}function getMsg() {// 偷偷的朝服务端要数据$.ajax({url:'/get_msg/',type:'get',data:{'name':'{{ name }}'},success:function (args) {if (args.status){// 获取消息动态渲染到页⾯上// 1 创建⼀个p标签var pEle = $('<p>');// 2 给p标签设置⽂本内容pEle.text(args.msg);// 3 将p标签添加到div内部$('.record').append(pEle)}getMsg()}})}// 页⾯加载完毕⽴刻执⾏$(function () {getMsg()})</script>前端代码2. 真实现Websocket(主流浏览器都⽀持)⽹络协议:HTTP:不加密传输https:加密传输websocket:加密传输,浏览器与服务端创建连接后默认不断开(TCP 客户端与服务端都可以recv和send),解决了服务端真正的主动给客户端发送消息3. websocket原理websoket 实现原理可以分为两部分1. 握⼿环节(handshake): ⽤握⼿环节来验证服务端是否⽀持websocket1. 浏览器访问服务端后浏览器会⽣成⼀个随机字符串2. 浏览器将⽣成的随机字符串发送给服务端(基于HTTP协议放在请求头中),⾃⼰也保留⼀份3. 服务端和客户端都对该字符串进⾏处理:跟magic string(固定的)拼接后加密(sha1+base64)4. 服务端将⽣成的加密字符串发给浏览器(基于HTTP,响应头中),做⽐对,如果⼀致说明服务端⽀持websocket,如果不⼀致说明不⽀持websocket 2. 收发数据环节基于⽹络传输的数据都是⼆进制的1. 先读取第⼆个字节后七位数据(payload)根据payload做不同的处理2. 后七位数据如果是:1. =127:继续往后读8个字节(数据报总共10个字节)2. =126:继续往后读两个字节(数据报总共4个字节)3. <=125:不再往后读取(数据报总共2个字节)3. 上述操作完成后会再往后读固定的4个字节数据(masking-key)4. 依据masking-key解析出真实的数据import socketimport hashlibimport base64# 正常的socket代码sock = socket.socket() # 默认就是TCP# 避免mac本重启服务经常报地址被占⽤的错误sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)sock.bind(('127.0.0.1', 8080))sock.listen(5)conn, address = sock.accept()data = conn.recv(1024) # 获取客户端发送的消息# print(data.decode('utf-8'))def get_headers(data):"""将请求头格式化成字典:param data::return:"""header_dict = {}data = str(data, encoding='utf-8')header, body = data.split('\r\n\r\n', 1)header_list = header.split('\r\n')for i in range(0, len(header_list)):if i == 0:if len(header_list[i].split('')) == 3:header_dict['method'], header_dict['url'], header_dict['protocol'] = header_list[i].split('')else:k, v = header_list[i].split(':', 1)header_dict[k] = v.strip()return header_dictdef get_data(info):"""按照websocket解密规则针对不同的数字进⾏不同的解密处理:param info::return:"""payload_len = info[1] & 127if payload_len == 126:extend_payload_len = info[2:4]mask = info[4:8]decoded = info[8:]elif payload_len == 127:extend_payload_len = info[2:10]mask = info[10:14]decoded = info[14:]else:extend_payload_len = Nonemask = info[2:6]decoded = info[6:]bytes_list = bytearray()for i in range(len(decoded)):chunk = decoded[i] ^ mask[i % 4]bytes_list.append(chunk)body = str(bytes_list, encoding='utf-8')return bodyheader_dict = get_headers(data) # 将⼀⼤堆请求头转换成字典数据类似于wsgiref模块client_random_string = header_dict['Sec-WebSocket-Key'] # 获取浏览器发送过来的随机字符串magic_string = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'# 全球共⽤的随机字符串⼀个都不能写错value = client_random_string + magic_string # 拼接ac = base64.b64encode(hashlib.sha1(value.encode('utf-8')).digest()) # 加密处理tpl = "HTTP/1.1 101 Switching Protocols\r\n" \"Upgrade:websocket\r\n" \"Connection: Upgrade\r\n" \"Sec-WebSocket-Accept: %s\r\n" \"WebSocket-Location: ws://127.0.0.1:8080\r\n\r\n"response_str = tpl %ac.decode('utf-8') # 处理到响应头中# 基于websocket收发消息conn.send(bytes(response_str,encoding='utf-8'))while True:data = conn.recv(1024)# print(data) # 加密数据 b'\x81\x89\n\x94\xac#\xee)\x0c\xc6\xaf)I\xb6\x80'value = get_data(data)print(value)后端代码实现websocket前端代码:<script>var ws = new WebSocket('ws://127.0.0.1:8080/')// 这⼀句话帮你完成了握⼿环节所有的操作// 1 ⽣成随机字符串// 2 对字符串做拼接和加码操作// 3 接受服务端返回的字符串做⽐对</script>4. Django中使⽤channels模块⽀持websocket后端框架有的是不⽀持websocket的,是需要借助模块来实现的"""后端框架django默认不⽀持websocket第三⽅模块:channelsflask默认不⽀持websocket第三⽅模块:geventwebsockettornado默认⽀持websocket"""Django下载第三⽅模块:channels需要注意的点:1. 版本不要⽤最新版的,推荐使⽤2.3,如果你安装最新版可能会出现⾃动将你本地的django版本升级为最新版2. Python解释器最好使⽤3.6版本,不会带来未知错误channels模块内部帮你封装了握⼿:加密解密等操作安装:pip3 install channels==2.3基本使⽤1. 注册appINSTALLED_APPS = ['channels']注册完成后,django会⽆法启动,会直接报错CommandError: You have not set ASGI_APPLICATION, which is needed to run the server.2. 配置# 2 配置变量ASGI_APPLICATION = 'sendsys.routing.application'# ASGI_APPLICATION = '项⽬名同名的⽂件名.⽂件夹下py⽂件名默认就叫routing.该py⽂件内部的变量名默认就叫application'3. 去项⽬名同名的⽂件夹下建routing⽂件,定义application变量from channels.routing import ProtocolTypeRouter,URLRouterfrom django.conf.urls import urlfrom app01 import consumersapplication = ProtocolTypeRouter({'websocket':URLRouter([# 书写websocket路由与视图函数对应关系url(r'^index/',consumers.XXXClass) # CBV])})上述配置完成后Django就即⽀持HTTP也⽀持websocket了,并且Django由wsgiref变为asgi启动http 的在路由在urls.py中写,视图函数在views.py中写websocket 路由在routing.py中写,视图函数在views.py的⽂件夹下新建⼀般叫做consumers.py⽂件中写,只⽀持CBV。

微信公众号关联小程序,实现消息推送。

微信公众号关联小程序,实现消息推送。

微信公众号关联⼩程序,实现消息推送。

1.⾸先需要公众号绑定好微信⼩程序。

2.创建H5页⾯,获取授权,拿到公众号的code。

下⾯是页⾯代码,直接复制即可。

3.在⼩程序中⽤web-view 将H5引⼊到⼩程序中。

下⾯直接上代码:index.js 只需要在data中添加链接即可/*** 页⾯的初始数据*/data: {link:"https:///connect/oauth2/authorize?appid=你的公众号appid&redirect_uri=你的H5页⾯地址&response_type=code&scope=snsapi_base&state=1#wechat_redirect"}index.wxml<!--page/index/index.wxml--><text>page/index/index.wxml</text><view><view class=""><web-view src="{{link}}"></web-view></view></view>4.拿到公众号的code后,需要将code传⼊到后台,获取拿到openid。

下⾯放个关于后台获取openid连接的教程https:///kongwei521/article/details/79741509(C#案例)⾄此就可以通过公众号的openid 来给关注的⽤户推送消息啦。

前⼈种树,后⼈乘凉。

记住⼩程序的获取⼩程序的openid是没有⽤的,只能获取公众号的openid才可以。

php实现微信模板消息推送

php实现微信模板消息推送

php实现微信模板消息推送本⽂实例为⼤家分享了php微信模板消息推送的具体代码,供⼤家参考,具体内容如下1.微信公众号模板消息配置2.PHP代码/*** 发送模板消息*/public function send_notice(){//获取access_tokenif ($_COOKIE['access_token']){$access_token2=$_COOKIE['access_token'];}else{$json_token=$this>curl_post("https:///cgi-bin/token?grant_type=client_credential&appid='.$appid.'&secret='.$appsecret.'"); $access_token1=json_decode($json_token,true);$access_token2=$access_token1['access_token'];setcookie('access_token',$access_token2,7200);}//模板消息$json_template = $this->json_tempalte();$url="https:///cgi- bin/message/template/send?access_token=".$access_token2;$res=$this->curl_post($url,urldecode($json_template));if ($res['errcode']==0){return '发送成功';}else{return '发送失败';}}/*** 将模板消息json格式化*/public function json_tempalte(){//模板消息$template=array('touser'=>'.$openid.', //⽤户openid'template_id'=>".$tenpalate_id.", //在公众号下配置的模板id'url'=>".$uel.", //点击模板消息会跳转的链接'topcolor'=>"#7B68EE",'data'=>array('first'=>array('value'=>urlencode("您的活动已通过"),'color'=>"#FF0000"),'keyword1'=>array('value'=>urlencode('测试⽂章标题'),'color'=>'#FF0000'), //keyword需要与配置的模板消息对应'keyword2'=>array('value'=>urlencode(date("Y-m-d H:i:s")),'color'=>'#FF0000'),'keyword3'=>array('value'=>urlencode('测试发布⼈'),'color'=>'#FF0000'),'keyword4'=>array('value'=>urlencode('测试状态'),'color'=>'#FF0000'),'remark' =>array('value'=>urlencode('备注:这是测试'),'color'=>'#FF0000'), ));$json_template=json_encode($template);return $json_template;}/*** @param $url* @param array $data* @return mixed* curl请求*/function curl_post($url , $data=array()){$ch = curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);// POST数据curl_setopt($ch, CURLOPT_POST, 1);// 把post的变量加上curl_setopt($ch, CURLOPT_POSTFIELDS, $data);$output = curl_exec($ch);curl_close($ch);return $output;}以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

微信小程序模板消息限制实现无限制主动推送的示例代码

微信小程序模板消息限制实现无限制主动推送的示例代码

微信⼩程序模板消息限制实现⽆限制主动推送的⽰例代码需求背景基于微信的通知渠道,微信⼩程序为开发者提供了可以⾼效触达⽤户的模板消息能⼒,在⽤户本⼈与⼩程序页⾯有交互⾏为后触发,通过微信聊天列表中的服务通知可快捷进⼊查看消息,点击查看详情还能跳转到下发消息的⼩程序的指定页⾯。

微信⼩程序允许下发模板消息的条件分为两类:⽀付或者提交表单。

通过提交表单来下发模板消息的限制为“允许开发者向⽤户在7天内推送有限条数的模板消息(1次提交表单可下发1条,多次提交下条数独⽴,相互不影响)”。

然⽽,⽤户1次触发7天内推送1条通知是明显不够⽤的。

⽐如,签到功能利⽤模板消息的推送来提醒⽤户每天签到,只能在⽤户前⼀天签到的情况下,获取⼀次推送模板消息的机会,然后⽤于第⼆天向该⽤户发送签到提醒。

但是很多情况下,⽤户在某⼀天忘记签到,系统便失去了提醒⽤户的权限,导致和⽤户断开了联系;再⽐如,系统想主动告知⽤户即将做某活动,然⽽由于微信⼩程序被动触发通知的限制,系统将⽆法主动推送消息。

如何突破模板消息的推送限制?突破⼝:“1次提交表单可下发1条,多次提交下发条数独⽴,相互不影响”为了突破模板消息的推送限制,实现7天内任性推送,只需收集到⾜够的推送码,即每次提交表单时获取到的formId。

⼀个formId代表着开发者有向当前⽤户推送模板消息的⼀次权限。

客户端收集推送码当表单组件中的属性report-submit=true时表⽰发送模板消息,提交表单便可以获取formId。

接下来只要对原先的页⾯进⾏改造,将⽤户原先绑定了点击事件的界⾯⽤表单组件中的button按钮组件来代替,即把⽤户的交互点击的bindtap事件由表单bindsubmit来代替,从⽽捕获⽤户的点击事件来⽣成更多的推送码。

// 收集推送码Page({formSubmit: funcition(e) {let formId = e.detail.formId;this.collectFormIds(formId); //保存推送码let type = e.detail.target.dataset.type; // 根据type执⾏点击事件},collectFormIds: function(formId) {let formIds = app.globalData.globalFormIds; // 获取全局推送码数组if (!formIds)formIds = [];let data = {formId: formId,expire: new Data().getTime() + 60480000 // 7天后的过期时间戳}formIds.push(data);app.globalData.globalFormIds = formIds;},})上报推送码等待⽤户下⼀次发起⽹络请求时,将globalFormIds发送给服务器。

微信企业号主动推送文本消息的ASP代码

微信企业号主动推送文本消息的ASP代码

'ASP文件需要以UTF-8的格式保存,否则乱码.'以下两行代码是为了通过微信接口验证的。

'response.write request("echostr")'response.enddim signature '微信加密签名dim timestamp '时间戳dim nonce '随机数'dim echostr '随机字符串dim Tokendim signaturetmptoken="xxxxxxxxxxxxxxxx" '您在后台添写的tokensignature = Request("signature")nonce = Request("nonce")timestamp = Request("timestamp")dim ToUserName '开发者微信号dim FromUserName'发送方帐号(一个OpenID)dim CreateTime '消息创建时间(整型)dim MsgType 'textdim Content '文本消息内容dim MsgId '消息id,64位整型set xml_dom = Server.CreateObject("MSXML2.DOMDocument")'此处根据您的实际服务器情况改写xml_dom.load requestToUserName=xml_dom.getElementsByTagName_r("ToUserName").item(0).text FromUserName=xml_dom.getElementsByTagName_r("FromUserName").item(0).text MsgType=xml_dom.getElementsByTagName_r("MsgType").item(0).textif MsgType="text" thenContent=xml_dom.getElementsByTagName_r("Content").item(0).textend ifset xml_dom=Nothingdim mingling,mlidmingling=replace(content,chr(13),"")mingling=trim(replace(mingling,chr(10),""))If IsNumeric(mingling) Then'如果是数字returnstr= FromUserName'这里添加您的回复代码else '非数字if mingling="Hello2BizUser" then '表示为新的用户关注,被关注后发布returnstr="欢迎关注<我的工资条>"&VBCrLf &_"快告诉你的Boss,下载“飞信工资条”软件可以将工资条群发到手机上啦!"elsereturnstr="快告诉你的Boss,下载“飞信工资条”软件可以将工资条群发到手机上啦!" end ifend ifif len(returnstr)=0 thenreturnstr="个人微信号/QQ:35491331"&VBCrLfend if'returnstr=returnstr&"帮助回复数字0 "strresponse="" &_""&fromusername&"" &_""&tousername&"" &_""&now&"" &_"text" &_"" & returnstr & "" &_"0" &_""response.write strresponse。

python使用itchat发送微信消息提醒

python使用itchat发送微信消息提醒

python使⽤itchat发送微信消息提醒最近在学习⼀点python,先找了找有趣的应⽤,实际修改跑了⼀下提⾼兴趣程度。

找到itchat,它的简介是这样的:“itchat是⼀个开源的微信个⼈号接⼝,使⽤python调⽤微信从未如此简单。

使⽤不到三⼗⾏的代码,你就可以完成⼀个能够处理所有信息的微信机器⼈。

当然,该api的使⽤远不⽌⼀个机器⼈,更多的功能等着你来发现,⽐如。

该接⼝与公众号接⼝共享类似的操作⽅式,学习⼀次掌握两个⼯具。

如今微信已经成为了个⼈社交的很⼤⼀部分,希望这个项⽬能够帮助你扩展你的个⼈的微信号、⽅便⾃⼰的⽣活。

”itchat使⽤需要先下载安装,安装过程很简单,直接pip install itchat我安装的python3.6⾃带pip,如果没有pip的话我建议升级python。

在⽹上已经有不少itchat的应⽤,最简单的就是查找特定⽤户来发送微信消息。

我结合另⼀个⽰范将消息扩展了⼀点:间隔特定时间给特定的好友发送微信消息提醒(久坐提醒?)代码如下:1#-*-coding:utf8-*-2import itchat3import datetime, os, platform,time45def timerfun(sched_time) :6 flag = 07while True:8 now = datetime.datetime.now()9if now > sched_time and now < sched_time + datetime.timedelta(seconds=1) : # 因为时间秒之后的⼩数部分不⼀定相等,要标记⼀个范围判断10 send_move()11 time.sleep(1) # 每次判断间隔1s,避免多次触发事件12 flag = 113else :14#print('schedual time is {0}'.format(sched_time))15#print('now is {0}'.format(now))16if flag == 1 :17 sched_time = sched_time + datetime.timedelta(hours=1) # 把⽬标时间增加⼀个⼩时,⼀个⼩时后触发再次执⾏18 flag = 01920def send_move:21# nickname = input('please input your firends\' nickname : ' )22# 想给谁发信息,先查找到这个朋友,name后填微信备注即可,deepin测试成功23# users = itchat.search_friends(name=nickname)24 users = itchat.search_friends(name='⼤壮') # 使⽤备注名来查找实际⽤户名25#获取好友全部信息,返回⼀个列表,列表内是⼀个字典26print(users)27#获取`UserName`,⽤于发送消息28 userName = users[0]['UserName']29 itchat.send("该起来动⼀下了!",toUserName = userName)30print('succeed')3132if__name__=='__main__':33 itchat.auto_login(hotReload=True) # ⾸次扫描登录后后续⾃动登录34 sched_time = datetime.datetime(2017,11,6,16,24,10) #设定初次触发事件的事件点35print('run the timer task at {0}'.format(sched_time))36 timerfun(sched_time)有⼏个地⽅调试了⼀下:1. 第9⾏判断时间是否到达指定时间处,因为now = datetime.datetime.now()返回的时间精确到了ms,所以直接拿精确到s的特定时间去⽐较会移植为False。

用Python实现微信推送消息

用Python实现微信推送消息这里咱们使用了一个第三方工具pushplus# 单人推送实现步骤:1、用微本本上。

代码展示import requests# Python源码资料电子书领取群 279199867def send_wechat(msg):token = 'XXXXXXXXXXXX'#前边复制到那个tokentitle = 'title1'content = msgtemplate = 'html'url = f'/send?token={token}&title={title}&content={content }&template={template}'print(url)r = requests.get(url=url)print(r.text)if __name__ == '__main__':msg = 'Life is short I use python'send_wechat(msg)在手机上看一下结果局限性:这个只能给自己推送,别人推送不了。

那怎么给别人推送呢?# 一对多推送实现步骤1、在一对多推送的tab页面里,新建群组,并记录下群组编码。

2、点击生成二维码,将二维码发给要接受消息的人。

让他们用微信扫码。

3、扫码后,看看订阅人,扫码之后的人,会显示在这里。

给这个群组发送的消息,这里的人都会接收到。

4、写代码发送消息到微信import requestsdef send_wechat(msg):token = ' XXXXXXXXXXXXXXXXXX' #前边复制到那个tokentitle = 'test notice title'content = msgtemplate = 'html'topic = '1'url = f'http:///send?token={token}&title={title}&content={c ontent}&template={template}&topic={topic}'print(url)r = requests.get(url=url)print(r.text)if __name__ == '__main__':msg = 'this is a one to more lizi'send_wechat(msg)效果展示至此到这里就完成啦!来源:网络。

java推送企业微信消息

java推送企业微信消息<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.8</version></dependency>所需配置cropId: 企业微信idcorpsecret 应⽤的凭证密钥agentid 企业应⽤的id1、封装消息体//封装消息体可以直接⽤json也可以创建对象public void send(String msg, String userIds) {//1.创建⽂本消息对象TextMessage message = new TextMessage();message.setTouser(userIds);//1.2必需message.setMsgtype("text");message.setAgentid(agentId);Text text = new Text();text.setContent(msg);message.setText(text);sendMessage(0, message);}@Datapublic class TextMessage extends BaseMessage {/*** ⽂本TextMessage*/private Text text;/*** 表⽰是否是保密消息,0表⽰否,1表⽰是,默认0*/private int safe;}@Datapublic class Text {/*** 消息内容,最长不超过2048个字节*/private String content;}2.请求token及推送消息public void sendMessage(Integer mark, BaseMessage message) {String key = "wx_accessToken:" + platformVO.getAppId() + "_secret:" + platformVO.getSecret(); String token = null;token = redisTemplate.opsForValue().get(key);//mark⼤于0代表token失效if (null == token || mark > 0) {AccessToken accessToken = WeiXinUtil.getAccessToken(platformVO.getAppId(), platformVO.getSecret());token = accessToken.getToken();redisTemplate.opsForValue().set(key, accessToken.getToken(), accessToken.getExpiresIn() - 4, TimeUnit.SECONDS);}("企业微信token:" + token);//3.发送消息:调⽤业务类,发送消息String jsonMessage = JSONObject.toJSONString(message);//2.获取请求的urlString sendMessage_url = "https:///cgi-bin/message/send?access_token=" + token;//3.调⽤接⼝,发送消息String result = HttpUtil.doPost(sendMessage_url, null, jsonMessage, null);JSONObject jsonObject = JSONObject.parseObject(result, JSONObject.class);List<String> errorCode = Lists.newArrayList();errorCode.add("40014");errorCode.add("42001");//4.错误消息处理if (null != jsonObject) {if (errorCode.contains(jsonObject.getString("errcode")) && mark < 3) {("消息推送失败 errcode:{}", jsonObject.getInteger("errcode") + "重新获取token");try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}sendMessage(mark + 1, message);} else if (0 != jsonObject.getInteger("errcode")) {log.error("消息推送失败 errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg"));} else {("企业微信消息推送成功!");}}}/*** 所需要⽤到的⼯具类* @author tangh*/@Slf4jpublic class WeiXinUtil {/*** 微信的请求url* 获取access_token的接⼝地址(GET)限200(次/天)*/public final static String ACCESS_TOKEN_URL = "https:///cgi-bin/gettoken?corpid={corpId}&corpsecret={corpsecret}"; /*** 1.发起https请求并获取结果** @param requestUrl 请求地址* @param outputStr 提交的数据* @return JSONObject(通过JSONObject.get ( key)的⽅式获取json对象的属性值)*/public static JSONObject httpRequest(String requestUrl, String outputStr) {JSONObject jsonObject = null;CloseableHttpResponse response = null;try {CloseableHttpClient httpClient = HttpClients.createDefault();HttpPost httpPost = new HttpPost(requestUrl);StringEntity requestEntity = new StringEntity(outputStr, "utf-8");httpPost.setEntity(requestEntity);httpPost.setHeader("Content-Type", "application/json;charset=UTF-8");response = httpClient.execute(httpPost);String result = EntityUtils.toString(response.getEntity(), "utf-8");} catch (ConnectException ce) {ce.printStackTrace();} catch (Exception e) {e.printStackTrace();} finally {try {if (response != null) {response.close();}} catch (IOException e) {log.error("POST请求response关闭异常,错误信息为{}", e.getMessage(), e);}}return jsonObject;}/*** 发起http请求获取返回结果** @param requestUrl 请求地址* @return*/public static String httpRequest(String requestUrl) {String result = null;HttpGet httpGet = new HttpGet(requestUrl);CloseableHttpResponse response = null;try (CloseableHttpClient httpClient = HttpClients.createDefault()) {response = httpClient.execute(httpGet);result = EntityUtils.toString(response.getEntity(), "utf-8");} catch (IOException e) {e.printStackTrace();} finally {try {if (response != null) {response.close();}} catch (IOException e) {log.error("GET请求response关闭异常,错误信息为{}", e.getMessage(), e);}}return result;}/*** 3.获取access_token** @param appid 凭证* @param appsecret 密钥* @return*/public static AccessToken getAccessToken(String appid, String appsecret) {AccessToken accessToken = null;String requestUrl = ACCESS_TOKEN_URL.replace("{corpId}", appid).replace("{corpsecret}", appsecret); JSONObject jsonObject = JSONObject.parseObject(httpRequest(requestUrl), JSONObject.class);// 如果请求成功if (null != jsonObject) {try {accessToken = new AccessToken();accessToken.setToken(jsonObject.getString("access_token"));accessToken.setExpiresIn(jsonObject.getInteger("expires_in"));} catch (JSONException e) {accessToken = null;// 获取token失败log.error("获取token失败 errcode:{} errmsg:{}" + jsonObject.getInteger("errcode") + ":" + jsonObject.getString("errmsg")); }return accessToken;}}@Slf4jpublic final class HttpUtil {/*** 超时时间*/private static final Integer TIMEOUT = 20000;private HttpUtil() {}/*** 发送post请求** @param url url* @param header header* @param body body* @param param param* @return string*/public static String doPost(String url, Map<String, String> header, String body, Map<String, Object> param) { String result = "";BufferedReader in = null;PrintWriter out = null;try {// 设置 urlurl = getUrl(url, param);URL realUrl = new URL(url);HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();connection.setRequestMethod("POST");// 设置 headerif (header != null) {for (String key : header.keySet()) {connection.setRequestProperty(key, header.get(key));}}// 设置请求 bodyconnection.setDoOutput(true);connection.setDoInput(true);//设置连接超时和读取超时时间connection.setConnectTimeout(TIMEOUT);connection.setReadTimeout(TIMEOUT);try {out = new PrintWriter(connection.getOutputStream());// 保存bodyout.print(body);// 发送bodyout.flush();} catch (Exception e) {e.printStackTrace();}("connection: " + connection);("body: " + out);try {// 获取响应bodyin = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)); String line;while ((line = in.readLine()) != null) {result += line;}} catch (Exception e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}return result;}/*** 发送get请求** @param url url* @param header header* @param param param* @return string*/public static String doGet(String url, Map<String, String> header, Map<String, Object> param) { String result = "";BufferedReader in = null;try {url = getUrl(url, param);// 设置 urlURL realUrl = new URL(url);HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection(); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); connection.setRequestProperty("Connection", "Keep-Alive");connection.setUseCaches(false);connection.setRequestMethod("GET");// 设置 headerif (header != null) {for (String key : header.keySet()) {connection.setRequestProperty(key, header.get(key));}}in = new BufferedReader(new InputStreamReader(connection.getInputStream()));String line;while ((line = in.readLine()) != null) {result += line;}} catch (Exception e) {log.error(e.getMessage());return null;}return result;}/*** @param url url* @param param 请求参数* @return String*/public static String getUrl(String url, Map<String, Object> param) {if (null != param && param.size() > 0) {StringBuilder stringBuilder = new StringBuilder(url);stringBuilder.append("?");Set<Map.Entry<String, Object>> entries = param.entrySet();for (Map.Entry<String, Object> entry : entries) {stringBuilder.append(entry.getKey() + "=" + entry.getValue() + "&");}url = stringBuilder.substring(0, stringBuilder.length() - 1);}return url;}}。

微信小程序订阅消息推送

微信⼩程序订阅消息推送微信⼩程序订阅消息推送开发配置配置服务器配置在⼩程序后台开启消息推送(开发-开发设置-消息推送)这⾥需要服务提供验证签名的接⼝将下⾯代码发布到服务器并使⽤80或443端⼝访问(我在使⽤其他端⼝时出现问题 80和443端⼝正常)例如:/// <summary>/// 接⼝认证/// </summary>/// <param name="echostr">回传参数</param>/// <param name="signature">加密字段</param>/// <param name="timestamp">时间搓</param>/// <param name="nonce">随机字符串</param>/// <returns></returns>[HttpGet,Route("api/wx/CheckWxSignature")]public IActionResult CheckWxSignature(string echostr, string signature, string timestamp, string nonce){string token = "test";if (!CheckSignature(token, signature, timestamp, nonce)){return Ok("error");}return Ok(echostr);}/// <summary>/// 验证微信签名/// </summary>private bool CheckSignature(string token, string signature, string timestamp, string nonce){string[] ArrTmp = { token, timestamp, nonce };Array.Sort(ArrTmp);string tmpStr = string.Join("", ArrTmp);var data = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(tmpStr));var sb = new StringBuilder();foreach (var t in data){sb.Append(t.ToString("X2"));}tmpStr = sb.ToString();tmpStr = tmpStr.ToLower();if (tmpStr == signature){return true;}else{return false;}}⼩程序配置⼩程序订阅消息在每次发送消息前需要询问⽤户是否授权,授权成功后才能调⽤。

python操作微信自动发消息的实现(微信聊天机器人)

python操作微信⾃动发消息的实现(微信聊天机器⼈)前⾔最近在学习python,发现⼀个微信⾃动发消息的⼩demo感觉很有意思,试了⼀下,不成功,因为demo中⽤的是itchat这个库来操作微信,⽽这个库是通过微信⽹页版来操作微信的,现在微信⽹页版已经不能登录了所以失败,我⼜试了第⼆种⽅法,我试图找到微信界⾯上的搜索框控件,使⽤搜索框控件找到想法消息的⼈,然后发送消息,结果就是⼜失败了,为啥呢?经过我翻翻翻,找找找,发现微信的界⾯是使⽤duilib实现的,界⾯都是画上去的,控件只是逻辑上存在,⽽实际没有,我们根本获取不到,然后我只能通过⼿动移动⿏标的⽅式来实现了1.打开微信,固定在左上⾓,这样便于我们固定微信上各个控件所在坐标2.把⿏标移动到微信左边的“通讯录”按钮上,单击,打开通讯录3.把⿏标移动到搜索框把你要找的⼈的微信名复制进去,回车,打开对话框(你要问我为什么要先打开通讯录再去搜索框搜?问就是不知道,其实是经过我的实验这样⽐较稳定,直接搜有bug,如果你能找到其他的解决办法请告诉我,谢谢啦)4.把你要发送的话复制到对话框,回车或者alt+s 发送这就结束了,下⾯是部分代码import win32clipboard as wimport win32conimport win32apiimport win32guiimport time#把⽂字放⼊剪贴板def setText(aString):w.OpenClipboard()w.EmptyClipboard()w.SetClipboardData(win32con.CF_UNICODETEXT,aString)w.CloseClipboard()#模拟ctrl+Vdef ctrlV():win32api.keybd_event(17,0,0,0) #ctrlwin32api.keybd_event(86,0,0,0) #Vwin32api.keybd_event(86,0,win32con.KEYEVENTF_KEYUP,0)#释放按键win32api.keybd_event(17,0,win32con.KEYEVENTF_KEYUP,0)#模拟alt+sdef altS():win32api.keybd_event(18,0,0,0)win32api.keybd_event(83,0,0,0)win32api.keybd_event(83,0,win32con.KEYEVENTF_KEYUP,0)win32api.keybd_event(18,0,win32con.KEYEVENTF_KEYUP,0)# 模拟enterdef enter():win32api.keybd_event(13,0,0,0)win32api.keybd_event(13,0,win32con.KEYEVENTF_KEYUP,0)#模拟单击def click():win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)#移动⿏标的位置def movePos(x,y):win32api.SetCursorPos((x,y))if __name__=="__main__":#获取⿏标当前位置#hwnd=win32gui.FindWindow("MozillaWindowClass",None)hwnd = win32gui.FindWindow("WeChatMainWndForPC", None)win32gui.ShowWindow(hwnd,win32con.SW_SHOW)win32gui.MoveWindow(hwnd,0,0,1000,700,True)time.sleep(0.01)#1.移动⿏标到通讯录位置,单击打开通讯录movePos(28,147)click()#2.移动⿏标到搜索框,单击,输⼊要搜索的名字movePos(148,35)click()setText('胡歌')ctrlV()time.sleep(1) #别问我为什么要停1秒,问就是给微信⼀个反应的时间,他反应慢反应不过来,其他位置暂停的原因同样enter()time.sleep(1)#3.复制要发送的消息,发送setText('你好啊')ctrlV()altS()到此这篇关于python操作微信⾃动发消息的实现(微信聊天机器⼈)的⽂章就介绍到这了,更多相关python操作微信⾃动发消息内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档