微信公众号开发-配置开发环境02

1.前言
  经过前面的配置,基本完成了一些基础配置。后面接下来就是一些开发流程了。

2.配置pom.xml

  1 <?xml version="1.0" encoding="UTF-8"?>
  2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4     <modelVersion>4.0.0</modelVersion>
  5
  6     <groupId>com.wunaozai.wechat</groupId>
  7     <artifactId>WeChat</artifactId>
  8     <version>0.0.1</version>
  9     <packaging>jar</packaging>
 10
 11     <name>WeChat</name>
 12     <description>微信公众号服务器</description>
 13
 14     <parent>
 15         <groupId>org.springframework.boot</groupId>
 16         <artifactId>spring-boot-starter-parent</artifactId>
 17         <version>2.0.4.RELEASE</version>
 18         <relativePath/> <!-- lookup parent from repository -->
 19     </parent>
 20
 21     <properties>
 22         <weixin-java-mp.version>3.1.0</weixin-java-mp.version>
 23         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 24         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 25         <java.version>1.8</java.version>
 26     </properties>
 27
 28     <dependencies>
 29         <dependency>
 30             <groupId>org.springframework.boot</groupId>
 31             <artifactId>spring-boot-starter-web</artifactId>
 32         </dependency>
 33
 34         <dependency>
 35             <groupId>org.springframework.boot</groupId>
 36             <artifactId>spring-boot-starter-thymeleaf</artifactId>
 37         </dependency>
 38         <dependency>
 39             <groupId>com.github.binarywang</groupId>
 40             <artifactId>weixin-java-mp</artifactId>
 41             <version>${weixin-java-mp.version}</version>
 42         </dependency>
 43
 44         <dependency>
 45             <groupId>org.springframework.boot</groupId>
 46             <artifactId>spring-boot-starter-data-redis</artifactId>
 47         </dependency>
 48         <dependency>
 49             <groupId>org.springframework.boot</groupId>
 50             <artifactId>spring-boot-starter-data-mongodb</artifactId>
 51         </dependency>
 52         <dependency>
 53             <groupId>org.postgresql</groupId>
 54             <artifactId>postgresql</artifactId>
 55         </dependency>
 56         <dependency>
 57             <groupId>org.mybatis.spring.boot</groupId>
 58             <artifactId>mybatis-spring-boot-starter</artifactId>
 59             <version>1.3.2</version>
 60         </dependency>
 61         <dependency>
 62             <groupId>org.springframework.boot</groupId>
 63             <artifactId>spring-boot-starter-security</artifactId>
 64         </dependency>
 65         <dependency>
 66             <groupId>org.springframework.security.oauth</groupId>
 67             <artifactId>spring-security-oauth2</artifactId>
 68             <version>2.3.3.RELEASE</version>
 69         </dependency>
 70         <!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter -->
 71         <dependency>
 72             <groupId>com.github.pagehelper</groupId>
 73             <artifactId>pagehelper-spring-boot-starter</artifactId>
 74             <version>1.2.5</version>
 75         </dependency>
 76         <!-- MQTT -->
 77         <dependency>
 78             <groupId>org.springframework.boot</groupId>
 79             <artifactId>spring-boot-starter-integration</artifactId>
 80         </dependency>
 81         <dependency>
 82             <groupId>org.springframework.integration</groupId>
 83             <artifactId>spring-integration-stream</artifactId>
 84         </dependency>
 85         <dependency>
 86             <groupId>org.springframework.integration</groupId>
 87             <artifactId>spring-integration-mqtt</artifactId>
 88         </dependency>
 89
 90         <dependency>
 91             <groupId>org.springframework.boot</groupId>
 92             <artifactId>spring-boot-devtools</artifactId>
 93             <scope>runtime</scope>
 94         </dependency>
 95         <dependency>
 96             <groupId>org.springframework.boot</groupId>
 97             <artifactId>spring-boot-starter-test</artifactId>
 98             <scope>test</scope>
 99         </dependency>
