2014-06-20 15:21:17 u013802231 阅读数 2384
  • 微信公众号开发6-事件开发管理-微信开发php

    微信公众平台开发之事件开发管理是子恒老师《微信公众平台开发》视频教程的第6部。详细讲解了用php开发微信,对微信公众平台中的常见事件管理开发。内容包含微信关注事件,取消关注事件等等,其它的事件会在相应的章节中详细讲述。欢迎反馈,微信/QQ:68183131

    4490 人正在学习 去看看 秦子恒
微信开发案例教程按知识点划分,共100小节,每小节时间不等,请学员注意!


微信开发教程-深入浅出微信公众平台实战开发(微网站、LBS云、Api接口调用、服务号高级接口)


1.1、课程的背景


微信公众平台的火热程度已经不用多言,无论是个人还是企业,政府还是商家,都已经开始搭建微信公众平台,微信的作用已经被各界人士认可。微信公众平台的技术需求市场缺口巨大。


1.2、微信开发教程课程内容简介


微信开发案例教程基于微信公众平台官方代码,由易到难,深入浅出的讲解微信公众平台各种常见功能的开发,微信开发教程包括Api接口调用,lbs应用,服务号高级接口,二级菜单,微网站搭建,分100节小课程,时长合计10小时26分钟。本课程针对零基础学员,如果具有一定的php和jquery基础将更快速的学习。


微信开发案例教程具体内容请查看:http://www.ibeifeng.com/goods-383.html


1.3、微信开发教程课程特色


1、讲师为业余程序开发爱好者,短时间内通过自学掌握微信公众平台开发技术,可以提供快速学习的方法和介绍学习经验,特别适合零基础学员。


2、微信公众平台各功能都是在客户需求基础上开发,实用性强。


3、在微信官方示例代码上进行修改,适合基础学员学习,避免讲解过于复杂的类的封装和继承。


1.4、微信开发视频教程课程亮点


1、紧跟最新微信公众平台接口更新内容,对各个接口讲解全面。


2、云平台开发,兼顾主流的BAE和SAE云平台,降低学习成本。


3、Dw6微网站开发,快速上手,所见所得,减少代码录入。


4、单客服、多客服、手机留言客服系统,多种客服解决方案,解决企业需求。


5、刮刮卡、会员卡、大转盘、一站到底微信流行游戏悉数介绍。


1.5、微信开发教程课程大纲




1、微信公众平台基础篇


(1)微信公众平台简介:开发准备、账号注册


(2)官方代码讲解


(3)编辑模式


(4)接口验证


(5)关键词回复


(6)关注事件


(7)图文消息


(8)音乐信息


(9)超链接,xml转义


(10)图片回复


2、Api调用


(11)车联网api测距


(12)最近店铺


(13)天气预报


(14)周边酒店


(15)静态地图


3、数据库


(16)Mysql数据库链接


(17) 欢迎老朋友,数据保存


(18)奖品秒杀


(19)数据库导入


4、提高篇


(20)综合功能,各类消息整合


(21)html5播放视频


(22)组合地图


(23)小黄鸡api


(24)调用手机web应用


(25)图片数据库


(26)字符串截取


(27)二级菜单


(28)图书馆查询 Rss调用


(29)SAE及SVN使用


(30)遍历数组


(31)刮刮乐


(32)缓存


(33)wap页制作


(34)足球比分,simple_html_dom应用


(35)导航地图


(36)模糊匹配


(37)百度翻译


(38)快递查询


(39)翻页查询


(40)任意翻页


(41)会员卡,BAE图片工具


(42)curl简介


(43)curl伪造来源


(44)法律查询


(45)curl重新定向


(46)自定义菜单


(47)微信5.0变化


(48)正则表达式


(49)简答题


(50)连闯三关


(51)电影点播


(52)四六级查询


5、微网站


(53)微网站介绍html+jqm


(54) 留言本


(55)手机浏览限制


(56)幻灯片,jqm事件


(57)滚屏,jqm方法


(58)日期插件


(59)html5定位+街景调用


(60)微网站布局


(61)升级版会员卡


(62)大转盘


(63)面板使用panel


(64) 人脸识别


6、服务号高级接口


(65)视频语音消息


(66) 高级接口综述


(67)语音接口,机器人问答


(68)语音接口,学英语


(69)客服接口,多条回复


(70)客服接口,生日提醒


(71)客服接口,手机随时回复


(72)永久二维码,分场景统计


(73)永久二维码,校园指南


(74)临时二维码,限时抢购


(75)地理位置接口,跑步签到


(76) 获取用户信息接口


(77)关注着列表接口


(78)分组管理接口


(79)多媒体上传下载接口


(80)oauth2 投票


(81)oauth2 留言


(82)声音提醒,ajax


(83)贺年卡


(84)微信墙


(85)叫号系统


(86)每问必答系统


(87)答错即过系统


(88)一站到底系统


(89)LBS云初步


(90)LBS云进阶


(91)单客服系统


(92)多客服系统


(93)异性对话


(94)摇色子


(95)WeixinJS接口


(96)中文分词


(97)360全景


(98)订阅号开发


(99)服务号开发


(100)代码调试
2013-10-03 22:38:29 zhihang1103 阅读数 1097
  • 微信公众号开发6-事件开发管理-微信开发php

    微信公众平台开发之事件开发管理是子恒老师《微信公众平台开发》视频教程的第6部。详细讲解了用php开发微信,对微信公众平台中的常见事件管理开发。内容包含微信关注事件,取消关注事件等等,其它的事件会在相应的章节中详细讲述。欢迎反馈,微信/QQ:68183131

    4490 人正在学习 去看看 秦子恒

    在微信接口的开发文档中定义了很多事件,当用户发送各种事件都有特定的回复,以下是关注时回复的具体代码展示:

