Monthly Archives: 一月 2014

Hello World 微信开发

玩转微信公号开发(六)——设置菜单

这里要讲的是,在开发模式下,如何自定义菜单

因为可能有中文乱码的问题,所以这里直接拼json串,然后调接口,post就ok了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public function weixin_custom_menu(){
	$token 		= WXUtil::getAccessToken();
	$url 			= "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=".$token;
	$msg 		= '{"button":['
		//单菜单
		.'{"type":"click","name":"现在购买","key":"BTN_1"},'
		.'{"type":"click","name":"优惠活动","key":"BTN_2"},'
		.'{"name":"帮助",//多级菜单
			"sub_button":[
					{"type":"view","name":"下载","url":"http://xx.com/download.html"},
					{"type":"view","name":"使用教程","url":"http://xx.com/howbuy.html"},  
					{"type":"view","name":"关于我们","url":"http://xx.com/about.html"}
				]
			}
		]}';
	echo $msg;
	$r 		= Http::httpsPost($url, $msg);
	print_r($r);//打印结果,返回error为0的话,即为设置成功
	exit;
}

参数说明

  • type,按钮的类型
    1. click,按钮,点击后,发送给开发者网关一个事件
      view,链接,打开一个webview页面,页面地址为url字段指定
  • name,按钮的显示名称
  • key,事件标示,对应本系列第二篇里提到的EventKey字段
  • url

菜单设置后,通常需要退出公众号再进一次才能生效,如果还不行,只能取消关注、再关注一次

————
转载请注明住处:http://www.jiangkl.com/2014/01/weixin_custom_menu

Hello World 微信开发

玩转微信公号开发(五)——发送主动消息

解决了access_token的问题,让我们来看看怎么主动给用户发消息

主动消息有两类,客服消息和模板消息,微信对滥发消息很敏感,所以对这两个功能限制很多,并且,这两个功能也都术语高级接口

客服消息

顾名思义,客服消息是给客服用的,具体限制是:用户给公众号发送过消息后(发送消息、菜单点击、支付成功、用户维权、扫描带参数二维码、订阅),48小时内,开发者可以调用客服消息接口,给该用户发送消息,消息的类型可以是文本、图片、语音、视频、音乐、图文,数据的格式是json~~注意,除了前面讲到的同步回复消息疑问,以后和微信的交互的数据格式都是json

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
	//$data可以是字符串,也可能是数组,随具体的$type而改变
	public function sendCustom($openId, $data, $type = 'text'){
		$msg 		= array(
			'touser'		=> $openId,
		);
		switch($type){
			case 'text':
				$msg['msgtype'] = 'text';
				$msg['text'] 	= array('content' => urlencode($data));
				break;
			case 'image':
				$msg['msgtype'] = 'image';
				$msg['image'] 	= array('media_id' => $data);
				break;
			case 'voice':
				$msg['msgtype'] = 'voice';
				$msg['voice'] 	= array('media_id' => $data);
				break;
			case 'video':
				$msg['msgtype'] = 'video';
				$msg['video'] 	= $data;
				break;
			case 'music':
				$msg['msgtype'] = 'music';
				$msg['music'] 	= $data; 
				break;
			case 'news':
				$msg['msgtype'] = 'news';
				foreach($data as $k => $v){
					if(isset($v['title'])) $v['title'] = urlencode($v['title']);
					if(isset($v['description'])) $v['description'] = urlencode($v['description']);
					$data[$k] 	= $v;
				}
				$msg['news'] 	= array('articles' => $data);
				break;
		}
		$url 		= 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token='.self::getAccessToken();
		$postData 	= urldecode(json_encode($msg));
		$r 		= Http::httpsPost($url, $postData, true, false);
		return $r;
	}

getAccessToken,是在取access_token
httpsPost和上次说的httpsGet类似,只多了下面的两行,$input即为post的内容:

1
2
	curl_setopt($ch, CURLOPT_POST, true);
	curl_setopt($ch, CURLOPT_POSTFIELDS, $input);

模板消息

模板消息,没有上面客服消息的限制,但是必须在微信提供的模板框架内拼出消息,如果用户想使用自己的模板,需要特别申请~~基本上很难
首先,从微信公号后台挑选可用的模板,拿到templateId,然后拼装下面结构的post参数:

1
2
3
4
5
6
7
8
$postData = array(
	"touser"	=> $openId,//接受者
	"template_id"	=> $templateId,
	//data为模板内的实际内容,字段项目视具体模板而定
	"data"		=> array("NAME"=>"里斯之泪", "PRICE"=>"¥10000.00"),
	"url"		=> "http://xxxx.xxx.com/xxxx",
	"topcolor"	=> "#333",//顶栏颜色
);

然后整理数据、调用接口就ok了

1
2
$postData 	= json_encode($postData);
$r 		= Http::httpsPost($url, $postData);

————
转载请注明出处: http://www.jiangkl.com/2014/01/custom-send_template/

幻界杂谈 日志

冰火志