100     </dependencies>
101
102     <build>
103         <plugins>
104             <plugin>
105                 <groupId>org.springframework.boot</groupId>
106                 <artifactId>spring-boot-maven-plugin</artifactId>
107             </plugin>
108         </plugins>
109     </build>
110
111
112 </project>

  Thymeleaf 作为公众号页面前端
  weixin-java-mp 是微信公众号开发工具包
  Redis 主要用来集成OAuth2.0认证
  MongoDB 存一些JSON数据
  PostgreSQL 关系型数据,保存业务数据
  security-OAuth2 认证、权限控制
  spring-integration-mqtt MQTT客户端,用来与设备通讯

3.配置文件application.properties

  一些项目配置

 1 spring.application.name=wechat
 2
 3 server.port=8001
 4
 5 logging.path=log
 6 logging.level.org.springframework.web=INFO
 7 logging.level.com.github.binarywang.demo.wx.mp=DEBUG
 8 logging.level.com.wunaozai.wechat=DEBUG
 9
10 wechat.mp.appId=wxc60******
11 wechat.mp.secret=cfe2******
12 wechat.mp.token=we****
13 wechat.mp.aesKey=2Bq*******
14 #微信号
15 #wechat.mp.accountId=gh_8*****
16 #上传临时目录
17 wechat.mp.tmpDir=C:/tmp
18 #系统语音存放目录
19 project.voice.dir=D:/tmp
20 #微信语音资源下载链接前缀
21 project.resource.url=http://wechat.wunaozai.com/wx/v1/voice/recv
22
23 #接口配置
24 wechat.mp.url=http://wechat.wunaozai.com/wx/wechat
25 #JS接口安全域名配置
26 wechat.mp.js=wechat.wunaozai.com
27 #网页授权域名配置
28 wechat.mp.web.oauth=wechat.wunaozai.com
29 wechat.mp.protocol=http
30
31 spring.thymeleaf.prefix=classpath:/templates/
32 spring.thymeleaf.suffix=.html
33 spring.thymeleaf.mode=HTML5
34
35
36 #postgres
37 spring.datasource.url=jdbc:postgresql://172.16.23.202:5432/wechat
38 spring.datasource.username=postgres
39 spring.datasource.password=
40 spring.datasource.driver-class-name=org.postgresql.Driver
41
42 #mybatis
43 mybatis.type-aliases-package=com.wunaozai.wechat.model
44 mybatis.mapper-locations=classpath:com/wunaozai/wechat/mapper/*.xml
45
46 #pagehelper
47 pagehelper.helper-dialect=postgresql
48 pagehelper.reasonable=true
49 pagehelper.support-methods-arguments=true
50 pagehelper.page-size-zero=true
51
52 #redis
53 spring.redis.database=2
54 spring.redis.host=172.16.23.203
55 spring.redis.port=6379
56 spring.redis.password=f4e4********
57 spring.redis.jedis.pool.max-active=8
58 spring.redis.jedis.pool.max-wait=60
59 spring.redis.jedis.pool.max-idle=8
60 spring.redis.jedis.pool.min-idle=0
61 spring.redis.timeout=10000
62
63 #mongoDB
64 spring.data.mongodb.uri=mongodb://www.wunaozai.com:27777/wechat
65
66 #MQTT Client
67 mqtt.client.host=tcp://mqtt.wunaozai.com:1883
68 mqtt.client.clientid=*****admin
69 mqtt.client.username=*****admin
70 mqtt.client.password=*******
71 mqtt.client.timeout=10
72 mqtt.client.keepalive=20
73
74 #tuling123
75 api.tuling.url=http://openapi.tuling123.com/openapi/api/v2
76 api.tuling.apiKey=******
77 api.tuling.userId=******

4.配置wechat-java-mp 工具包
  这个配置基本参考官网的Demo就可以了。我这里截图我自己的目录结构。

  从目录结构可以看出,一个 WechatMpConfiguration.java 作为全局配置及微信开发工具包入口。而下方的handler是对所有微信的事件进行封装。
  例如菜单事件、关注事件、取消关注事件、扫描事件、语音事件、对话事件等。每个事件都对应一个Handler。

  1 /**
  2  * 微信公众号开发 全局配置区
  3  * @author wunaozai
  4  * @date 2018-08-15
  5  */
  6 @Configuration
  7 @ConditionalOnClass(value=WxMpService.class)
  8 @EnableConfigurationProperties(WechatMpProperties.class)
  9 public class WechatMpConfiguration {
 10
 11     @Autowired
 12     private WechatMpProperties properties;
 13     @Autowired
 14     private WechatMpLogHandler logHandler;
 15     @Autowired
 16     private WechatMpNullHandler nullHandler;
 17     @Autowired
 18     private WechatMpMenuHandler menuHandler;
 19     @Autowired
 20     private WechatMpMsgHandler msgHandler;
 21     @Autowired
 22     private WechatMpMsgVoiceHandler msgvoiceHandler;
 23     @Autowired
 24     private WechatMpUnsubscribeHandler unsubscribeHandler;
 25     @Autowired
 26     private WechatMpSubscribeHandler subscribeHandler;
 27     @Autowired
 28     private WechatMpScanHandler scanHandler;
 29
 30     @Bean
 31     @ConditionalOnMissingBean
 32     public WxMpConfigStorage configStorage() {
 33         WxMpInMemoryConfigStorage config = new WxMpInMemoryConfigStorage();
 34         config.setAppId(properties.getAppId());
 35         config.setSecret(properties.getSecret());
 36         config.setToken(properties.getToken());
 37         config.setAesKey(properties.getAesKey());
 38         config.setTmpDirFile(new File(properties.getTmpDir()));
 39         return config;
 40     }
 41
 42     @Bean
 43     @ConditionalOnMissingBean
 44     public WxMpService wxmpService(WxMpConfigStorage config) {
 45         WxMpService service = new WxMpServiceImpl();
 46         service.setWxMpConfigStorage(config);
 47         return service;
 48     }
 49     /*
 50     @Bean
 51     @ConditionalOnMissingBean
 52     public WxMpDeviceService wxMpDeviceService(WxMpService wxmpService) {
 53         WxMpDeviceService service = new WxMpDeviceServiceImpl(wxmpService);
 54         return service;
 55     }
 56     */
 57
 58     @Bean
 59     public WxMpMessageRouter router(WxMpService wxmpService) {
 60
 61         final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxmpService);
 62
 63         //记录所有事件日志(异步执行)
 64         newRouter.rule().async(false).handler(this.logHandler).next();
 65
 66         //当前项目Wifi故事机 只处理自定义菜单事件、关注/取关事件、文本和语音信息
 67         //自定义菜单事件
 68         newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
 69             .event(MenuButtonType.CLICK).handler(menuHandler).end();
 70         //关注事件
 71         newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
 72             .event(EventType.SUBSCRIBE).handler(subscribeHandler).end();
 73         //取消关注事件
 74         newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
 75             .event(EventType.UNSUBSCRIBE).handler(unsubscribeHandler).end();
 76         //处理扫描事件
 77         newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
 78             .event(EventType.SCANCODE_WAITMSG).handler(scanHandler).end();
 79
 80         //这里过滤掉所有事件
 81         newRouter.rule().async(false).msgType(XmlMsgType.EVENT).handler(nullHandler).end();
 82
 83         //处理语音信息
 84         newRouter.rule().async(false).msgType(XmlMsgType.VOICE).handler(msgvoiceHandler).end();
 85
 86         //这里过滤掉所有输入
 87         newRouter.rule().async(false).handler(msgHandler).end();
 88
 89         /*
 90         //接收客服会话管理事件
 91         newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
 92             .event(WxMpEventConstants.CustomerService.KF_CREATE_SESSION)
 93             .handler(kfsessionHandler).end();
 94         newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
 95             .event(WxMpEventConstants.CustomerService.KF_CLOSE_SESSION)
 96             .handler(kfsessionHandler).end();
 97         newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
 98             .event(WxMpEventConstants.CustomerService.KF_SWITCH_SESSION)
 99             .handler(kfsessionHandler).end();
100
101         //门店审核事件
102         newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
103             .event(MenuButtonType.CLICK).handler(nullHandler).end();
104
105         //自定义菜单事件
106         newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
107             .event(MenuButtonType.CLICK).handler(menuHandler).end();
108
109         //点击菜单链接事件
110         newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
111             .event(MenuButtonType.VIEW).handler(nullHandler).end();
112
113         //关注事件
114         newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
115             .event(EventType.SUBSCRIBE).handler(subscribeHandler).end();
116
117         //取消关注事件
118         newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
119             .event(EventType.UNSUBSCRIBE).handler(unsubscribeHandler).end();
120
121         //上报地理位置事件
122         newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
123             .event(EventType.LOCATION).handler(locationHandler).end();
124
125         //接收地理位置消息
126         newRouter.rule().async(false).msgType(XmlMsgType.LOCATION)
127             .handler(locationHandler).end();
128
129         //扫码事件
130         newRouter.rule().async(false).msgType(XmlMsgType.EVENT)
131             .event(EventType.SCAN).handler(nullHandler).end();
132
133         //默认
134         newRouter.rule().async(false).handler(msgHandler).end();
135         */
136         return newRouter;
137     }
138 }

