C#开发微信门户及应用(12)-使用语音处理
我们知道,微信最开始就是做语音聊天而使得其更加流行的,因此语音的识别处理自然也就成为微信交流的一个重要途径,微信的开发接口,也提供了对语音的消息请求处理。本文主要介绍如何利用语音的识别,对C#开发的微信门户应用的整个事件链的处理操作,使得在我们的微信账号里面,更加方便和多元化对用户的输入进行处理。
1、微信语音接口的定义0
微信的API这么定义语音的识别的:开通语音识别功能,用户每次发送语音给公众号时,微信会在推送的语音消息XML数据包中,增加一个Recongnition字段。
语音的消息格式如下所示。
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1357290913</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<MediaId><![CDATA[media_id]]></MediaId>
<Format><![CDATA[Format]]></Format>
<MsgId>1234567890123456</MsgId>
</xml>
| 参数 | 描述 |
|---|---|
| ToUserName | 开发者微信号 |
| FromUserName | 发送方帐号(一个OpenID) |
| CreateTime | 消息创建时间 (整型) |
| MsgType | 语音为voice |
| MediaId | 语音消息媒体id,可以调用多媒体文件下载接口拉取数据。 |
| Format | 语音格式,如amr,speex等 |
| MsgID | 消息id,64位整型 |
根据以上微信接口的定义,我们可以定义一个实体类来对消息的传递进行处理,如下所示。
/// <summary>
/// 接收的语音消息
/// </summary>
[System.Xml.Serialization.XmlRoot(ElementName = "xml")]
public class RequestVoice : BaseMessage
{
public RequestVoice()
{
this.MsgType = RequestMsgType.Voice.ToString().ToLower();
} /// <summary>
/// 语音格式,如amr,speex等
/// </summary>
public string Format { get; set; } /// <summary>
/// 语音消息媒体id,可以调用多媒体文件下载接口拉取数据。
/// </summary>
public string MediaId { get; set; } /// <summary>
/// 消息ID
/// </summary>
public Int64 MsgId { get; set; } /// <summary>
/// 语音识别结果,UTF8编码
/// </summary>
public string Recognition { get; set; } }
我们看到,这里我们最感兴趣的是语音的识别结果,也就是Recognition的字段,这个就是微信服务器自动根据用户的语音转换过来的内容,我测试过,识别率还是非常高的。
这个实体类,在整个微信应用的消息传递中的关系如下所示:

2、语音的处理操作
明确了上面的语音对象实体,我们就可以看看它们之间是如何处理的。
微信消息的处理逻辑如下图所示。

其中我们来看看语音的处理操作,我的代码处理逻辑如下所示。
/// <summary>
/// 对语音请求信息进行处理
/// </summary>
/// <param name="info">语音请求信息实体</param>
/// <returns></returns>
public string HandleVoice(Entity.RequestVoice info)
{
string xml = "";
// 开通语音识别功能,用户每次发送语音给公众号时,
// 微信会在推送的语音消息XML数据包中,增加一个Recongnition字段。
if (!string.IsNullOrEmpty(info.Recognition))
{
TextDispatch dispatch = new TextDispatch();
xml = dispatch.HandleVoiceText(info, info.Recognition);
}
else
{
xml = "";
} return xml;
}
在这里,我先看看,是否获得了微信的语音识别结果,如果获得,那么这个时候,就是和处理用户文本输入的操作差不多了,因此把它转给TextDispatch的处理类进行处理。
其中这里面的处理逻辑如下所示。