<?php

//define your token
define("TOKEN", "wechatnow");
$wechatObj = new wechatCallbackapiTest();
//$wechatObj->valid();
$wechatObj->responseMsg();

class wechatCallbackapiTest
{
	public function valid()
    {
        $echoStr = $_GET["echostr"];

        //valid signature , option
        if($this->checkSignature()){
        	echo $echoStr;
        	exit;
        }
    }

    public function responseMsg()
    {
		//get post data, May be due to the different environments
		$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];

      	//extract post data
		if (!empty($postStr)){
                
              	$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
                $fromUsername = $postObj->FromUserName;
                $toUsername = $postObj->ToUserName;
                $keyword = trim($postObj->Content);
                $time = time();
                $textTpl = "<xml>
							<ToUserName><![CDATA[%s]]></ToUserName>
							<FromUserName><![CDATA[%s]]></FromUserName>
							<CreateTime>%s</CreateTime>
							<MsgType><![CDATA[%s]]></MsgType>
							<Content><![CDATA[%s]]></Content>
							<FuncFlag>0</FuncFlag>
							</xml>";  
							
				$ev=$postObj->Event;//subscirbe event			
				if($ev=="subscribe")
				{
					$msgType = "text";
					$contentStr="欢迎关注***,你的支持是我一直前行的动力!";
					$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
					echo $resultStr;
				}
				if($ev=="unsubscribe")
				{
					$msgType = "text";
					$contentStr="***将会推出更多贴心的功能,欢迎继续关注!";
					$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
					echo $resultStr;
				}
								
							           
				if(!empty( $keyword ))//depent on your keyword
                {
              		$msgType = "text";
                	switch ($keyword)
					{
					case "你好";
					$contentStr = "你好,我是robot!";
					$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
                	echo $resultStr;
					break;
					case "加油";
					$contentStr = "加油!";
					$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
                	echo $resultStr;
					break;
					case "图文";//返回图文信息
					$picTpl=" <xml>
					 <ToUserName><![CDATA[%s]]></ToUserName>
					 <FromUserName><![CDATA[%s]]></FromUserName>
					 <CreateTime>%s</CreateTime>
					 <MsgType><![CDATA[news]]></MsgType>
					 <ArticleCount>2</ArticleCount>
					 <Articles>
					 <item>
					 <Title><![CDATA[Hello Word!]]></Title> 
					 <Description><![CDATA[Weibo]]></Description>
					 <PicUrl><![CDATA[http://0.wechatnow.duapp.com/weibo.jpg]]></PicUrl>
					 <Url><![CDATA[http://weibo.com/***]]></Url>
					 </item>
					 <item>
					 <Title><![CDATA[wechat]]></Title>
					 <Description><![CDATA[***]]></Description>
					 <PicUrl><![CDATA[http://0.wechatnow.duapp.com/wechat.png]]></PicUrl>
					 <Url><![CDATA[http://weibo.com/***]]></Url>
					 </item>
					 </Articles>
					 </xml> 
					";
					$resultStr = sprintf($picTpl, $fromUsername, $toUsername, $time);
               	    echo $resultStr;
					default;
					$contentStr = "欢迎关注***,更多功能即将推出!";	
					$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
                	echo $resultStr;		
					}			
                }else{
                	echo "Input something...";
                }

        }else {
        	echo "";
        	exit;
        }
    }
		
	private function checkSignature()//check your signature
	{
        $signature = $_GET["signature"];
        $timestamp = $_GET["timestamp"];
        $nonce = $_GET["nonce"];	
        		
		$token = TOKEN;
		$tmpArr = array($token, $timestamp, $nonce);
		sort($tmpArr);
		$tmpStr = implode( $tmpArr );
		$tmpStr = sha1( $tmpStr );
		
		if( $tmpStr == $signature ){
			return true;
		}else{
			return false;
		}
	}
}

?>


2017-07-28 15:32:35 chenqiuge1984 阅读数 2830
  • 微信公众号开发6-事件开发管理-微信开发php

    微信公众平台开发之事件开发管理是子恒老师《微信公众平台开发》视频教程的第6部。详细讲解了用php开发微信,对微信公众平台中的常见事件管理开发。内容包含微信关注事件,取消关注事件等等,其它的事件会在相应的章节中详细讲述。欢迎反馈,微信/QQ:68183131

    4490 人正在学习 去看看 秦子恒

本文节选自苏震巍撰写的《微信开发深度解析:微信公众号、小程序高效开发秘籍》一书,由电子工业出版社出版。
责编:陈秋歌,关注微信开发等领域,寻求报道或者投稿请发邮件至chenqg#csdn.net。

MessageHandler 是一个微信消息的处理模块,也是整个微信开发过程中不可缺少的一部分。在 MessageHandler 中,开发者可以非常轻松地处理所有类型的微信消息。

本文将介绍 MessageHandler 的原理以及使用方法,包括支撑MessageHandler 运行所必需的实体类型、工厂方法等相关知识的介绍。

设计思想

如果你已经了解微信消息的基本通信原理,那我们现在可以非常方便地构造出一个简单的消息处理功能,如下:


StreamReader str = new StreamReader(Request.InputStream, System.Text.Encoding. UTF8);
XmlDocument xml = new XmlDocument();
xml.Load(str);
var wx = new WeixinRequest();
wx.ToUserName = xml.SelectSingleNode("xml").SelectSingleNode("ToUserName").InnerText;
wx.FromUserName = xml.SelectSingleNode("xml").SelectSingleNode("FromUserName"). InnerText;
wx.MsgType = xml.SelectSingleNode("xml").SelectSingleNode("MsgType").InnerText;
if (wx.MsgType.Trim() == "event")
{
    wx.EventName = xml.SelectSingleNode("xml").SelectSingleNode("Event").InnerText;
    //  WriteLog(wx.EventName);
    if (wx.EventName.ToUpper() == "LOCATION")
    {
        wx.Latitude = xml.SelectSingleNode("xml").SelectSingleNode("Latitude").InnerText;
        wx.Longitude = xml.SelectSingleNode("xml").SelectSingleNode("Longitude"). InnerText;
        wx.Precision = xml.SelectSingleNode("xml").SelectSingleNode("Precision"). InnerText;
    }
    else
    {
        wx.EventKey = xml.SelectSingleNode("xml").SelectSingleNode("EventKey"). InnerText;
    }
}
else if (wx.MsgType.Trim() == "text")
{
    wx.Content= xml.SelectSingleNode("xml").SelectSingleNode("Content").InnerText;
} else if (...)
{
    //...
}

这个方法也是目前很多其他框架甚至微信官方的Demo使用的,但是这种方法我可以用“不美好”来形容。

不美——首先使用字符串拼接的方式非常丑陋,其次哪怕使用 XmlDocument 或 XDocument 等面向对象的方式去处理,面对几十种不同的微信消息类型以及一一对应的不同的格式,代码将变得非常冗长而且难以维护。这样的代码你的老板或客户会喜欢吗?

不好——这样的写法坏处太多:

  • 可移植性差
  • 并没有做到很好地分离(无论是和整个应用程序还是不同请求类型之间)
  • 如果要做单元测试就必须整体代码一起上
  • 基本上不具备可扩展性
  • 容错能力很差,即使做到了,代码已经无法直视
  • 正常人用多了会心情不好

那么,“美好”的消息处理方式应该是怎么样的呢?

下面就将 Senparc.Weixin.MP.MessageHandler 介绍给你。

首先,美好的 MessageHandler 必须具有对消息类型的自动识别和分类能力。

第二,美好的 MessageHandler 必须能够同时、自动处理“明文”“兼容模式”“加密模式”三种(所有)消息加密类型,并且让开发者忘掉加密这回事情的存在。

第三,美好的 MessageHandler 必须能够提供很好的消息容器以及储存容器,来解决消息去重、Session 等一系列的问题。

第四,美好的 MessageHandler 必须能够兼容 MVC 和 WebFroms 不同的请求处理方式。

第五,美好的 MessageHandler 必须能够提供统一逻辑处理的接口,方便在特定的环节对消息进行统一处理。

第六,美好的 MessageHandler 必须具备优秀的可测试性和扩展能力。

第七,美好的 MessageHandler 必须能做到很好的逻辑分离。

第八,美好的 MessageHandler 必须让你用起来心情好。

第九,美好的 MessageHandler 不能保证你能在 10 分钟内,完成一个满足以上八条的简单微信应用从开发到上线、发布的全过程。但是我们做到了。

消息类型

概述

微信的互动消息包含请求消息响应消息两类:

  • 请求消息:由微信服务器发送到应用服务器的消息(通常由用户微信操作触发或用户主动发送)。
    -响应消息:应用服务器收到请求消息之后,返回给微信服务器的消息。响应消息可以被转发到用户微信,也可以采用“沉默”的方式不给予响应。

所有的消息类型如图1所示(至本文发布,消息类型又丰富了许多)。

图片描述

图1

无论是请求消息还是响应消息,各自还包括不同的消息类型,其中每一种消息类型,又都有不同的参数和对应的格式要求。

对应每一种消息具体的参数和 XML 格式可以参考微信官方Wiki,这里不再赘述。本书将重点针对面向对象的类展开介绍,使用 Senparc.Weixin SDK 的开发者基本上可以忘掉微信的 XML 格式和要求,只需要了解如何面向对象地处理消息。当然,对于 XML 的了解将帮助你更加从容地处理一些问题,例如测试和调试过程都可能需要用到 XML。

命名规则

为了可以使用 C# 面向对象地处理问题,同时也更加规范地进行编程,我们决定在一些地方改变微信原有的命名规则(全部使用小写,用下划线_分隔不同单词),而使用 C# 推荐的命名方式(Pascal 大小写命名法)来作为类名或属性名称。如微信文档中的属性或名称可能为 access_token,在 Senparc.Weixin 中将被命名为 AccessToken。当阅读微信官方的文档时理解这样的变化举一反三即可。

当然,这种改变是灵活的,有一些地方我们仍然需要保持参数名称的“原貌”来确保 JSON 和 XML 自动转换的准确性和稳定性。

这样的改变不仅出现在消息类型中,对本书后面会介绍的 API 和其他功能同样适用。
全局消息基类

在所有这些消息类型中,都具有一些相同的属性,因此在 MessageHandler 体系中,我们为所有的消息创建了一个基类 MessageBase

    /// <summary>
    /// 所有Request和Response消息的基类
    /// </summary>
    public abstract class MessageBase : IMessageBase
    {
        public string ToUserName { get; set; }
        public string FromUserName { get; set; }
        public DateTime CreateTime { get; set; }
    }

MessageBase将作为所有消息的基类,无论是请求消息还是响应消息,也无论是微信公众号还是企业号或开放平台等,MessageBase 对微信消息进行了非常高度的抽象和概括。

下面我们将分别介绍的请求消息和响应消息都是以 MessageBase 作为基类的。

请求消息

请求消息又分为两种类型:普通消息事件推送消息。无论是哪一种消息,它们都具有相同的基础参数,如表1所示。

图片描述

为此,在 MessageBase 的基础上,我们为所有的请求消息设置了一个基类 RequestMessageBase

图片描述

请注意 RequestMessageBase 是一个抽象类,因此不可以被直接实例化。事实上,这个类也不应该被实例化,因为我们没有办法通过实例化这个类达到操作一个具体的请求类型消息的目的,我们仍然需要创建基于 RequestMessageBase 的对应每一个消息类型的实体来对其进行操作(作为全局考虑,不光微信公众号的请求消息需要用到 RequestMessageBase,企业号、开放平台等其他模块也需要用到)。

以上的基类都定义在 Senparc.Weixin.dll 中,普通消息的定义在Senparc.Weixin.MP.dll 中,直接使用 RequestMessageBase 作为基类,对应关系如表2所示。

图片描述

事件推送消息比普通消息多了 Event 这个属性,因此我们为所有的事件推送消息定义了一个统一的基类 RequestMessageEventBase

    public class RequestMessageEventBase : RequestMessageBase, IRequestMessageEventBase
    {
        public override RequestMsgType MsgType
        {
            get { return RequestMsgType.Event; }
        }

        /// <summary>
        /// 事件类型
        /// </summary>
        public virtual Event Event
        {
            get { return Event.ENTER; }
        }
    }

可以看到 RequestMessageEventBaseRequestMessageBase 多了一个 Event 属性,并且对MsgType 属性进行了强制的规定,默认情况下所有继承 RequestMessageEventBase 的类型都将返回 RequestMsgType.Event,这样 MessageHandler 将可以对事件推送消息消息类型进行特殊的处理。

由于事件推送消息类型比较多,我们将其分为 3 大类:

  • 常规事件(公众号基础功能返回事件)
  • 菜单事件(各种类型的公众号菜单返回事件)
  • 应用事件(应用模块返回事件,例如卡券、多客服等)

对应如表3所示。

图片描述

以上的类型中,都具有从 RequestMessageEventBase 继承而来的 Event 属性,有部分类型都具有 EventKey 属性,说明如表4所示。

图片描述

并不是所有的事件都具有EventKey,因此我们提供了IRequestMessageEventKey 接口,所有实现此接口的消息类型必须提供 EventKey,例如订阅事件:

    /// <summary>
    /// 事件之订阅
    /// </summary>
    public class RequestMessageEvent_Subscribe : RequestMessageEventBase, IRequestMessageEventBase, IRequestMessageEventKey
    {
        /// <summary>
        /// 事件类型
        /// </summary>
        public override Event Event
        {
            get { return Event.subscribe; }
        }

        /// <summary>
        /// 事件KEY值,qrscene_为前缀,后面为二维码的参数值(如果不是扫描场景二维码,此参数为空)
        /// </summary>
        public string EventKey { get; set; }
        /// <summary>
        /// 二维码的ticket,可用来换取二维码图片(如果不是扫描场景二维码,此参数为空)
        /// </summary>
        public string Ticket { get; set; }
    }

有些事件则不需要 EventKey,如取消订阅事件:

    /// <summary>
    /// 事件之取消订阅
    /// </summary>
    public class RequestMessageEvent_Unsubscribe : RequestMessageEventBase, IRequestMessageEventBase
    {
        /// <summary>
        /// 事件类型
        /// </summary>
        public override Event Event
        {
            get { return Event.unsubscribe; }
        }
    }

注意:实现 EventKey 参数类型都是字符串,但是在不同的事件中会具有不同的含义,有些官方已经规定了参数格式(如:扫描带参数二维码事件,都是以 qrscene_ 为前缀),而有些可以自己定义(如:菜单点击事件),在开发的过程中需要注意。


注意:事件推送消息的触发大部分是通过用户的某个微信界面的操作触发的(如:菜单点击、发送语音等),也有通过其他操作触发的(如:微小店订单付款通知、多客服转接会话等),因此在“人肉测试”的时候要格外注意结合参考微信官方的文档,了解其触发流程,避免误认为程序问题而没有触发事件的错误判断。

响应消息
响应消息和请求消息的设计原理类似,所有响应消息的类型都继承自ResponseMessageBase,ResponseMessageBase 同样继承自 MessageBase。 Senparc.Weixin.dll 下的 ResponseMessageBase (Weixin.Entities.ResponseMessageBase)代码如下:

 /// <summary>
 /// 响应回复消息
 /// </summary>
 public abstract class ResponseMessageBase : MessageBase, IResponseMessageBase
 {
 }

以上 Weixin.Entities.ResponseMessageBase 适用于包含微信公众号、企业号、开发平台等在内的多个平台,作为响应消息的基类。

为了增强 MessageHandler 的便捷性,Senparc.Weixin.MP.dll 提供了专门用于微信公众号的 ResponseMessageBase (Senparc.Weixin.MP.Entities. ResponseMessageBase,继承自 Senparc.Weixin. Entities.ResponseMessageBase),代码如下:

    /// <summary>
    /// 微信公众号响应回复消息基类
    /// </summary>
    public class ResponseMessageBase : Weixin.Entities.ResponseMessageBase, IResponseMessageBase
    {
        public virtual ResponseMsgType MsgType
        {
            get { return ResponseMsgType.Text; }
        }

        /// <summary>
        /// 获取响应类型实例,并初始化
        /// </summary>
        /// <param name="requestMessage">请求</param>
        /// <param name="msgType">响应类型</param>
        /// <returns></returns>
        [Obsolete("建议使用CreateFromRequestMessage<T>(IRequestMessageBase requestMessage)取代此方法")]
        private static ResponseMessageBase CreateFromRequestMessage(IRequestMessageBase requestMessage, ResponseMsgType msgType)
        {
            //略
        }

        /// <summary>
        /// 获取响应类型实例,并初始化
        /// </summary>
        /// <typeparam name="T">需要返回的类型</typeparam>
        /// <param name="requestMessage">请求数据</param>
        /// <returns></returns>
        public static T CreateFromRequestMessage<T>(IRequestMessageBase requestMessage) where T : ResponseMessageBase
        {
            //略        }

        /// <summary>
        /// 从返回结果XML转换成IResponseMessageBase实体类
        /// </summary>
        /// <param name="xml">返回给服务器的Response Xml</param>
        /// <returns></returns>
        public static IResponseMessageBase CreateFromResponseXml(string xml)
        {
            //略        }
    }

通过上述的两个 ResponseMessageBase,我们可以发现,和 RequestMessageBase 不同的是,ResponseMessageBase 没有提供 MsgId,这就意味着:应用程序服务器回复微信服务器的消息,必须一次成功,微信没有提供和响应消息一样的容错机制(数秒内收不到响应则连续发送几条带有 MsgId 的消息到应用服务器,确保消息可以到达)。也就是说,如果这条响应消息因为各种原因没有发送成功(网络问题或格式错误),客户端将收不到正确的消息回复,通常还会显示一条“该公众号暂时无法提供服务,请稍后再试(Official account services unavailable. Try again later)”的错误信息,如图2所示。

图片描述

图2

此错误可以在“盛派网络小助手”发送文字“错误”进行测试。

注意:对于多条带有相同 MsgId 的请求消息进行多次回复,客户端也只能收到微信服务器最后一次重发所对应的这条响应消息。

例如由于应用程序服务器没有及时响应,微信服务器连续发送了 3 条MsgId都为 6224799151644543291 的消息到应用程序服务器,这三次请求分别为 A、B、C,应用程序服务器由于没有对消息去重,分别响应了 A1、B1、C1,此时,客户端只会收到一条 C1 的回复。此错误可以在“盛派网络小助手”发送文字“容错”进行测试。

响应消息的类型比请求消息要少许多,如表5所示。

图片描述

上述响应类型中,有部分包含复杂的属性,我们将其独立创建类,分别有:Image、Voice、Video、Music、Article 这些类型。
以比较常用的图文消息为例,ResponseMessageNews 定义如下:

/// <summary>
    /// 图文消息
    /// </summary>
    public class ResponseMessageNews : ResponseMessageBase, IResponseMessageBase
    {
        new public virtual ResponseMsgType MsgType
        {
            get { return ResponseMsgType.News; }
        }

        public int ArticleCount
        {
            get
            {
                return Articles == null ? 0 : Articles.Count;
            }
            set
            {
                //这里开放set只为了逆向从Response的XML转成实体的操作一致性,没有实际意义。
            }
        }

        /// <summary>
        /// 文章列表,微信客户端只能输出前10条(可能未来数字会有变化,出于视觉效果考虑,建议控制在8条以内)
        /// </summary>
        public List<Article> Articles { get; set; }

        public ResponseMessageNews()
        {
            Articles = new List<Article>();
        }
    }

由于工厂模式自动初始化的需要,必须提供一个不带参数的构造函数,因此Articles参数无法通过构造函数设置,必须分成两步:

    var reponseMessage = CreateResponseMessage<ResponseMessageNews>();
    reponseMessage.Articles.Add(new Article()
    {
        Title = "你点击了子菜单图文按钮",
        Description = "你点击了子菜单图文按钮,这是一条图文信息。",
        PicUrl = "http://weixin.senparc.com/Images/qrcode.jpg",
        Url = "http://weixin.senparc.com"
    });

当 Articles 列表中只有 1 个 Article 对象的时候,显示为单图文,如图3所示。当 Article 大于 1 个时,显示为多图文,如图4所示。Articles 中最多允许有 10 个 Article 对象,即 10 条图文信息。

图片描述

使用MessageHandler

下面来看一下 MessageHandler 是如何让你爱上微信开发的。

在上述例子中,你只需要做三步:

  • 第一步:通过 Nuget 安装 Senparc.Weixin.MP。
  • 第二步:创建你自己的 MessageHandler(大部分代码只需要复制)。
  • 第三步:写 3 行关键代码(同样只需要复制)。

下面我们来跟随这三步,略为详细地展开一下 MessageHandler 最基础的一些用法,随后我们将学习 MessageHandler 的内部实现。

第一步:通过Nuget安装Senparc.Weixin.MP

第二步:创建你自己的MessageHandler

创建新文件 CustomMessageHandler.cs。CustomMessageHandle.cs 需要继承 Senparc.Weixin.MP. MessageHandlers 这个抽象类,并实现部分方法。最初步的 CustomMessageHandle.cs 代码可以如下。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using Senparc.Weixin.MP.Context;
using Senparc.Weixin.MP.Entities;
using Senparc.Weixin.MP.MessageHandlers;

namespace Senparc.Weixin.MP.Sample.Weixin
{
    public class CustomMessageHandler : MessageHandler<CustomMessageContext>
    {
        public CustomMessageHandler(Stream inputStream, PostModel postModel)
            : base(inputStream, postModel)
        {

        }

        public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)
        {
            var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); //ResponseMessageText也可以是News等其他类型
            responseMessage.Content = "这条消息来自DefaultResponseMessage。";
            return responseMessage;
        }
    }
}

我们可以看到必须要重写实现的抽象方法名为 DefaultResponseMessage(),这一条信息用于返回一条默认(替补)消息,假如对应类型(如语音)的微信消息没有被代码处理,那么默认会返回这里的结果。

在 DefaultResponseMessage() 方法中,有这样一句:

var responseMessage = base.CreateResponseMessage<ResponseMessageText>(); //ResponseMessageText也可以是News等其他类型

这里的 CreateResponseMessage 方法即创建一个返回对象,T 可以为以下类型的任意一个,分别对应了不同的返回类型,具体类型及说明请参考表5。

关于上述所有类型参数的设置方法,可以看 Senparc.Weixin SDK 的官方 Demo,这里不再重复。

接下来,我们了解下如何处理微信服务器发过来的文字信息。

很简单——在 CustomMessageHandler 里面重写一个 OnTextRequest 方法即可 :


public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)
{
    if (requestMessage.Content == "你好")
    {
        var responseMessage = base.CreateResponseMessage<ResponseMessageNews>();
        var title = "Title";
        var description = "Description";
        var picUrl = "PicUrl";
        var url = "Url";
        responseMessage.Articles.Add(new Article()
        {
            Title = title,
            Description = description,
            PicUrl = picUrl,
            Url = url
        });
        return responseMessage;
    }
    else if (requestMessage.Content == "Senparc")
    {
        //相似处理逻辑
    }
    else
    {
        //...
    }
}

这个方法中可以自由发挥,比如读取数据库、判断关键字,甚至返回不同的ResponseMessageXX 类型(只要最终的类型都是在 IResponseMessageBase 接口下的即可)。

与 OnTextRequest 对应,如果我们要处理语音、地理位置、菜单等类型的消息,只需要重写对应的方法,可以重写的方法如下:

  • 接收消息方法
#region 接收消息方法

/// <summary>
/// 默认返回消息(当任何OnXX消息没有被重写,都将自动返回此默认消息)
/// </summary>
public abstract IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage);

/// <summary>
/// 预处理文字或事件类型请求。
/// 这个请求是一个比较特殊的请求,通常用于统一处理来自文字或菜单按钮的同一个执行逻辑,
/// 会在执行OnTextRequest或OnEventRequest之前触发,具有以下一些特征:
/// 1、如果返回null,则继续执行OnTextRequest或OnEventRequest
/// 2、如果返回不为null,则终止执行OnTextRequest或OnEventRequest,返回最终ResponseMessage
/// 3、如果是事件,则会将RequestMessageEvent自动转为RequestMessageText类型,其中RequestMessageText.Content就是RequestMessageEvent.EventKey
/// </summary>
public virtual IResponseMessageBase OnTextOrEventRequest(RequestMessageText requestMessage){...}

/// <summary>
/// 文字类型请求
/// </summary>
public virtual IResponseMessageBase OnTextRequest(RequestMessageText requestMessage) {...}

/// <summary>
/// 位置类型请求
/// </summary>
public virtual IResponseMessageBase OnLocationRequest(RequestMessageLocation requestMessage) {...}

/// <summary>
/// 图片类型请求
/// </summary>
public virtual IResponseMessageBase OnImageRequest(RequestMessageImage requestMessage) {...}

/// <summary>
/// 语音类型请求
/// </summary>
public virtual IResponseMessageBase OnVoiceRequest(RequestMessageVoice requestMessage) {...}

/// <summary>
/// 视频类型请求
/// </summary>
public virtual IResponseMessageBase OnVideoRequest(RequestMessageVideo requestMessage) {...}

/// <summary>
/// 链接消息类型请求
/// </summary>
public virtual IResponseMessageBase OnLinkRequest(RequestMessageLink requestMessage) {...}

/// <summary>
/// 小视频类型请求
/// </summary>
public virtual IResponseMessageBase OnShortVideoRequest(RequestMessageShortVideo requestMessage) {...}

#endregion
  • 接收事件方法
#region Event下属分类,接收事件方法

/// <summary>
/// Event事件类型请求之ENTER
/// </summary>
public virtual IResponseMessageBase OnEvent_EnterRequest(RequestMessageEvent_ Enter requestMessage){...}

/// <summary>
/// Event事件类型请求之LOCATION
/// </summary>
public virtual IResponseMessageBase OnEvent_LocationRequest(RequestMessageEvent_ Location requestMessage) {...}

//依此类推还有:
// Event事件类型请求之subscribe:OnEvent_SubscribeRequest()
// Event事件类型请求之unsubscribe:OnEvent_UnsubscribeRequest()
// Event事件类型请求之CLICK:OnEvent_ClickRequest()
// Event事件类型请求之scan:OnEvent_ScanRequest()
// 事件之URL跳转视图(View):OnEvent_ViewRequest()
// 事件推送群发结果:OnEvent_MassSendJobFinishRequest()
// 发送模板消息返回结果:OnEvent_TemplateSendJobFinishRequest()
// 弹出拍照或者相册发图:OnEvent_PicPhotoOrAlbumRequest()
// 扫码推事件:OnEvent_ScancodePushRequest()
// 扫码推事件且弹出“消息接收中”提示框:OnEvent_ScancodeWaitmsgRequest()
// 弹出地理位置选择器:OnEvent_LocationSelectRequest()
// 弹出微信相册发图器: OnEvent_PicWeixinRequest()
// 弹出系统拍照发图:OnEvent_PicSysphotoRequest()
// 卡券通过审核:OnEvent_Card_Pass_CheckRequest()
// 卡券未通过审核: OnEvent_Card_Not_Pass_CheckRequest()
// 领取卡券:OnEvent_User_Get_CardRequest()
// 删除卡券:OnEvent_User_Del_CardRequest()
// 多客服接入会话:OnEvent_Kf_Create_SessionRequest()
// 多客服关闭会话:OnEvent_Kf_Close_SessionRequest()
// 多客服转接会话:OnEvent_Kf_Switch_SessionRequest()
// Event事件类型请求之审核结果事件推送:OnEvent_Poi_Check_NotifyRequest()
// Event事件类型请求之Wi-Fi连网成功:OnEvent_WifiConnected()
// Event事件类型请求之卡券核销:OnEvent_User_Consume_Card()
// Event事件类型请求之从卡券进入公众号会话:OnEvent_User_Enter_Session_From_Card()
// Event事件类型请求之进入会员卡:OnEvent_User_View_Card()
// Event事件类型请求之微小店订单付款通知:OnEvent_Merchant_Order()
// Event事件类型请求之接收会员信息事件通知:OnEvent_Submit_Membercard_User_Info()
// Event事件类型请求之摇一摇事件通知:OnEvent_ShakearoundUserShake()

#endregion

其中 OnEvent_XX 对应的都是 Event 请求的子类型。

第三步:写3行关键代码

在已经创建好的 WeixinController.cs 中,加入如下代码:

[HttpPost]
[ActionName("Index")]
public ActionResult Post(PostModel postModel)
{
    if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel. Nonce, Token))
    {
        return Content("参数错误!");
    }

    postModel.Token = Token;
    postModel.EncodingAESKey = EncodingAESKey;//根据自己后台的设置保持一致
    postModel.AppId = AppId;//根据自己后台的设置保持一致

    var messageHandler = new CustomMessageHandler(Request.InputStream, postModel); //接收消息(第一步)

    messageHandler.Execute();//执行微信处理过程(第二步)

    return new FixWeixinBugWeixinResult(messageHandler);//返回(第三步)
}

如果你不需要进行保存消息日志等操作,这一步也几乎可以通过复制完成,不需要修改任何东西。当然即使需要保存日志,我们的 Demo 中也已经有相关案例可以直接使用。

上述代码中的 FixWeixinBugWeixinResult 用于提供给 MVC 一个处理一些微信官方疏忽的问题或者由于跨平台导致的字符识别问题的修正方法,使所有手机平台都可以得到一致、稳定的结果。这个方法需要使用到 Senparc.Weixin.MP.MvcExtension.dll。

至此我们已经使用 MassageHandler 处理所有微信用户发送过来的请求。

点击订购:《微信开发深度解析:微信公众号、小程序高效开发秘籍

图片描述

2017-01-11 11:19:22 qq_36671474 阅读数 403
  • 微信公众号开发6-事件开发管理-微信开发php

    微信公众平台开发之事件开发管理是子恒老师《微信公众平台开发》视频教程的第6部。详细讲解了用php开发微信,对微信公众平台中的常见事件管理开发。内容包含微信关注事件,取消关注事件等等,其它的事件会在相应的章节中详细讲述。欢迎反馈,微信/QQ:68183131

    4490 人正在学习 去看看 秦子恒

最近这两天,在任何时候打开任意一个IT网站,都能在显著位置看到关于微信开发的文章,相信不少读者也关注了其中一些;由此可以肯定的一点是:大家对微信这一平台是非常关注的;相信很多人也都想基于这一平台去做一些事情,当你看到这篇文章的时候,希望能给眼前的你更多实践性的参考,也希望大家能谈谈自己的看法>>>>>>>>

1、微信开发介绍

1.1  微信开发网址

网址:https://open.weixin.qq.com

有兴趣的朋友可以打开网址看下微信开发的种类什么的

1.2  微信开发种类

1.2.1  移动应用(Native)开发

接入微信开放平台,让你的应用支持微信分享、微信收藏和微信支付。

举例:

①  现在在IOS和Android上有款应用叫做【开发者头条】,你阅读文章列表的某篇文章时,如果你觉得不错,可以收藏到微信中,或者分享到你的微信好友或者朋友圈;

②  我们使用京东或者美团进行商品购买后,可以使用微信进行支付,这些功能的实现就是做IOS、Andrdid开发人员使用OC、Java来结合微信的开发包来实现的;

具体可以到官网上点击微信开发平台来了解更多噢!

1.2.2  网站应用(Website)开发

接入微信开放平台,让你的网站支持使用微信账号来登陆。

优点:

省得你输入一堆的注册信息或者登陆信息,降低了注册门槛,给用户提供更多的方便;

具体可以到官网上点击微信开发平台来了解更多噢!

1.2.3  公众账号开发

接入微信开放平台公众账号开发,为亿万用户提供轻便的服务。

微信账号种类:

①  个人账号

个人注册,门槛较低,主要用于建立朋友圈,在自己的朋友圈范围内进行分享/聊天等。

②  公众账号

注册需要严格的审核,因为公众账号要作为一个具有广泛传播的这么一个平台,所以肯定审核严格。如果是企业,需要组织机构代码、法人信息等;如果是个人,需要身份证信息、银行信息等;如果是事业单位,需要提供法律文件等;

举例:

⑴  假如我是个人开发者,精通Android、IOS、Java、嵌入式、Web开发,平时喜欢分享一些开发经验在朋友圈,慢慢就觉着传播范围太受限制(必须是好友),于是,你就可以注册一个公众账号,每周写几篇文章,通过公众账号,下发给关注我、关注技术的人。

⑵  假如你是招商银行,为了方便客户进行业务查询/办理,可以申请一个公众账号,然后做一些开发,让客户能够关注公众账号,进行余额查询。业务办理等。

1.2.4  公众号第三方平台开发

成为公众号第三方平台,为广大公众号提供运营服务和行业解决方案。

举例:

假如你开了一家餐厅,你的朋友开了一个家具厂,你俩想让生意更红火,也想借着微信来推广,但是自己又不懂技术,这个时候就可以借助【微信第三方平台】进行公众号管理/顾客关系经营(抽奖、促销、会员管理等)

1.3  公众账号之详细介绍

1.3.1  种类有哪些呢?

详情请看官网:https://mp.weixin.qq.com/

种类:

订阅号:订阅号都在一个文件夹内放着

服务号:服务号和微信的好友在一个列表当中

企业号:企业号主要用于公司内部通讯使用的 

1.3.2  有什么区别呢?

①  订阅号

主要偏向于为用户传达资讯(类似报纸杂志),认证前后每天只可以群发一条消息;

(个人一般注册订阅号)

②  服务号

主要偏向于服务交互(类似银行,114等提高服务查询),认证前后每月可群发四条消息;

(个人不能注册,需要资质),经过认证的服务号可以调用全部九大类微信接口和微信支付。

③  企业号

主要用于公司内部通讯使用,需要先有成员的通讯验证信息才可以成功关注企业号;

温馨提示:

⑴  如果想简单的发送消息,达到宣传效果,建议你选择订阅号;

⑵  如果像进行商品销售,商品售卖,建议你可申请服务号;

⑶  如果想用来管理内部企业员工,团队,对内使用的话,可申请企业号;

1.3.3  十大类接口

•  语音识别接口(stt 将语音转化为文本)

•  客服接口(如果用户给公众号发送了消息,在24小时之内 可以给用户回复消息)

•  OAuth2.0网页授权接口(微信的第三方登录)

•  生成带参数的二维码接口(推广活动)

•  获取用户地理位置接口(拿到你的位置)

•  获取用户基本信息接口

•  获取关注着列表接口

•  用户分组接口

•  上传下载多媒体文件接口

•  微信支付接口(只允许经过验证的服务号才能够调用成功,否则都是无法调用。)

1.4  公众账号→订阅号开发基本步骤(商业开发)

①  购买一个一级域名,必须通过备案(将域名解析到DNS解析到云空间地址);

②  申请或购买主机空间(互联网可以访问),用于保存网页的;

③  注册公众账号(个人订阅号);

④  登陆公众账号,修改/维护个人订阅账号;

⑤  编写代码,调用微信平台提供的九大类接口;

个人推荐几个域名交易网站:

https://wanwang.aliyun.com/domain/

http://godaddy.com/

http://dnspod.com/

主机空间:

阿里云、亚马逊云(AWS)、腾讯云

1.5  公众账号→订阅号开发基本步骤(测试开发)

①  申请或购买主机空间(互联网可以访问),用于保存网页的;

②  申请测试用的公众账号(个人订阅号);

③  编写代码,调用微信平台提供的九大类接口;

2、公众号调用JS,SDK的步骤(个人订阅号)

步骤1:绑定域名(商业开发、测试开发都得绑定)
步骤2:引入微信所提供的js文件
步骤3:config(debug、timestamp、signature、jsApiList)
步骤4:wx.ready 调用微信所提供的接口
步骤5:error 进行失败的异常处理

jssdk的使用文档url:

https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN


基于sample调用jssdk步骤

①  sample.php中 填写对应的appID、appsecret

②  将ticket、token这两个php文件传到新浪云中的bucket

③  修改jssdk.php中访问文件的方式

saestor://mybucket/...

④  将要使用的接口在config的jsApiList声明一下

⑤  在wx的ready中的回调函数中可以直接调用api


2017-07-13 15:18:02 Francis123580 阅读数 516
  • 微信公众号开发6-事件开发管理-微信开发php

    微信公众平台开发之事件开发管理是子恒老师《微信公众平台开发》视频教程的第6部。详细讲解了用php开发微信,对微信公众平台中的常见事件管理开发。内容包含微信关注事件,取消关注事件等等,其它的事件会在相应的章节中详细讲述。欢迎反馈,微信/QQ:68183131

    4490 人正在学习 去看看 秦子恒

背景

由于项目中要实现对关注公众号的用户实现定制消息推送,所以需要进行微信开发

 

订阅号 · 服务号 · 小程序 · 企业微信

1.进入微信公众号平台,可以申请公众号:https://mp.weixin.qq.com/
2.当我们选择注册的时候,会有4个选择

这里写图片描述

它们各自的侧重点是不同的,从开发角度,简单来说明一下(详细情况百度就好)

订阅号的功能是向用户推送消息,每天可以群发1条消息
在进行认证之后可以自定义添加菜单,添加跳转url,但是一些高级开发接口没有开放,所以关于用户信息,交易这部分的功能是没有的

服务号的功能是向用户提供服务,每月只能发送4条消息
服务号可以进行高级功能的开发,用户管理,交易,语音,地理什么的

企业微信,也就是之前的企业号,主要为企业内部提供服务,它需要用户关注,填写信息,同时管理员需要进入企业微信后台,把用户添加到通讯录中,双方认证,这样,用户才能收到企业信息

小程序,是一种不需要下载安装即可使用的应用,用户通过扫一扫或者搜索即可使用。开发的时候需要我们把自己的页面上传到腾讯云端服务器,然后调用自己服务器上的相关接口。


简单来说,订阅号是来发布消息的,服务号是用来开发提供服务的,它们都是对外的公众号,关注即可
企业微信是企业内部使用的,相比于订阅号和服务号,需要后端添加用户;小程序则是网页版的app了

 

公众号平台 开发区域

这里写图片描述

现在仅作了解,正式开发的时候仔细研究就好,多看看开发者文档会有很大的帮助。

 

测试号开发

这里写图片描述

这里值得一提的是开始的时候我们可能没有服务号,或者接口权限不全,或者在开发公司服务号之前需要先进行一系列的测试,写一些demo

这时候,就可以进入 【开发者工具】 - 【公众平台测试账号】,进行各种测试开发

 

web开发者工具

这里写图片描述

因为我们进行微信端的开发,经常会在电脑和手机端切换,调试自己的程序,不是很方便

这款工具就在【开发者工具】 - 【web开发者工具】,它可以在电脑端模仿手机访问

这里写图片描述

开始的时候,直接输入网址,会出现这个问题。是因为它模仿手机登录,需要有一个绑定一个微信号进行模仿。
解决办法就是进入公众号平台的开发者工具,把自己的微信号绑定到上面就可以测试了

 

小结

开始的时候知道微信开发的一些基本知识,知道要开发什么,开发环境,开发工具,开发文档

了解原理流程之后,然后就是各种测试,最终根据项目的需求实现相应的功能

JAVA微信开发总结

阅读数 593

没有更多推荐了,返回首页