5. 关注事件举例
  我们在WechatMpConfiguration.java中注册了一个关注事件处理Handler。

newRouter.rule().async(false).msgType(XmlMsgType.EVENT).event(EventType.SUBSCRIBE).handler(subscribeHandler).end();
 1 /**
 2  * 用户关注事件
 3  * @author wunaozai
 4  * @date 2018-08-15
 5  */
 6 @Component
 7 public class WechatMpSubscribeHandler extends AbstractHandler {
 8
 9     @Autowired
10     private WechatUserService wechatuserService;
11
12     @Override
13     public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxmpService,
14             WxSessionManager sessionManager) throws WxErrorException {
15         //log.info("新关注用户 openid: " + wxMessage.getFromUser());
16         //获取微信用户基本信息
17         WxMpUser user = wxmpService.getUserService().userInfo(wxMessage.getFromUser(), null);
18         if(user != null) {
19             //可以添加关注用户到本地数据库
20             WechatUserPoModel po = new WechatUserPoModel();
21             po.setOpenid(user.getOpenId());
22             po.setStatus(true);
23             wechatuserService.selectOneAndInsertIt(po);
24
25             po.setNickname(user.getNickname());
26             po.setSex_desc(user.getSexDesc());
27             po.setSex(user.getSex());
28             po.setCity(user.getCity());
29             po.setProvince(user.getProvince());
30             po.setCountry(user.getCountry());
31             po.setHead_img_url(user.getHeadImgUrl());
32             wechatuserService.updateOneByOpenid(po);
33
34         }
35         try {
36             String msg = "您好," + user.getNickname() +
37                     "!\n欢迎使用杰理故事机/:heart\n如果是第一次使用,请点击下方按钮,按提示步骤进行操作。";
38             return new WechatMpTextBuilder().build(msg, wxMessage, wxmpService);
39         } catch (Exception e) {
40             log.error(e.getMessage());
41         }
42         return null;
43     }
44 }

