5 临时素材

公众号经常有需要用到一些临时性的多媒体素材的场景,例如在使用接口特别是发送消息时,对多媒体文件、多媒体消息的获取和调用等操作,是通过MediaID来进行的。

譬如实现“图”尚往来中,粉丝给公众号发送图片消息,便产生一临时素材。

因为永久素材有数量的限制,但是公众号又需要临时性使用一些素材,因而产生了临时素材。这类素材不在微信公众平台后台长期存储,所以在公众平台官网的素材管理中查询不到,但是可以通过接口对其操作。

其他详情请以公众平台官网wiki介绍为依据。

5.1 新建临时素材

接口详情请依据wiki介绍。提供参考代码如何上传素材作为临时素材,供其它接口使用。

vim media.py 编写完成之后,直接运行media.py 即可上传临时素材。

  [py]
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
# -*- coding: utf-8 -*- # filename: media.py from basic import Basic import urllib2 import poster.encode from poster.streaminghttp import register_openers class Media(object): def __init__(self): register_openers() # 上传图片 def upload(self, accessToken, filePath, mediaType): openFile = open(filePath, "rb") param = {'media': openFile} postData, postHeaders = poster.encode.multipart_encode(param) postUrl = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=%s" % ( accessToken, mediaType) request = urllib2.Request(postUrl, postData, postHeaders) urlResp = urllib2.urlopen(request) print urlResp.read() if __name__ == '__main__': myMedia = Media() accessToken = Basic().get_access_token() filePath = "D:/code/mpGuide/media/test.jpg" # 请按实际填写 mediaType = "image" myMedia.upload(accessToken, filePath, mediaType)

5.2 获取临时素材MediaID

临时素材的MediaID 没有提供特定的接口进行统一查询,因此有俩种方式

1) 通过接口上次的临时素材,在调用成功的情况下,从返回JSON数据中提取MediaID,可临时使用

2) 粉丝互动中的临时素材,可从xml 数据提取MediaID,可临时使用

5.3 下载临时素材

5.3.1 手工体验

开发者如何保存粉丝发送的图片呢?

接口文档:获取临时素材接口,为方便理解,从最简单浏览器获取素材的方法入手,根据实际情况,浏览器输入网址: https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID (自行替换数据) ACCESS_TOKEN 如 “AccessToken”章节讲解 MEDIA_ID 如 图尚往来/接受图片消息xml中的MediaId 讲解 只要数据正确,则会下载图片到本地,如下图:

5.3.2 接口获取

现在已经理解这个接口的功能了,只剩码代码了。

vim media.py

  [py]
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
# -*- coding: utf-8 -*- # filename: media.py import urllib2 import json from basic import Basic class Media(object): def get(self, accessToken, mediaId): postUrl = "https://api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s" % ( accessToken, mediaId) urlResp = urllib2.urlopen(postUrl) headers = urlResp.info().__dict__['headers'] if ('Content-Type: application/json\r\n' in headers) or ('Content-Type: text/plain\r\n' in headers): jsonDict = json.loads(urlResp.read()) print jsonDict else: buffer = urlResp.read() # 素材的二进制 mediaFile = file("test_media.jpg", "wb") mediaFile.write(buffer) print "get successful" if __name__ == '__main__': myMedia = Media() accessToken = Basic().get_access_token() mediaId = "2ZsPnDj9XIQlGfws31MUfR5Iuz-rcn7F6LkX3NRCsw7nDpg2268e-dbGB67WWM-N" myMedia.get(accessToken, mediaId)

直接运行 media.py 即可把想要的素材下载下来,其中图文消息类型的,会直接在屏幕输出json数据段。

6 永久素材

6.1 新建永久素材的方式

6.1.1 手工体验

公众号官网的素材管理新增素材。补充一点,公众平台只以MediaID区分素材,MediaID不等于素材的文件名。

MediaID只能通过接口查询,公众平台官网看到的是素材的文件名,如下图:

6.1.2 新增永久素材

新增永久素材接口(详情见wiki),跟新增临时素材的操作差不多,使用url不一样而已,这里避免重复,以新增永久图文素材接口为例,新增其他类型的素材请参考新增临时素材代码。