首先我根据识别结果,寻找是否用户读出了微信门户的菜单名称,如果根据语音结果找到对应的菜单记录,那么我们执行菜单事件(如果是URL的View类型菜单,我们没办法重定向到指定的链接,因此给出一个链接文本提示,给用户单击进入;如果没有找到菜单记录,那么我们就把语音识别结果作为一般的事件进行处理,如果事件逻辑没有处理,那么我们最后给出一个默认的语音应答提示结果就可以了。
具体的处理代码如下所示。
/// <summary>
/// 如果用户用语音读出菜单的内容,那么我们应该先根据菜单对应的事件触发,最后再交给普通事件处理
/// </summary>
/// <param name="info"></param>
/// <returns></returns>
public string HandleVoiceText(BaseMessage info, string voiceText)
{
string xml = "";
MenuInfo menuInfo = BLLFactory<Menu>.Instance.FindByName(voiceText);
if (menuInfo != null)
{
#region 如果找到菜单对象的处理
if (menuInfo.Type == "click")
{
//模拟单击事件
RequestEventClick eventInfo = new RequestEventClick();
eventInfo.CreateTime = info.CreateTime;
eventInfo.EventKey = menuInfo.Key;
eventInfo.FromUserName = info.FromUserName;
eventInfo.ToUserName = info.ToUserName; xml = base.DealEvent(eventInfo, eventInfo.EventKey);
}
else
{
//由于无法自动切换到连接,
//转换为连接文本供用户进入
string content = string.Format("请单击链接进入<a href=\"{0}\">{1}</a> ", menuInfo.Url, menuInfo.Name); ResponseText textInfo = new ResponseText(info);
textInfo.Content = content; xml = textInfo.ToXml();
}
#endregion
}
else
{
//交给事件机制处理
if (string.IsNullOrEmpty(xml))
{
xml = HandleText(info, voiceText);
}
} //最后如果没有处理到,那么提示用户的语音内容
if (string.IsNullOrEmpty(xml))
{
ResponseText textInfo = new ResponseText(info);
textInfo.Content = string.Format("非常抱歉,您输入的语音内容没有找到对应的处理方式。您的语音内容为:{0}", voiceText);
xml = textInfo.ToXml();
} return xml;
}
微信门户测试界面效果如下所示。


为了方便对客户会话的记录,我的微信门户后台,会记录用户的语音输入内容,如下所示。

当然,微信后台的管理界面,也能够查到相应的语音记录,界面如下所示。

以上就是我对微信语音的消息定义和事件处理的逻辑,其实语音是一个重要的输入,如果正确的识别内容,比手工输入的效果更好,给用户提供另外一种高效的输入和事件处理操作。
这样的处理模式,能够使得我们整个微信门户框架,不管是对于用户的语音输入,还是文本输入,还是菜单事件的处理,都可以融为一体,实现更加完美的衔接。
如果对这个《C#开发微信门户及应用》系列感兴趣,可以关注我的其他文章,系列随笔如下所示:
C#开发微信门户及应用(23)-微信小店商品管理接口的封装和测试
C#开发微信门户及应用(21)-微信企业号的消息和事件的接收处理及解密
C#开发微信门户及应用(19)-微信企业号的消息发送(文本、图片、文件、语音、视频、图文消息等)
C#开发微信门户及应用(18)-微信企业号的通讯录管理开发之成员管理
C#开发微信门户及应用(17)-微信企业号的通讯录管理开发之部门管理
C#开发微信门户及应用(15)-微信菜单增加扫一扫、发图片、发地理位置功能
C#开发微信门户及应用(14)-在微信菜单中采用重定向获取用户数据
C#开发微信门户及应用(11)--微信菜单的多种表现方式介绍
C#开发微信门户及应用(10)--在管理系统中同步微信用户分组信息
C#开发微信门户及应用(9)-微信门户菜单管理及提交到微信服务器
C#开发微信门户及应用(12)-使用语音处理的更多相关文章
- C#开发微信门户及应用(39)--使用微信JSSDK实现签到的功能
随着微信开逐步开放更多JSSDK的接口,我们可以利用自定义网页的方式来调用更多微信的接口,实现我们更加丰富的界面功能和效果,例如我们可以在页面中调用各种手机的硬件来获取信息,如摄像头拍照,GPS信息. ...
- C#开发微信门户及应用(25)-微信企业号的客户端管理功能
我们知道,微信公众号和企业号都提供了一个官方的Web后台,方便我们对微信账号的配置,以及相关数据的管理功能,对于微信企业号来说,有通讯录中的组织架构管理.标签管理.人员管理.以及消息的发送等功能,其中 ...
- C#开发微信门户及应用(38)--微信摇一摇红包功能
摇一摇周边红包接口是为线下商户提供的发红包功能.用户可以在商家门店等线下场所通过摇一摇周边领取商家发放的红包.我曾经在<C#开发微信门户及应用(28)--微信“摇一摇·周边”功能的使用和接口的实 ...
- C#开发微信门户及应用(37)--微信公众号标签管理功能
微信公众号,仿照企业号的思路,增加了标签管理的功能,对关注的粉丝可以设置标签管理,实现更加方便的分组管理功能.开发者可以使用用户标签管理的相关接口,实现对公众号的标签进行创建.查询.修改.删除等操作, ...
- C#开发微信门户及应用(36)--微信卡劵管理的封装操作
前面几篇介绍了微信支付方面的内容,本篇继续微信接口的一些其他方面的内容:卡劵管理.卡劵管理是微信接口里面非常复杂的一个部分,里面的接口非常多,我花了不少时间对它进行了封装处理,重构优化等等工作,卡劵在 ...
- C#开发微信门户及应用(35)--微信支付之企业付款封装操作
在前面几篇随笔,都是介绍微信支付及红包相关的内容,其实支付部分的内容还有很多,例如企业付款.公众号支付或刷卡支付.摇一摇红包.代金券等方面的内容,这些都是微信接口支持的内容,本篇继续微信支付这一主题, ...
- C#开发微信门户及应用(34)--微信裂变红包
在上篇随笔<C#开发微信门户及应用(33)--微信现金红包的封装及使用>介绍了普通现金红包的封装和使用,这种红包只能单独一次发给一个人,用户获取了红包就完成了,如果我们让用户收到红包后,可 ...
- C#开发微信门户及应用(33)--微信现金红包的封装及使用
我在上篇随笔<C#开发微信门户及应用(32)--微信支付接入和API封装使用>介绍为微信支付的API封装及使用,其中介绍了如何配置好支付环境,并对扫码支付的两种方式如何在C#开发中使用进行 ...
- C#开发微信门户及应用(32)--微信支付接入和API封装使用
在微信的应用上,微信支付是一个比较有用的部分,但也是比较复杂的技术要点,在微商大行其道的年代,自己的商店没有增加微信支付好像也说不过去,微信支付旨在为广大微信用户及商户提供更优质的支付服务,微信的支付 ...
随机推荐
- MJRefresh 源码解读 + 使用
MJRefresh这个刷新控件是一款非常好用的框架,我们在使用一个框架的同时,最好能了解下它的实现原理,不管是根据业务要求在原有的基础上修改代码,还是其他的目的,弄明白作者的思路和代码风格,会受益匪浅 ...
- windows环境redis主从安装部署
准备工作 下载windows环境redis,我下载的是2.4.5,解压,拷贝一主(master)两从(slaveof).主机端口使用6379,两从的端口分别为6380和6381, 我本地索性用6379 ...
- 移动应用App测试与质量管理一
测试工程师 基于Html的WebApp测试, 现在一些移动App混Html5 HTML5性能测试 兼容性 整理后的脑图 测试招聘 弱化大量技术考察 看重看问题的高度 看重潜力 测试经验 质量管理 专项 ...
- Android开发案例 – 在AbsListView中使用倒计时
在App中, 有多种多样的倒计时需求, 比如: 在单View上, 使用倒计时, 如(如图-1) 在ListView(或者GridView)的ItemView上, 使用倒计时(如图-2) 图-1 图-2 ...
- vim的一些常用命令(一)
先确认在Normal模式下,如不确认,请按几次Esc. :sy on/clear sy表示语法高亮,on是打开.clear是取消. :set go= set表示一般性设置,go是gui option的 ...
- HTML 学习笔记 JQuery(DOM 操作2)
接着上一节的将,这一节从复制节点讲起 复制节点 继续使用之前的例子 如果单击<li>元素后 需要在复制一个<li>元素,可以使用clone()方法完成.全部代码如下 <h ...
- 机器指令翻译成 JavaScript —— 终极目标
上一篇,我们顺利将 6502 指令翻译成 C 代码,并演示了一个案例. 现在,我们来完成最后的目标 -- 转换成 JavaScript. 中间码输出 我们之所以选择 C,就是为了使用 LLVM.现在来 ...
- XSS 前端防火墙 —— 无懈可击的钩子
昨天尝试了一系列的可疑模块拦截试验,尽管最终的方案还存在着一些兼容性问题,但大体思路已经明确了: 静态模块:使用 MutationObserver 扫描. 动态模块:通过 API 钩子来拦截路径属性. ...
- Netty构建分布式消息队列实现原理浅析
在本人的上一篇博客文章:Netty构建分布式消息队列(AvatarMQ)设计指南之架构篇 中,重点向大家介绍了AvatarMQ主要构成模块以及目前存在的优缺点.最后以一个生产者.消费者传递消息的例子, ...
- CSharpGL(25)一个用raycast实现体渲染VolumeRender的例子
CSharpGL(25)一个用raycast实现体渲染VolumeRender的例子 本文涉及的VolumeRendering相关的C#代码是从(https://github.com/toolchai ...