6. 扫码事件举例
  类似关注事件,扫码事件,也是需要在配置类,注册一个Handler。

newRouter.rule().async(false).msgType(XmlMsgType.EVENT).event(EventType.SCANCODE_WAITMSG).handler(scanHandler).end();
 1 @Component
 2 public class WechatMpScanHandler extends AbstractHandler {
 3
 4     @Autowired
 5     private WechatUserCtrlService wechatuserctrlService;
 6
 7     @Override
 8     public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxmpService,
 9             WxSessionManager sessionManager) throws WxErrorException {
10         String scan_type = wxMessage.getScanCodeInfo().getScanType();
11         String scan_result = wxMessage.getScanCodeInfo().getScanResult();
12         String info = "非本公众号内二维码";
13         try {
14             if(scan_type.equalsIgnoreCase("qrcode")) {
15                 ScanResult result = TranUtils.tranJSONObejct(scan_result, ScanResult.class);
16                 String openid = wxMessage.getFromUser();
17                 if(result.getK().equalsIgnoreCase("share")) {
18                     //设备分享功能
19                     try {
20                         boolean flag = wechatuserctrlService.bindDeviceByShareKey(openid, result.getV());
21                         if(flag == true) {
22                             info = "绑定成功.";
23                         }else {
24                             info = "绑定失败.";
25                         }
26                     }catch (Exception e) {
27                         info = e.getMessage();
28                     }
29                 }
30             }
31         }catch (Exception e) {
32             e.printStackTrace();
33         }
34         return new WechatMpTextBuilder().build(info, wxMessage, wxmpService);
35     }
36 }

