nap文档 # 量子云科技nap平台文档 [TOC] *************************** ## 简介 nap平台是用于快速帮助实习程序员编写基于微信公众号的网页应用程序的平台。该平台有以下几个特点: 1. 通过[平台首页][3]配置项目以及项目关联的公众号,使得一个项目可以配置到多个公众号以及一个公众号可以配置多个项目。 2. 程序员用Sublime编写php和python等程序,使用平台的Sublime插件上传代码到服务器以及从服务器下载代码,程序员可以方便的随时随地下载代码继续编程。 3. 平台提供微信公众号实用功能接口,让程序员无需关心微信端的各种签名以及服务器数据库等,只需专注于项目功能的实现。 4. 利用php注释实现简易接口调用,程序员按照指定格式在注释中写接口命令,在上传代码时服务器会将注释的命令翻译为调用接口的php代码,实现接口的调用或者实现一些通用功能。 5. [网页在线调试python程序](http://nap1.kagirl.cn/nap/pydebug/) ------------ ## Sublime插件 在使用nap平台的Sublime编写php程序的时候,nap平台提供直接上传到服务器的插件。该插件的功能是管理程序员在[首页][3]注册的app代码,程序员在注册app时会提供appid以及该项目的密码,在注册了app之后,该app的代码将会被上传到http://stu.kagirl.cn/nap/doc/appid/ 目录下,服务器上该目录下的文件结构和程序员本地的文件结构相同,**需要注意的是程序员必须在本地建立一个同app的id相同名称的目录才能同步代码到服务器**,例如我建立了一个appid为facedemo的项目,因此我需要在本地建立一个facedemo文件夹,然后在facedemo下的文件才能被上传到http://stu.kagirl.cn/nap/doc/facedemo/ 目录下。在上传下载代码时需要输入appid以及appid对应的密码。 该插件右键有"上传到服务器"、“下载代码”、“上传所有代码”三个菜单选项。分别有以下功能: 1. 上传到服务器-->将当前正在编辑的文档上传到服务器 2. 下载代码-->将服务器中的所有项目代码下载到本地 3. 上传所有代码-->将当前正在编辑文档所属项目的所有代码一次性上传到服务器 ### 下载安装插件 1. [Sublime Text2下载地址](http://blog.liangziyun.net/typecho/usr/uploads/2017/10/267173492.zip) 2. [Sublime Text3下载地址](http://blog.liangziyun.net/typecho/usr/uploads/2017/11/1433325411.zip) #### [sublime 2/3通用下载地址](http://blog.liangziyun.net/typecho/usr/uploads/2017/11/542382927.zip) ### 上传到服务器 步骤: 1. 在[首页][3]新建一个app,假设appid为testapp,密码为testpwd 2. 在本地新建一个名称为testapp的文件夹 3. 在testapp文件夹下创建文档编写代码,假设在testapp文件夹下新建了test.php文件 4. 点击鼠标右键-->上传到服务器 5. 输入账号密码分别为testapp和testpwd 6. 上传成功,在浏览器端输入http://stu.kagirl.cn/nap/doc/testapp/test.php即可以调试test.php文件 ### 下载代码 假设需要在本地下载上面testapp的代码 步骤: 1. 新建一个名称为testapp的文件夹,并且在文件夹下新建一个temp.txt的文件 2. 打开temp.txt文件 3. 右键-->下载代码 4. 输入账号密码分别为testapp和testpwd 5. 下载完成,删除temp.txt文件。temp.txt文件的作用是获取testapp的路径,使得下载的代码能够找到存储的地方 ### 上传所有代码 假设我在testapp文件夹下编写了很多程序,此时希望将更新的这些程序同步到服务器 步骤: 1. 打开testapp文件夹下的任一文件 2. 右键-->上传所有代码 3. 输入账号密码分别为testapp和testpwd 4. 上传完成 ### 代码的路径 非python代码会被存放到服务器的/www/nap/doc/appid/目录下 sdk.php在/www/nap/doc/目录下 python代码会被存放到服务器的/nap/doc/appid/目录下 sdk.py在/nap/doc/目录下,要引入sdk.py需加入以下代码 ``` python #!/usr/bin/env python # -*- coding: utf-8 -*- import sys sys.path.append("/nap/doc") from sdk import * ``` 若appid为test的项目下有test.py和tools.py,test.py想引入tools.py建议用下列方式引入. ``` python #!/usr/bin/env python # -*- coding: utf-8 -*- import sys sys.path.append("/nap/doc") sys.path.append("/nap/doc/test/") from sdk import * from tools import * ``` ### 关于php中的注释型命令 为方便程序员快速编写程序,nap平台在程序员上传php代码到服务器中时会检测`/*** ***/`中间的内容,将能够识别的命令翻译成指定的功能 例如在php中编写 ``` php /*** debug ***/ ``` 会被翻译成,用来调试php程序中的错误。 ``` php error_reporting(E_ALL); ini_set("display_errors", "1"); ``` 注释命令对**缩进**有严格要求,在翻译命令时,每当遇到一个命令时,后面缩进大于该命令的行都将作为该命令的参数直到遇到下一个缩进小于该命令的行。例如 ``` php /*** config ->>遇到config命令 wxid testmp ->>缩进小于config命令,那么该行都是config命令的参数 appid facedemo ->>缩进小于config命令,那么该行都是config命令的参数 redis ->>缩进不小于config命令,那么该行是新的redis命令 hget books test ->>缩进小于redis命令,那么该行都是redis命令的参数 ***/ ``` 注释命令中可以携带**php变量**例如 ``` php /*** hget books $bookid ***/ ``` 注释命令有**返回结果**,注释命令有两种形式,一种是单命令,一种是批量命令,单命令时返回该命令的执行结果,如果没有结果则返回null,批量命令返回数组,数组中每个元素对应每个命令的返回结果,例如 ``` php $ret = /*** redis hget books $bookid hset test_key test_field test facepp $imgurl ***/ ``` 返回的$ret为一个数组,数组第一个元素是redis命令的返回结果,第二个元素是facepp命令的返回结果。 不能识别的命令仍然为注释。 ## 接口文档 在php和python的sdk中都有编写用于调用接口的call_api函数, ### 公用函数 #### php公用函数 ##### call_api-->调用nap平台接口的函数 语法 ``` php call_api($api, $params) ``` |参数|说明| |:--|:--| |$api|string 类型,必需,请求的接口名字| |$params|array 类型,非必需,请求的json参数| |返回值|说明| |:--|:--| |array|请求接口返回的json数据| #####openlogin-->网页版扫码登陆 openlogin() 网页端扫描登陆函数,该函数为非微信客户端网页扫描二维码登陆使用。 返回array,格式如下: { "openid":" OPENID", " nickname": NICKNAME, "sex":"1", "province":"PROVINCE" "city":"CITY", "country":"COUNTRY", "headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46", "privilege":[ "PRIVILEGE1" "PRIVILEGE2" ], "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" } |返回值|说明| |:--|:--| |array|用户登陆获取到的详细信息,格式如上| php调用实例: ``` php /*** config wxid testmp appid facedemo ***/ $ret = openlogin(); echo json_encode($ret); $openid = $ret["openid"]; $headimgurl = $ret["headimgurl"]; ``` ##### infologin-->微信端显示登陆 ingologin()函数用于微信端显示登陆,可获取用户详细信息,返回openlogin相同格式的json数据。 |返回值|说明| |:--|:--| |array|用户登陆获取到的详细信息| ``` php /*** config wxid testmp appid facedemo ***/ $ret = infologin(); echo json_encode($ret); $openid = $ret["openid"]; $headimgurl = $ret["headimgurl"]; ``` ##### baselogin-->微信端隐式登陆 baselogin()函数用于微信端隐式登陆,只能获取用户的openid,**注:同一个用户通过openlogin获取的openid与通过infologin和baselogin获取的openid是不一定相同的。** |返回值|说明| |:--|:--| |string|用户登陆获取到的openid| php实例 ``` php /*** config wxid testmp appid facedemo ***/ $openid = baselogin(); echo $openid; ``` ##### get_viewport->[设置网页viewport](http://www.cnblogs.com/2050/p/3877280.html) 手机端网页需要设置viewport,让网页固定宽高,该函数接收一个设置网页宽度的参数,默认宽为500。 语法 get_viewport( $width=500) |参数|说明| |:--|:--| |$width|int 类型,非必需,需要设置的viewport的宽,默认为500 |返回值|说明| |:--|:--| |string|设置viewport的javascript代码,直接echo即可| php示例: ``` php /*** config wxid testmp appid facedemo ***/ echo get_viewport(); //默认设置网页宽高为500*750 //或者 echo get_viewport(640); //设置网页宽高为640*960 ``` #####encode_id-->加密字符串 语法 encode_id($id) |参数|说明| |:--|:--| |$id|string 类型,必需,需要加密的字符串或数字| |返回值|说明| |:--|:--| |string|加密后的字符串| 实例 ``` php /*** config wxid testmp appid facedemo ***/ //生成一个新的id $id = /*** incr bookid ***/ $code = encode_id($id); echo $code; ``` #####decode_id-->解密字符串 语法 decode_id($code) |参数|说明| |:--|:--| |$code|string 类型,必需,需要解密的字符串| |返回值|说明| |:--|:--| |string|解密后的字符串| 实例 ``` php /*** config wxid testmp appid facedemo ***/ $code = $_GET["code"]; $id = decode_id($code); echo $id; ``` #####format_face-->格式化[face++][1]获取的数据 由于获取的face++数据的字段名字太长以及字段对应的值精度较高,因此写了该函数,主要将face++返回的数据去除掉小数点以及更改字段名字,使得保存到数据库之后占用尽量少的存储空间。 语法 format_face($data) |参数|说明| |:--|:--| |$data| array 类型,必需,需要格式化的[face++][1]返回的数据| |返回值|说明| |:--|:--| |array|格式化后的[face++][1]数据,仅去除了小数点以及更改了字段名| 实例 ``` php /*** config wxid testmp appid facedemo ***/ $imgurl = "http://www.faceplusplus.com.cn/wp-content/themes/faceplusplus/assets/img/demo/2.jpg"; $data = /*** facepp $imgurl ***/ echo "origin data "; echo json_encode($data); echo "format data "; $f_data = format_face($data); echo json_encode($f_data); ``` #####unformat_face-->将格式化的人脸数据返回正常的[face++][1]的数据格式 语法 unformat_face($data) |参数|说明| |:--|:--| |$data|array 类型,必需,需要返回[face++][1]人脸格式的数据| |返回值|说明| |:--|:--| |array|正常[face++][1]人脸格式的数据| 实例 ``` php /*** config wxid testmp appid facedemo ***/ $imgurl = "http://www.faceplusplus.com.cn/wp-content/themes/faceplusplus/assets/img/demo/2.jpg"; $data = /*** facepp $imgurl ***/ echo "origin data "; echo json_encode($data); echo "format data "; $f_data = format_face($data); echo json_encode($f_data); ``` ####python公用函数 #####call_api-->python调用nap平台接口 语法 call_api(api, params) |参数|说明| |:--|:--| |api|string 类型,必需,请求的接口名字| |params|json 类型,非必需,请求的json参数| |返回值|说明| |:--|:--| |json|请求接口返回的json数据| #####get_param-->获取该程序接收的参数 在php中调用python接口时需要post一个json数据给"python.php"接口,该接口会将post过来的json数据原封不动的传递给要执行的python程序,而在Python程序中调用此函数获取传递过来的参数。 语法 get_param() |返回值|说明| |:--|:--| |json|php 传递过来的json数据| ###数据库接口 ####说明 nap平台采用[redis][2]作为数据库, 语法 ``` php call_api("redis.php?appid=appid&wxid=wxid", params) ``` |参数|说明| |:---|:---| |appid|项目的id| |wxid|当前页面的wxid,该接口会利用appid和wxid去寻找该项目当前所在的数据库| |params|json数据,格式如下| 单个命令操作 { "fun" : "hget", "key" : "books", "field":"" } 批量命令操作 [ { "fun":"get", "key":"test_key" }, { "fun":"del", "key":"test_key" } ... ] 该函数返回redis操作的结果如下格式 { "errcode":0, "data":"当params是批量操作时此处为数组,单命令时字符串或者false" } 目前支持的redis函数及格式如下 > **注:**fun列表示接口支持的redis函数,key、field、value列表示该redis函数需要的字段。例如expire函数的key字段和value字段都是yes,因此请求接口时json数据为```{"fun":"expire,"key":"test",value:30}``` |index|fun|key|field|value| |:--|:--|:--|:--|:--| |1|del|yes||| |2|exists|yes||| |3|expire|yes||yes| |4|keys|||yes| |5|type|yes||| |6|get|yes||| |7|incr|yes||| |8|incrby|yes||yes |9|set|yes||yes| |10|hdel|yes|yes|| |11|hexists|yes|yes|| |12|hget|yes|yes|| |13|hgetall|yes||| |14|hincrby|yes|yes|yes| |15|hkeys|yes||| |16|hlen|yes||| |17|hset|yes|yes|yes| |18|llen|yes||| |19|lpop|yes||| |20|lpush|yes||yes| |21|rpop|yes||| |22|rpush|yes||yes| 特殊函数 { "fun":"hscan", "key":"test_key", "cursor":null, "pattern":"test_*" } { "fun":"lindex", "key":"test_list", "index":0 } #### php实例 php可以采用两种方式调用接口,一种是自己构造请求json数据,通过call_api函数调用接口,另一种是用注释命令调用接口。 1.注释型调用 ``` php /*** config wxid testmp appid facedemo ***/ $ret = /*** hset test_key test_field test ***/ echo json_encode($ret); echo ""; $ret = /*** redis hget test_key test_field hdel test_key test_field ***/ echo json_encode($ret); ``` >注释型写法只支持php语言。 2.call_api调用 ``` php /*** config wxid testmp appid facedemo ***/ $params = array("fun"=>"hset", "key"=>"test_key", "field"=>"test_field", "value"=>"test"); $ret = call_api("redis.php?appid=facedemo&wxid=testmp", $params); echo json_encode($ret); echo ""; $params = array( array("fun"=>"hget", "key"=>"test_key", "field"=>"test_field"), array("fun"=>"hdel", "key"=>"test_key", "field"=>"test_field") ); $ret = call_api("redis.php?appid=facedemo&wxid=testmp", $params); echo json_encode($ret); ``` >两种方式实现的内容是一样的,但是第一种形式的写法在Sublime将代码上传到服务器的时候会将注释的命令翻译成第二种写法。提供第一种写法的原因是方便代码的编写。 #### python实例 ``` python #!/usr/bin/env python # -*- coding: utf-8 -*- import sys sys.path.append("/nap/doc") #sdk的路径 from sdk import * params = { "fun":"hset", "key":"test_key", "field":"test_field", "value":"test" } ret = call_api("redis.php?appid=facedemo&wxid=testmp", params) print ret params = [ { "fun":"hget", "key":"test_key", "field":"test_field" }, { "fun":"hdel", "key":"test_key", "field":"test_field" } ] ret = call_api("redis.php?appid=facedemo&wxid=testmp", params) print ret ``` 可在[python调试工具][4]执行该代码 ###其他接口汇总 ####公众号回复 >接口名 reply.php >post请求 > >{ "wxid":"公众号微信id", "openid":"回复到指定客户端的openid", "type":"text", "text":"回复内容" } 或者 { "wxid":"公众号微信id", "openid":"回复到指定客户端的openid", "type":"news", "articles": [ { "title":"Happy Day", "description":"Is Really A Happy Day", "url":"URL", "picurl":"PIC_URL" }, { "title":"Happy Day", "description":"Is Really A Happy Day", "url":"URL", "picurl":"PIC_URL" } ] } 返回 { "errcode":0, "data":[微信接口][5]返回的结果 } ####引入[微信js](http://mp.weixin.qq.com/wiki/11/74ad127cc054f6b80759c40f77ec03db.html)以及签名 >接口名 wxconfig.php >post请求 > >{ "apilist":["onMenuShareTimeline", "onMenuShareAppMessage"], "debug":false, #默认为false,该属性可不填写 "url":"当前url连接" //"http://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"] } 返回 { "errcode":0, "script":"...." 返回微信配置的javascript代码 } ####人脸识别 >接口名 facepp.php >post请求,详细请查看[face++文档][1],此处会将请求的参数传递给face++ > >{ "methd":"/detection/detect", "url":imgurl, "mode" >} >返回,参看[face++文档][1]返回示例 ####调用python python程序通过sdk中的get_param()函数获取此处请求的post数据。 >接口名 python.php?appid=appid >post请求 > >{ "wxid":"test", #如果python程序需要访问数据库则该字段必须 "path":"test.py", #python 程序路径 相对于app目录的路径 "...":"" #支持自定义字段, 该json数据会直接传给python程序供其使用 } 返回 { "errcode":0 } ####卡娃音乐库 >接口名 music.php >post请求 > >{ "action":"get", "name":"music name" } 返回 { "errcode":0, "url":"music url" } 或者post请求 { "action":"list", #请求音乐列表 "type":"pop", #请求类型 pop "start":0, #音乐列表下标 "count":20 #请求数 } 返回 [ { "musicname":"wodekuailejiushixiangni_x", "title":"我的快乐就是想你", "url":"http://7xjeju.com2.z0.glb.qiniucdn.com/music/wodekuailejiushixiangni.mp3" }, ... ] ####网页选择图片上传 >接口名fetch.php >post请求 > >{ "mediaid":网页端wx.uploadImage的serverId, "key":"存储在七牛端的key" >} >返回 >{ "url":"http://7xjeju.com2.z0.glb.qiniucdn.com/key", "key":"key" >} > #### 登录接口login >接口名 login.php >post请求 > >{ "type": openlogin/baselogin/baseinfo/infologin, "from":null/youpin } >返回 >{ "info":{} //用户数据 >} > #### 获取用户信息 >接口名 wxuserinfo.php >post请求 > >{ "wxid": "", "openid: "" >} 返回 >{ "nickname":"" >} ##命令文档 php中支持注释型命令写法,命令的参数形式分为**键值对参数**和**数组参数**,下面将列出目前支持的所有命令 **键值对参数**:参数在命令下面一行,缩进小于命令的缩进,如 ``` php /*** config wxid testmp appid facedemo ***/ ``` **数组参数**:参数与命令在同一行,如 ``` php /*** hget books $bookid ***/ ``` ###config config命令是用于加载sdk.php以及配置一些其他命令所需参数的命令。因此需要在php文档开发编写该命令,这样其他命令才能顺利完成各自的功能。 >键值对参数 >|key|说明|必须| >|:--|:--||:--| >|wxid|当前页面所属的wxid|否(当与数据库相关时必须)| >|appid|当前页面所属的appid|是| >|noecho|config命令是否可以输出js代码|否 >返回null ``` php /*** config wxid testmp appid facedemo ***/ ``` >该命令加载了sdk.php,并且生成config_wxid和config_appid两个变量,供其他命令调用 ###debug debug命令用于调试当前php页面,建议上线程序之后删除该命令 >无参数 >返回null ``` php /*** debug ***/ ``` ###redis 该命令用于批量执行redis命令,其参数是一系列的redis命令。返回一个数组,数组每个元素是每条redis命令执行的结果。该命令**依赖config命令的wxid和appid参数** >键值对参数 >|说明| >|:--| >|每行对应一条redis命令| >返回 > >{ "errcode":0, "data":[每条redis命令的结果] } ``` php $ret = /*** redis hget books $bookid hset test_hash test 1 keys * ***/ echo json_encode($ret); ``` ###del,get,set,hget,hset,... redis单命令操作,目前支持的redis函数以及示例。该命令**依赖config命令的wxid和appid参数** >数组参数 >|说明| >|:--| >|每条命令即redis命令| >返回 > >{ "errcode":0, "data":该命令的执行结果 } |index|fun|示例| |:--|:--|:--|:--|:--| |1|del|del test_key| |2|exists|exists test_key| |3|expire|expire test_key 30| |4|keys|keys *| |5|type|type test_key| |6|get|get test_key| |7|incr|incr test_key| |8|incrby|incrby test_key 1 |9|set|set test_key 2| |10|hdel|hdel test_hash test_field| |11|hexists|hexists test_hash test_field| |12|hget|hget test_hash test_field| |13|hgetall|hgetall test_hash| |14|hincrby|hincrby test_hash test_field| |15|hkeys|hkeys test_hash| |16|hlen|hlen test_hash| |17|hset|hset test_hash test_field test| |18|llen|llen test_list| |19|lpop|lpop test_list| |20|lpush|lpush test_list test| |21|rpop|rpop test_list| |22|rpush|rpush test_list test| |23|hscan|hscan test_hash null test_* |24|lindex|lindex test_list 0| 上面的示例可直接写为命令,例如 ```php $ret = /*** set test_key 2 ***/ ``` ###share 该命令用于快捷设置分享 >键值对参数 >|key|说明|必须| >|:--|:--||:--| >|title|分享的标题|否| >|desc|分享的描述|否| >|link|分享之后的链接|是| >|imgurl|分享的缩略图|否| >返回null 示例 ``` php /*** share title 人脸游戏 desc 测试 link $share_url imgurl $imgurl ***/ ``` ###reply 该命令用于[公众号快捷回复][5] >键值对参数 >|key|说明|必须| >|:--|:--||:--| >|wxid|公众号的微信id|是| >|openid|openid|是| >|type|text 或者 news|是| >|text|回复内容|type为text时必须| >|articles|具体文章[{"title":...},{...}]|type为news时必须| >|media_id|回复图片对应的素材库id|type为image时| >|file_path|回复图片的路径,会自动上传为临时素材并回复|type为image时| >返回 { “errcode”:0, “data”:[微信接口][5]返回的结果 } 示例 ``` php /*** reply wxid testmp openid oUPlIt86UYkoFLGSuiJjmAsBS_UA type text text $text ***/ ``` ###facepp 该命令用于调用[face++][1]接口,该命令既支持键值对参数,也支持数组参数 >键值对参数 >|key|说明|必须| >|:--|:--||:--| >|method|face++接口名称|否(默认为/detection/detect) >|url|要检测人脸的图片的url|否| >数组参数 >|index|说明|必须| >|:--|:--||:--| >|0|url,要识别的图片的链接|是 >返回,参看[face++文档][1]返回示例 示例 ``` php /*** facepp method /detection/detect url $imgurl mode oneface attr none facepp $imgurl ***/ ``` ###python 该命令用于传递参数给python程序执行,**依赖config命令的appid参数** >键值对参数 >|key|说明|必须| >|:--|:--||:--| >|wxid||如果python程序需要访问数据库则该字段必须 | >|path|python程序相对于项目目录的路径|是| >返回 >{"errcode":0} 示例 ``` php /*** python wxid $_GET["wxid"] path test.py url $imgurl openid oUPlIt86UYkoFLGSuiJjmAsBS_UA ***/ ``` ###music 用于播放音乐以及生成播放按钮 >数组参数 >|index|说明|必须| >|:--|:--||:--| >|0|音乐的播放链接或者在卡娃音乐库中得name|是 >返回null 示例 ``` php /*** music wodekuailejiushixiangni_x ***/ ``` ``` php $music_url = "http://7xjeju.com2.z0.glb.qiniucdn.com/music/wodekuailejiushixiangni.mp3"; /*** music $music_url ***/ ``` ###musiclist 用于获取卡娃音乐库的音乐列表 >键值对参数 >|key|说明|必须| >|:--|:--||:--| >|type|音乐类型,取值有"hot", pop","old", "pure"(纯音乐), "feast"(生日), "child"(儿歌)|是 >|start|从列表的第几条开始获取,默认是0|否 >|count|获取多少条音乐,默认是20|否 >返回 > >[ { "musicname":"wodekuailejiushixiangni_x", "title":"我的快乐就是想你", "url":"http://7xjeju.com2.z0.glb.qiniucdn.com/music/wodekuailejiushixiangni.mp3" }, ... ] 示例 ``` php /*** musiclist type pop start 0 count 20 ***/ ``` ### wxuserinfo 用户获取用户信息 示例 ```php /*** wxuserinfo wxid kawa openid absasdklfjasldkfjaslf ***/ ``` ##微信消息数据结构 ###文字消息 在公众号收到用户发送过来的消息之后,如果是收到的文字消息,则会从公众号当前配置的所有app中寻找一个满足关键字的app,然后将该条文字消息的json数据用post方式转发给app配置的后台php程序。文字消息的格式如下: { "service":"service.php", #app配置的后台程序 "text":"测试", #收到的具体文字 "server":"微信端公众号的id", #备用 "openid":"openid", #发送该消息人的openid "appid":"testapp", #处理该消息的appid "owner":"zengkv", #该app的创建者 "wxid":"testmp1", #公众号的wxid "type":"text" #消息类型 } ###图片消息 由于一个公众号可配置多个app,每个app可能都需要图片,因此app还会配置一个菜单,当点击菜单选择图片时,后面发送过来的图片都会发送到该app。nap平台会事先将图片上传到[七牛](http://developer.qiniu.com/code/v7/sdk/python.html),然后将图片在七牛的链接以及key返回给后台程序,图片消息的格式如下: { "service":"service.php", "server":"微信端公众号的id", #备用 "openid":"openid", #发送该消息人的openid "url":"http://7xjeju.com2.z0.glb.qiniucdn.com/test2_test1_107078", #用户上传的图片的链接 "key":"test2_test1_107078", #图片的id "appid":"testapp", #处理该消息的appid "owner":"zengkv", #该app的创建者 "wxid":"testmp1", #公众号的wxid "type":"image" #消息类型 固定为image } ###菜单按键 微信用户点击公众号菜单时的消息格式如下: { "service":"service.php", "server":"微信端公众号的id", #备用 "openid":"openid", #发送该消息人的openid "key":"create", #该按键的具体key值 "appid":"testapp2", #处理该消息的appid "owner":"zengkv", #该app的创建者 "wxid":"testmp1", #公众号的wxid "type":"pic_photo_or_album", #消息类型 类型目前有click(点击事件) 和 pic_photo_or_album(选照片事件) } ##php开发实例 ###配置 1. 前往[微信公众号测试平台](http://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index)申请一个测试公众号,并关注该公众号。 2. 前往[nap平台公众号管理](http://nap1.kagirl.cn/nap/mps.php)新增刚刚申请的测试公众号,填写公众号的appid和appsecret以及自己取一个wxid。并且在[微信公众号测试平台](http://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index)页面修改接口配置信息,将url设置为http://nap1.kagirl.cn/nap/wxservice.php?wxid=刚刚新建的wxid,token设置为naptoken 3. 前往[nap平台app管理](http://nap1.kagirl.cn/nap/app.php)新建一个app,这里我将appid设置为testapp,后台程序路径设置为service.php,接收关键字设置为["哈哈", "测试"],这样当用户发送附带"哈哈","测试"的文字到公众号时,nap平台将会把文字转发post到我们设置的后台程序service.php上,本次开发实例将在收到消息后回复hello nap,并且hello nap是一个超链接,点击该链接跳转到我们的show.php,并且在show.php中要求登陆,并显示hello 用户名 4. 前往nap平台的[app配置到公众号](http://nap1.kagirl.cn/nap/config.php) 将新建的app配置到新申请的公众号上做测试。 ###编程 新建一个testapp文件夹,并在该文件夹下编写编写service.php ``` php hello nap"; $ret = /*** reply wxid $post["wxid"] openid $post["openid"] type text text $content ***/ } ?> ``` 接下来编写show.php ``` php ``` ##python开发实例 在php开发实例中,show.php调用了python接口,为test.py程序传递了wxid,openid,nick等参数,接下来我们编写test.py,为主人回复谁访问了show.php页面。 ``` python #!/usr/bin/env python # -*- coding: utf-8 -*- import sys sys.path.append("/nap/doc") from sdk import * data = get_param() # data = { # u"wxid":u"testmp", # u"openid":u"oUPlIt86UYkoFLGSuiJjmAsBS_UA", # u"appid":u"testapp", # u"nick":u"曾奎" # } # #模拟data数据调试程序 print data openid = data["openid"] wxid = data["wxid"] appid = data["appid"] nick = data["nick"] content = "%s %s 访问了show.php" % (wxid.encode("utf-8"), nick.encode("utf-8")) #在真实环境中data的字段是Unicode类型,因此此处需要转换为utf-8避免报错 reply = { "wxid":wxid, "openid":openid, "type":"text", "text":content } ret = call_api("reply.php", reply) print ret ``` 取消掉模拟的data注释,然后注释掉data = get_param()即可直接前往nap平台[python调试工具][4]进行调试 ##错误返回码 | errcode | errmsg | 说明 | | :-------- | :--------| :---- | | 通用 | | 404 | 404 not found |api接口不存在| | 500 | |接口程序错误| | 10001 | host not in white list |请求ip不在白名单内| | 10002 | appid error |appid不存在| | 10003 | wxid error |wxid不存在| |redis.php| | 11001 | redis post data type error |请求参数错误| |reply.php| | 12001 | reply type error |参数中type字段不能解析| | 12002 | reply post data error |参数中需要wxid和openid字段| | 12003 | reply wxid error, not get token|错误的wxid| |login.php||该接口不对开发者开放| | 13001 | no login |未登录| |wxconfig.php| | 14001 | post data format error |该接口需要提供apilist以及要签名的url| |facepp.php| | 15001 | post data must have url attr |该接口需要提供人脸识别的图片url| | 15002 | request face++ faild |接口程序人脸识别失败,可尝试重新请求| |python.php| | 16001 | post data must have appid and path attr|该接口必须提供appid字段,以及python程序相对于app目录的路径| |qiniu.php| | 17001 | |不支持的请求参数| [1]:http://www.faceplusplus.com.cn/api-overview/ [2]:http://redisdoc.com/ [3]:http://nap1.kagirl.cn/nap/index.php [4]:http://nap1.kagirl.cn/nap/pydebug/ [5]:http://mp.weixin.qq.com/wiki/11/c88c270ae8935291626538f9c64bd123.html#.E5.AE.A2.E6.9C.8D.E6.8E.A5.E5.8F.A3-.E5.8F.91.E6.B6.88.E6.81.AF