官方文档 (由于本人公众号权限的原因,这一节的大部分例子都没有测试)
注意:
1、对于认证订阅号,群发接口每天可成功调用1次,此次群发可选择发送给全部用户或某个标签;
2、对于认证服务号虽然开发者使用高级群发接口的每日调用限制为100次,但是用户每月只能接收4条,无论在公众平台网站上,还是使用接口群发,用户每月只能接收4条群发消息,多于4条的群发将对该用户发送失败;
3、开发者可以使用预览接口校对消息样式和排版,通过预览接口可发送编辑好的消息给指定用户校验效果;
4、群发过程中,微信后台会自动进行图文消息原创校验,请提前设置好相关参数(send_ignore等);
5、开发者可以主动设置 clientmsgid 来避免重复推送。
6、群发接口每分钟限制请求60次,超过限制的请求会被拒绝。
7、图文消息正文中插入自己帐号和其他公众号已群发文章链接的能力
关于群发时使用is_to_all为true使其进入公众号在微信客户端的历史消息列表:
1、使用is_to_all为true且成功群发,会使得此次群发进入历史消息列表。
2、为防止异常,认证订阅号在一天内,只能使用is_to_all为true进行群发一次,或者在公众平台官网群发(不管本次群发是对全体还是对某个分组)一次。
以避免一天内有2条群发进入历史消息列表。
3、类似地,服务号在一个月内,使用is_to_all为true群发的次数,加上公众平台官网群发(不管本次群发是对全体还是对某个分组)的次数,最多只能是4次。
4、设置is_to_all为false时是可以多次群发的,但每个用户只会收到最多4条,且这些群发不会进入历史消息列表。
另外,请开发者注意,本接口中所有使用到media_id的地方,现在都可以使用素材管理中的永久素材media_id了。请但注意,使用同一个素材群发出去的链接是一样的,
这意味着,删除某一次群发,会导致整个链接失效。
群发图文消息:
1、首先,预先将图文消息中需要用到的图片,使用上传图文消息内图片接口,上传成功并获得图片 URL;
def upload_newsurl(self,access_token,picfile):
upload_url = 'https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=%s'% access_token
postData ={
'media':open(picfile,'rb')
}
response = requests.post(upload_url,files=postData)
return json.loads(response)['url']
2.上传图文消息素材,需要用到图片时,请使用上一步获取的图片 URL;
如果需要在群发图文中插入小程序,则在调用上传图文消息素材接口时,需在content字段中添加小程序跳转链接,有以下三种样式的可供选择。 小程序卡片跳转小程序,代码示例:
文字跳转小程序,代码示例:
图片跳转小程序,代码示例:
|
3. 根据标签进行群发:
def send_massmsg(access_token,postData):
send_url ='https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token=%s'% access_token
response = requests.post(send_url,json.dumps(postData))
return json.loads(response.text)
mpnews |
|
text |
|
voice |
|
image |
|
mpvideo |
|
卡券消息 |
|
视频消息的media_id需要通过 先上传视频,再从素材中获取得到的media_id为准:
def get_uploadedvideo(self,access_token,media_id,video_title='',video_intro=''):
'''为群发视频消息使用
https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Batch_Sends_and_Originality_Checks.html
'''
upload_url = 'https://api.weixin.qq.com/cgi-bin/media/uploadvideo?access_token=%s'% access_token
postData ={
'media_id':media_id,
"title": video_title,
"description": video_intro
}
result = requests.post(upload_url,json.dumps(postData,ensure_ascii=False).encode('utf-8'))
return json.loads(result.text)
返回数据示例(正确时的JSON返回结果):
{
"errcode":0,
"errmsg":"send job submission success",
"msg_id":34182,
"msg_data_id": 206227730 #图文消息专有
}
预览消息:
POST数据说明
POST数据示例如下:
图文消息(其中media_id与根据分组群发中的media_id相同):
{
"touser":"OPENID",
"mpnews":{
"media_id":"123dsdajkasd231jhksad"
},
"msgtype":"mpnews"
}
文本:
{
"touser":"OPENID",
"text":{
"content":"CONTENT"
},
"msgtype":"text"
}
语音(其中media_id与根据分组群发中的media_id相同):
{
"touser":"OPENID",
"voice":{
"media_id":"123dsdajkasd231jhksad"
},
"msgtype":"voice"
}
图片(其中media_id与根据分组群发中的media_id相同):
{
"touser":"OPENID",
"image":{
"media_id":"123dsdajkasd231jhksad"
},
"msgtype":"image"
}
视频(其中media_id与根据分组群发中的media_id相同):
{
"touser":"OPENID",
"mpvideo":{ "media_id":"IhdaAQXuvJtGzwwc0abfXnzeezfO0NgPK6AQYShD8RQYMTtfzbLdBIQkQziv2XJc",
},
"msgtype":"mpvideo"
}
卡券:
{ "touser":"OPENID",
"wxcard":{
"card_id":"123dsdajkasd231jhksad",
"card_ext": "{"code":"","openid":"","timestamp":"1402057159","signature":"017bb17407c8e0058a66d72dcc61632b70f511ad"}"
},
"msgtype":"wxcard"
}
请注意,上述JSON数据中的touser字段都可以改为towxname,这样就可以针对微信号进行预览(而非openID),towxname和touser同时赋值时,以towxname优先。修改后JSON数据如下(以图文消息为例): 图文消息:
{
"towxname":"示例的微信号",
"mpnews":{
"media_id":"123dsdajkasd231jhksad"
},
"msgtype":"mpnews"
}
def preview_massmsg(access_token,postData):
'''预览接口'''
send_url = 'https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token=%s' % access_token
response = requests.post(send_url, json.dumps(postData))
return json.loads(response.text)
删除消息:
def del_massmsg(access_token,msg_id, article_idx=0):
'''只能删除图文和视频消息.收到消息的用户点击时会显示已被删除'''
del_url = 'https://api.weixin.qq.com/cgi-bin/message/mass/delete?access_token=%s'% access_token
postData={
"msg_id": msg_id,
"article_idx": article_idx
}
response = requests.post(del_url, json.dumps(postData))
return json.loads(response.text)
查询群发消息发送状态
def get_massmsg_status(access_token,msg_id):
'''查看消息状态'''
send_url = 'https://api.weixin.qq.com/cgi-bin/message/mass/get?access_token=%s' % access_token
postData = {
"msg_id": msg_id
}
response = requests.post(send_url, json.dumps(postData))
return json.loads(response.text)
事件推送群发结果
由于群发任务提交后,群发任务可能在一定时间后才完成,因此,群发接口调用时,仅会给出群发任务是否提交成功的提示,若群发任务提交成功,则在群发任务结束时,会向开发者在公众平台填写的开发者URL(callback URL)推送事件。
需要注意,由于群发任务彻底完成需要较长时间,将会在群发任务即将完成的时候,就推送群发结果,此时的推送人数数据将会与实际情形存在一定误差
推送的XML结构如下(发送成功时),已增加原创校验结果和群发图文的url:
<xml>
<ToUserName><![CDATA[gh_4d00ed8d6399]]></ToUserName>
<FromUserName><![CDATA[oV5CrjpxgaGXNHIQigzNlgLTnwic]]></FromUserName>
<CreateTime>1481013459</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[MASSSENDJOBFINISH]]></Event>
<MsgID>1000001625</MsgID>
<Status><![CDATA[err(30003)]]></Status>
<TotalCount>0</TotalCount>
<FilterCount>0</FilterCount>
<SentCount>0</SentCount>
<ErrorCount>0</ErrorCount>
<CopyrightCheckResult>
<Count>2</Count>
<ResultList>
<item>
<ArticleIdx>1</ArticleIdx>
<UserDeclareState>0</UserDeclareState>
<AuditState>2</AuditState>
<OriginalArticleUrl><![CDATA[Url_1]]></OriginalArticleUrl>
<OriginalArticleType>1</OriginalArticleType>
<CanReprint>1</CanReprint>
<NeedReplaceContent>1</NeedReplaceContent>
<NeedShowReprintSource>1</NeedShowReprintSource>
</item>
<item>
<ArticleIdx>2</ArticleIdx>
<UserDeclareState>0</UserDeclareState>
<AuditState>2</AuditState>
<OriginalArticleUrl><![CDATA[Url_2]]></OriginalArticleUrl>
<OriginalArticleType>1</OriginalArticleType>
<CanReprint>1</CanReprint>
<NeedReplaceContent>1