7. 自定义菜单
  这个就分为创建自定义菜单和自定义菜单事件。创建自定义菜单,这个需要先构造自定义菜单格式,然后POST到微信。

 1 @RestController
 2 @RequestMapping("/wx/wechat")
 3 public class WechatMenuController implements WxMpMenuService {
 4
 5     @Autowired
 6     private WxMpService wxmpService;
 7     @Value(value="${wechat.mp.url}")
 8     private String url;
 9
10     @GetMapping("/menu")
11     public String menuCreateSample() throws WxErrorException {
12         WxMenu menu = new WxMenu();
13         WxMenuButton story = new WxMenuButton();
14         story.setType(MenuButtonType.VIEW);
15         story.setName("听故事");
16         story.setKey(WechatMpMenuConfig.M_STORY);
17         story.setUrl(url + "/story/index");
18
19         WxMenuButton device_1 = new WxMenuButton();
20         device_1.setType(MenuButtonType.VIEW);
21         device_1.setName("联网配置");
22         device_1.setKey(WechatMpMenuConfig.M_DEVICE_1);
23         device_1.setUrl(url + "/airkiss");
24         WxMenuButton device_2 = new WxMenuButton();
25         device_2.setType(MenuButtonType.VIEW);
26         device_2.setName("设备绑定");
27         device_2.setKey(WechatMpMenuConfig.M_DEVICE_2);
28         device_2.setUrl(url + "/scan_bind");
29         WxMenuButton device_3 = new WxMenuButton();
30         device_3.setType(MenuButtonType.SCANCODE_WAITMSG);
31         device_3.setName("二维码扫描");
32         device_3.setKey(WechatMpMenuConfig.M_DEVICE_3);
33         WxMenuButton device_4 = new WxMenuButton();
34         device_4.setType(MenuButtonType.VIEW);
35         device_4.setName("我的设备");
36         device_4.setKey(WechatMpMenuConfig.M_DEVICE_4);
37         device_4.setUrl(url + "/story/index#/user");
38         WxMenuButton device = new WxMenuButton();
39         device.setType(MenuButtonType.CLICK);
40         device.setName("设备功能");
41         device.setKey(WechatMpMenuConfig.M_DEVICE);
42         device.getSubButtons().add(device_1);
43         device.getSubButtons().add(device_2);
44         device.getSubButtons().add(device_3);
45         device.getSubButtons().add(device_4);
46
47
48         WxMenuButton other_1 = new WxMenuButton();
49         other_1.setType(MenuButtonType.VIEW);
50         other_1.setName("常见问题");
51         other_1.setKey(WechatMpMenuConfig.M_OTHER_1);
52         other_1.setUrl("https://mp.weixin.qq.com/s/YTGis2OK2Jtx-4NnnRqukw");
53         WxMenuButton other_2 = new WxMenuButton();
54         other_2.setType(MenuButtonType.VIEW);
55         other_2.setName("意见反馈");
56         other_2.setKey(WechatMpMenuConfig.M_OTHER_2);
57         other_2.setUrl(url + "/feedback");
58         WxMenuButton other_3 = new WxMenuButton();
59         other_3.setType(MenuButtonType.VIEW);
60         other_3.setName("官网");
61         other_3.setKey(WechatMpMenuConfig.M_OTHER_3);
62         other_3.setUrl("http://www.wunaozai.com/");
63         WxMenuButton other_4 = new WxMenuButton();
64         other_4.setType(MenuButtonType.CLICK);
65         other_4.setName("接收新信息");
66         other_4.setKey(WechatMpMenuConfig.M_OTHER_NEW_MSG);
67         WxMenuButton other = new WxMenuButton();
68         other.setType(MenuButtonType.CLICK);
69         other.setName("更多");
70         other.setKey(WechatMpMenuConfig.M_OTHER);
71         other.getSubButtons().add(other_1);
72         other.getSubButtons().add(other_2);
73         other.getSubButtons().add(other_3);
74         other.getSubButtons().add(other_4);
75
76
77         menu.getButtons().add(story);
78         menu.getButtons().add(device);
79         menu.getButtons().add(other);
80
81         wxmpService.getMenuService().menuCreate(menu);
82         return "ok";
83   }
84   //...
85 }

  自定义菜单事件Handler

 1 /**
 2  * 菜单功能
 3  * @author wunaozai
 4  * @date 2018-08-15
 5  */
 6 @Component
 7 public class WechatMpMenuHandler extends AbstractHandler {
 8
 9     @Override
10     public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxmpService,
11             WxSessionManager sessionManager) throws WxErrorException {
12         log.info("微信公众号 菜单功能");
13         String msg = String.format("Type: %s, Event: %s, Key: %s",
14                 wxMessage.getMsgType(), wxMessage.getEvent(), wxMessage.getEventKey());
15         if(MenuButtonType.VIEW.equals(wxMessage.getEvent())) {
16             //如果是跳转类按钮的就不进行处理
17             return null;
18         }
19         if(wxMessage.getEventKey().equalsIgnoreCase(WechatMpMenuConfig.M_OTHER_NEW_MSG)) {
20             //TODO: 读取数据库,下发信息,并删除
21             //如果没有信息的,提示没有未读信息
22             String info = "暂无新消息.";
23             return new WechatMpTextBuilder().build(info, wxMessage, wxmpService);
24         }
25         String info = "按下“"+wxMessage.getEventKey()+"”按钮,将跳转到指定的公众号页面.";
26         return new WechatMpTextBuilder().build(info, wxMessage, wxmpService);
27     }
28
29 }

  自定义菜单注册