《冰与火之歌》,史诗级的魔幻巨著,已出版的五部、15本,总共应该有五千余页~~~~~历时九个月,终于读完了

上班不读,在家不读,只在上下班的地铁里,每天不到一小时~~已经用这种方式读完了基地系列和冰与火系列,下一步要读哪个,还没目标,或许会把阿瑟克拉克的再读一遍,或者远望系列、沙丘系列

还是回来说冰与火吧,整部书的发生在一个虚构的世界里,社会形态类似中世纪的欧洲,大部分是“人间”的故事,魔法的成分很少

 

骑士、领主、封臣、奴隶、国王、学士

城堡、王国、草原、荒漠、大海、自由贸易城邦

铁卫、海盗、马帮、佣兵、野人、守夜人

心树、光之王、魔龙、冰原狼、异鬼、尸鬼、魔法

长矛、匕首、长剑、弯刀、战锤、野火、龙晶、瓦雷利亚钢

爱与恨、情与怨,忠诚与背叛、聪明与愚蠢、坚强与懦弱、仁爱与残忍、诺言与谎言、欲望、无耻

诸多关键字,勾勒出了一个庞杂的故事背景,让各色人等争相表现自己的爱恨情仇与喜怒哀乐

 

史塔克、坦格利安、拜拉席恩、兰尼斯特、提利尔、佛雷、波顿、马泰尔、徒利、葛雷乔伊……

一个家族就是一支力量、一段历史,若干家族,一起演义维斯特洛几千年的历史

 

丹妮莉丝、琼恩、提利昂、艾丽娅、凯瑟琳、布蕾妮、詹姆、瑟曦……

马丁老爷子借助他们的眼睛和视角,将故事为我们娓娓道来

 

同样作为国王,罗柏与丹妮对婚姻的选择,向我们展示什么叫不成熟

同样作为女王,瑟曦与丹妮对属下的态度,向我们展示什么叫大愚若智

所以,故事的解决似乎很明显,丹妮会一统天下,然而,马丁老爷子有不是按套路出牌的人,故事的解决究竟会怎样,或许只有他老人家自己知道

“欲知后事,且听下回”,第五部的结尾,为我们留下了一个无比开放的场面:

北方

正准备南下对付波顿的琼恩被捅了一刀,已经进入长城的野人和黑衣人之间脆弱的和平会被打破吗?

拉姆斯给琼恩的信里说,斯坦尼斯死了,是真的吗?

冯凯兰尼斯特死了,君临的烂摊子如何收拾,提利尔会彻底把兰尼斯特干掉吗?

奴隶湾

维克塔利昂率领的铁舰队对奴隶湾的战局会有什么影响?

贾科卡奥会帮助丹妮莉丝吗?

无畏的巴利斯坦能掌控弥林的局面吗?能打破渊凯的围困吗?

最后,最大的疑问,龙之号角能顺利到达丹妮莉丝手里吗?

 

Hello World 微信开发

玩转微信公号开发(四)——获取access_token与上传多媒体文件

access_token

access_token是开发者访问其他微信接口的凭证,一个微信公众号,在同一时刻,只能有一个access_token,有效时间两小时

具体的获取方法如下

1
2
3
4
5
  $url   = "https://api.weixin.qq.com/cgi-bin/token?"
      ."grant_type=client_credential&appid=".$appId."&secret=".$appSecret;
  $r     = Http::httpsGet($url);
  $r     = json_decode($r, true);
  $token = isset($r['access_token']) ? urldecode($r['access_token']) : false;

其中,httpsGet:

1
2
3
4
5
6
7
8
9
10
11
12
  function httpsGet($url){
    $ch = curl_init(); 
    $header[] = "Content-type: text/plain";
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    $response = curl_exec($ch);
    curl_close($ch);
    $result = trim(urldecode($response));
    return $result;
  }

鉴于access_token的“广泛应用”和诸多限制,我们的做法是为它做了一个redis缓存,每小时刷新一次,所有用到access_token项目都从这个缓存里取

上传多媒体文件

~~其实,俺们的项目里,还没用到过这个功能,但既然做教程,就尽量做的完整些,下面内容只是微信官方文档的整理摘录

上传地址:http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE

type: image/voice/video/thumb(缩略图)

POST字段名:media

(看这格式,还是写个html页面比较合适)

限制:
图片(image): 128K,支持JPG格式
语音(voice):256K,播放长度不超过60s,支持AMR\MP3格式
视频(video):1MB,支持MP4格式
缩略图(thumb):64KB,支持JPG格式

下载多媒体文件

http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID

~~没啥可说的,一目了然

————
转载请注明出处:http://www.jiangkl.com/2014/01/access-token_media/

Hello World 微信开发

玩转微信公号开发(三)——消息的回复

这里说的消息回复,是指对用户发给公众号消息的同步回复,用户给公众号发了消息,开发者可以不回复,或者给该用户回复一条~~只一条

回复消息的格式如下:

1
2
3
4
5
6
7
  <xml>
    <ToUserName><![CDATA[orrnVjsadf-FbumIsdafZiBUFTw]]></ToUserName>
    <FromUserName><![CDATA[gh_fsadf942sdf9]]></FromUserName>
    <CreateTime>1390889296</CreateTime>
    <MsgType><![CDATA[text]]></MsgType>
    <Content><![CDATA[你好]]></Content>
  </xml>

虽然消息里第一项就是ToUserName,但是~~这里只能回复给当前发送消息的用户,写别的用户是无效的

    MsgType包括下面几个类型:

  • text,文本
  • image,图片
  • voice,语音
  • video,视频
  • music,音乐
  • news,图文

文本

即开篇的那个例子,Content是文本内容~~~告诉大家一个官方文档没有的小秘密:使用a标签,可以给消息添加链接

图片

1
2
3
4
5
6
7
8
9
  <xml>
    <ToUserName><![CDATA[orrnVjsadf-FbumIsdafZiBUFTw]]></ToUserName>
    <FromUserName><![CDATA[gh_fsadf942sdf9]]></FromUserName>
    <CreateTime>1390889296</CreateTime>
    <MsgType><![CDATA[image]]></MsgType>
   <Image>
     <MediaId><![CDATA[media_id]]></MediaId>
   </Image>
  </xml>

图片,以及下面的视频、音频里的media_id,首先要通过微信的上传多媒体文件接口获得,详细的情况,以后会讲到

语音

1
2
3
4
5
6
7
8
9
  <xml>
    <ToUserName><![CDATA[orrnVjsadf-FbumIsdafZiBUFTw]]></ToUserName>
    <FromUserName><![CDATA[gh_fsadf942sdf9]]></FromUserName>
    <CreateTime>1390889296</CreateTime>
    <MsgType><![CDATA[voice]]></MsgType>
    <Voice>
      <MediaId><![CDATA[media_id]]></MediaId>
    </Voice>
  </xml>

~没啥可说的,和图片类似

视频

1
2
3
4
5
6
7
8
9
10
11
  <xml>
    <ToUserName><![CDATA[orrnVjsadf-FbumIsdafZiBUFTw]]></ToUserName>
    <FromUserName><![CDATA[gh_fsadf942sdf9]]></FromUserName>
    <CreateTime>1390889296</CreateTime>
    <MsgType><![CDATA[video]]></MsgType>
    <Video>
      <MediaId><![CDATA[media_id]]></MediaId>
      <Title><![CDATA[视频标题]]></Title>
      <Description><![CDATA[视频介绍]]></Description>
    </Video> 
  </xml>

音乐

1
2
3
4
5
6
7
8
9
10
11
12
13
  <xml>
    <ToUserName><![CDATA[orrnVjsadf-FbumIsdafZiBUFTw]]></ToUserName>
    <FromUserName><![CDATA[gh_fsadf942sdf9]]></FromUserName>
    <CreateTime>1390889296</CreateTime>
    <MsgType><![CDATA[video]]></MsgType>
    <Music>
      <Title><![CDATA[音乐标题]]></Title>
      <Description><![CDATA[音乐介绍]]></Description>
      <MusicUrl><![CDATA[音乐链接]]></MusicUrl>
      <HQMusicUrl><![CDATA[WIFI环境优先使用的高质量音乐链接]]></HQMusicUrl>
      <ThumbMediaId><![CDATA[media_id~缩略图的媒体id]]></ThumbMediaId>
    </Music> 
  </xml>

图文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<xml>
  <ToUserName><![CDATA[orrnVjsadf-FbumIsdafZiBUFTw]]></ToUserName>
  <FromUserName><![CDATA[gh_fsadf942sdf9]]></FromUserName>
  <CreateTime>1390889296</CreateTime>
  <MsgType><![CDATA[news]]></MsgType>
  <ArticleCount>5</ArticleCount>
  <Articles>
    <item>
      <Title><![CDATA[标题1]]></Title>
      <PicUrl><![CDATA[http://y1.ifengimg.com/2014/01/28/14023732.jpg]]></PicUrl>
      <Url><![CDATA[http://xxxx.xxx.com/index]]></Url>
    </item>
    <item>
      <Title><![CDATA[标题2]]></Title>
      <PicUrl><![CDATA[http://xxxx.xxx.com/xxx.png]]></PicUrl>
      <Url><![CDATA[http://xxxx.xxx.com/index]]></Url>
    </item>
    ......  
  </Articles>
</xml>

ArticleCount,是item子项的数量

图文的第一条,会以大图显示,推荐尺寸720*400,不同的尺寸在不同的手机上显示效果差别很大,可能左右也可能上下被遮住

除第一条外,其他的图文里的图,都只显示小icon,所以我们用的时候,统一用了一个向右的箭头

最后,来说一个不常用,但对于新手很重要的东西:网关的验证消息怎么回复

太简单了~~直接输出get参数里的echostr

————
转载请注明出处:http://www.jiangkl.com/2014/01/weixin_msg_2/