vim material.py

  [py]
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
# -*- coding: utf-8 -*- # filename: material.py import urllib2 import json from basic import Basic class Material(object): # 上传图文 def add_news(self, accessToken, news): postUrl = "https://api.weixin.qq.com/cgi-bin/material/add_news?access_token=%s" % accessToken urlResp = urllib2.urlopen(postUrl, news) print urlResp.read() if __name__ == '__main__': myMaterial = Material() accessToken = Basic().get_access_token() news = ( { "articles": [ { "title": "test", "thumb_media_id": "X2UMe5WdDJSS2AS6BQkhTw9raS0pBdpv8wMZ9NnEzns", "author": "vickey", "digest": "", "show_cover_pic": 1, "content": "<p><img src=\"\" alt=\"\" data-width=\"null\" data-ratio=\"NaN\"><br /><img src=\"\" alt=\"\" data-width=\"null\" data-ratio=\"NaN\"><br /></p>", "content_source_url": "", } ] }) # news 是个dict类型,可通过下面方式修改内容 #news['articles'][0]['title'] = u"测试".encode('utf-8') # print news['articles'][0]['title'] news = json.dumps(news, ensure_ascii=False) myMaterial.add_news(accessToken, news)

6.2 获取永久素材MediaID

1) 通过新增永久素材接口(详情见wiki)新增素材时,保存MediaID

2) 通过获取永久素材列表(下文介绍) 的方式获取素材信息,从而得到MediaID

6.3 获取素材列表

官方wiki链接:获取素材列表特别说明:此接口只是批量拉取素材信息,不是一次性拉去所有素材的信息,所以可以理解offset字段的含义了吧。

vim material.py

  [py]
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
# -*- coding: utf-8 -*- # filename: material.py import urllib2 import json import poster.encode from poster.streaminghttp import register_openers from basic import Basic class Material(object): def __init__(self): register_openers() #上传 def upload(self, accessToken, filePath, mediaType): openFile = open(filePath, "rb") fileName = "hello" param = {'media': openFile, 'filename': fileName} #param = {'media': openFile} postData, postHeaders = poster.encode.multipart_encode(param) postUrl = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=%s&type=%s" % (accessToken, mediaType) request = urllib2.Request(postUrl, postData, postHeaders) urlResp = urllib2.urlopen(request) print urlResp.read() #下载 def get(self, accessToken, mediaId): postUrl = "https://api.weixin.qq.com/cgi-bin/material/get_material?access_token=%s" % accessToken postData = "{ \"media_id\": \"%s\" }" % mediaId urlResp = urllib2.urlopen(postUrl, postData) headers = urlResp.info().__dict__['headers'] if ('Content-Type: application/json\r\n' in headers) or ('Content-Type: text/plain\r\n' in headers): jsonDict = json.loads(urlResp.read()) print jsonDict else: buffer = urlResp.read() # 素材的二进制 mediaFile = file("test_media.jpg", "wb") mediaFile.write(buffer) print "get successful" #删除 def delete(self, accessToken, mediaId): postUrl = "https://api.weixin.qq.com/cgi-bin/material/del_material?access_token=%s" % accessToken postData = "{ \"media_id\": \"%s\" }" % mediaId urlResp = urllib2.urlopen(postUrl, postData) print urlResp.read() #获取素材列表 def batch_get(self, accessToken, mediaType, offset=0, count=20): postUrl = ("https://api.weixin.qq.com/cgi-bin/material" "/batchget_material?access_token=%s" % accessToken) postData = ("{ \"type\": \"%s\", \"offset\": %d, \"count\": %d }" % (mediaType, offset, count)) urlResp = urllib2.urlopen(postUrl, postData) print urlResp.read() if __name__ == '__main__': myMaterial = Material() accessToken = Basic().get_access_token() mediaType = "news" myMaterial.batch_get(accessToken, mediaType)

6.4 删除永久素材

如果我想删除掉 20160102.jpg 这张图片,除了官网直接操作,也可以使用接口: 删除永久素材 接口文档。

首先需要知道该图片的mediaID,方法上小节已讲述。代码可参考上小节:Material().delete() 接口 调用接口成功后,在公众平台官网素材管理的图片中,查询不到已删除的图片。

参考资料

https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Getting_Started_Guide.html