newRouter.rule().async(false).msgType(XmlMsgType.EVENT).event(MenuButtonType.CLICK).handler(menuHandler).end();

  公众号后台-菜单分析

原文地址:https://www.cnblogs.com/wunaozai/p/9911089.html

时间: 2024-10-08 04:37:43

微信公众号开发-配置开发环境02的相关文章

基于java的微信公众号二次开发视频教程

详情请交流  QQ  709639943 00.基于java的微信公众号二次开发视频教程 00.leetcode 算法 面试 00.北风网 零基础到数据(大数据)分析专家-首席分析师 00.快速上手JMeter 00.Jmeter 00.2017年Java web开发工程师成长之路 00.R语言速成实战 00.R语言数据分析实战 00.Python+Django+Ansible Playbook自动化运维项目实战 00.Java深入微服务原理改造房产销售平台 00.Python3入门机器学习 经

微信公众号积分系统开发模式详解

微信公众号积分系统开发(李想.185.6504.8478)微信公众号积分系统是什么?微信公众号积分系统有什么用?微信公众号积分模式系统简介:O2O电子商务模式需具备五大要素:独立网上商城.国家级权威行业可信网站认证.在线网络广告营销推广.全面社交媒体与客户在线互动.线上线下一体化的会员营销系统.一种观点是,一家企业能兼备网上商城及线下实体店两者,并且网上商城与线下实体店全品类价格相同,即可称为O2O:也有观点认为,O2O是B2C( Business To Customers)的一种特殊形式. 在

微信公众号平台接口开发:基础支持,获取access_token

新建Asp.net MVC 4.0项目 WeChatSubscript是项目UI层 WeChatTools是封装操作访问公众号接口的一些方法类库 获取AccssToken 我们要的得到AccessToken,这是所有接口访问的基础,我们看看官方给出的接口调用文档 很简单明了,grant_type=client_credential,这是固定的不会变 appid与secret就是前面一章我叫大家记起来的那个认证口令数据. 下边我们来实现这个功能,新建WeCharBase.cs 1 public c

微信公众号平台接口开发:基础支持,获取微信服务器IP地址

官方说明 目前看不出来这个接口有哪些具体运用,但是既然有这个接口,那我们就试试能不能用 访问接口 修改WeCharBase.cs,新增以下2个方法 1 public static string ServerIPs 2 { 3 get { return GetServerIPs(); } 4 } 5 6 /// <summary>获取所有服务器IP</summary> 7 /// <returns></returns> 8 private static str

微信公众号PHP简单开发流程

微信公众号开发分傻瓜模式和开发者模式两种,前者不要考虑调用某些接口,只要根据后台提示傻瓜式操作即可,适用于非专业开发人员. 开发模式当然就是懂程序开发的人员使用的. 下面简单说一下微信公众号开发的简易流程,新手看看会有帮助,高手请一笑而过. 1.配置服务器: A.首先在本机建立如下结构的文件夹(这里是我自己的习惯,仅供参考) MMPN:总目录mro message public number 微信公众号 backup:备份目录,主要用于备份php文件,每次修改时将原稿备份到里面去. images

微信公众号的后台开发

公司想要做一个微信公众号,经理叫我去研究怎么自动回复信息,自定义菜单. 弄了几天,功能基本上都实现了,下面就讲讲步骤吧. 首先当然是需要一个微信公众号啦,没有的话可以先去申请(个人订阅号不支持自定义菜单,这个挺坑的,最后还是拿公司的工作号做的测试).申请完成后需要进行开发的基本配置. URL需要一个外网能够访问的地址(最好是映射到自己本机方便调试),Token与你程序中定义的token变量需要一致,用于接入微信的接口. 微信服务器转发request数据包含下面信息(在CoreServlet中的d

微信公众号二次开发(二)-注册新浪SAE

新浪SAE:Sina App Engine是新浪提供的云服务,对个人提供免费的Web应用/业务开发托管.运行平台.我们就用它来作为我们的开发服务器测试环境. 注册新浪云http://sinacloud.com/ 创建SAE应用,使用PHP作为开发语言 填写运营者身份信息 进入后台 在后台查看总揽 该服务器我们就将利用它作为我们的二次开发服务器进行配置. 欢迎微信扫一扫或搜索关注我的"Windows自动化运维"公众号,我会每天定期发布Windows自动化运维的相关知识供大家讨论研究. 本

微信公众号第三方平台开发坑

坑一:文档数据结构错误,导致授权方公众号二维码URL无法获取 在公众号授权流程文档页面中(点击查看),有这样一个数据结构: 我把这个代码复制出来,放在chrome里面,清楚的看到如下的数据结构: 错就错在这个qrcode_url,在微信官方提供的文档中,qrcode_url是出现在object的第一级属性中的,但是,TMD的微信真正返回的数据结构中,qrcode_url是在authprizer_info里面的.WHAT THE FUCK! 害得老子把自己的代码检查.调试了两个小时,之崩溃,就没有

微信公众号二次开发(三)-介绍tortoisesvn开发工具

SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS.互联网上很多版本控制服务已从CVS迁移到Subversion. 集中式管理的工作流程如下图: 集中式代码管理的核心是服务器,所有开发者在开始新一天的工作之前必须从服务器获取代码,然后开发,最后解决冲突,提交.所有的版本信息都放在服务器上.如果脱离了服务器,开发者基本上可以说是无法工作的.下面举例说明: 开始新一天的工作: 1.从服务器下载项目组最新代码. 2

微信公众号第三方平台开发概况

首先要知道为什么要用公众号第三方平台,公众号第三方平台的开放,是为了让公众号运营者,在面向垂直行业需求时,可以一键登录授权给第三方的公众号运营平台,通过第三方开发者提供的公众号第三方平台来完成相关业务.简单来说就是不懂技术的小白用户一键授权给第三方公司代理开放的权限如发送消息等,不用填写一些繁琐的Appid,AppSecret,URL,Token等信息.博客中已有园友写了详细的内容,以下只是强调开发过程中的一些问题. 微信的授权流程 具体的详情请见官网 接下来就首先要申请公众号第三方平台,具体流