C#开发微信门户及应用(19)-微信企业号的消息发送(文本、图片、文件、语音、视频、图文消息等)

我们知道,企业号主要是面向企业需求而生的,因此内部消息的交流显得非常重要,而且发送、回复消息数量应该很可观,对于大企业尤其如此,因此可以结合企业号实现内部消息的交流。企业号具有关注安全、消息无限制等特点,很适合企业内部的环境。本文主要介绍如何利用企业号实现文本、图片、文件、语音、视频、图文消息等消息的发送操作。

1、企业号特点

对于企业号,有以下一些特点:
1)关注更安全
–只有企业通讯录的成员才能关注企业号,分级管理员、保密消息等各种特性确保企业内部信息的安全。
企业可以设置自行验证关注者身份,进行二次安全验证,保证企业信息使用和传递安全。
若员工离职,企业管理员可在通讯录中删除该成员,该成员即自动取消关注企业号,同时微信中的企业号历史记录也会被清除。
2)应用可配置
–企业可自行在企业号中可配置多个服务号,可以连接不同的企业应用系统,只有授权的企业成员才能使用相应的服务号。
3)消息无限制
–发送消息无限制,并提供完善的的管理接口及微信原生能力,以适应企业复杂、个性化的应用场景。
企业可以主动发消息给员工,消息量不受限制
4)使用更便捷
–企业号在微信中有统一的消息入口,用户可以更方便地管理企业号消息。微信通讯录也可以直接访问企业号中的应用。

2、企业号的管理接口内容

目前企业号的内容可以用下面的分层图来展示,分别包含素材管理、被动响应消息、通讯录管理、自定义菜单等内容,详细可以看下面图示。


3、企业号消息和事件的处理

企业号和公众号一样,可以分为消息处理和事件处理,下面是他们两种类型的处理操作,也就发送的消息有文本消息、图片消息、文件消息、视频消息、语音消息、地理文字消息、图文和多媒体消息等。
事件处理主要就是关注、取消关注事件,以及菜单click类型和view类型两种操作,还有就是地理位置上报事件等。
两种类型的处理图如下所示。


4、企业号消息管理

在企业的管理后台,和公众号一样,可以看到对应信息交流记录,包括文字、图片、地理位置等等,如下所示。



由于消息分为几种类型,包括文本(Text)、图片(Image)、文件(File)、语音(Voice)、视频(Video)、图文消息等(News)、MpNews等。
因此我们需要分别对它们进行一定的定义和封装处理,如下是它们的信息对象设计图。


企业号发送消息的官方定义如下:
企业可以主动发消息给员工,消息量不受限制
调用接口时,使用Https协议、JSON数据包格式,数据包不需做加密处理。
目前支持文本、图片、语音、视频、文件、图文等消息类型。除了news类型,其它类型的消息可在发送时加上保密选项,保密消息会被打上水印,并且只有接收者才能阅读。

我们以发送的文本消息为例进行说明,它的定义如下所示。
text消息

{
   "touser": "UserID1|UserID2|UserID3",
   "toparty": " PartyID1 | PartyID2 ",
   "totag": " TagID1 | TagID2 ",
   "msgtype": "text",
   "agentid": "1",
   "text": {
       "content": "Holiday Request For Pony(http://xxxxx)"
   },
   "safe":"0"
}

其中每种消息都会包含以下消息所示,也就是它们共同的属性:

touser": "UserID1|UserID2|UserID3",
"toparty": " PartyID1 | PartyID2 ",
"totag": " TagID1 | TagID2 ",
"msgtype": "text",
"agentid": "1",

因此我们可以定义一个基类用来方便承载这些共同的信息。

/// <summary>
/// 企业号发送消息的基础消息内容
/// </summary>
public class CorpSendBase
{      
    /// <summary>
    /// UserID列表(消息接收者,多个接收者用‘|’分隔)。特殊情况:指定为@all,则向关注该企业应用的全部成员发送
    /// </summary>
    public string touser { get; set; }

    /// <summary>
    /// PartyID列表,多个接受者用‘|’分隔。当touser为@all时忽略本参数
    /// </summary>
    public string toparty { get; set; }

    /// <summary>
    /// TagID列表,多个接受者用‘|’分隔。当touser为@all时忽略本参数
    /// </summary>
    public string totag { get; set; }

    /// <summary>
    /// 消息类型
    /// </summary>
    public string msgtype { get; set; }

    /// <summary>
    /// 企业应用的id,整型。可在应用的设置页面查看
    /// </summary>
    public string agentid { get; set; }

    /// <summary>
    /// 表示是否是保密消息,0表示否,1表示是,默认0
    /// </summary>
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public string safe { get; set; }

}

然后其他消息逐一继承这个基类即可,如下所示。



最终会构成下面这个继承关系图。


5、消息接口的定义和实现

定义好相关的发送对象后,我们就可以定义它的统一发送接口了,如下所示。

/// <summary>
/// 企业号消息管理接口定义
/// </summary>
public interface ICorpMessageApi
{        
    /// <summary>
    /// 发送消息。
    /// 需要管理员对应用有使用权限,对收件人touser、toparty、totag有查看权限,否则本次调用失败。
    /// </summary>
    /// <param name="accessToken"></param>
    /// <returns></returns>
    CommonResult SendMessage(string accessToken, CorpSendBase data);
}

最终,文本等类型的消息会根据接口定义进行实现,实现代码如下所示。注意,发送过程不需要调用加密类进行加密。

/// <summary>
/// 企业号消息管理实现类
/// </summary>
public class CorpMessageApi : ICorpMessageApi
{
    /// <summary>
    /// 发送消息。
    /// 需要管理员对应用有使用权限,对收件人touser、toparty、totag有查看权限,否则本次调用失败。
    /// </summary>
    /// <param name="accessToken"></param>
    /// <returns></returns>
    public CommonResult SendMessage(string accessToken, CorpSendBase data)
    {        
        CommonResult result = new CommonResult();

        string urlFormat = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={0}";
        var url = string.Format(urlFormat, accessToken);
        var postData = data.ToJson();

        //数据不用加密发送
        CorpSendResult sendResult = CorpJsonHelper<CorpSendResult>.ConvertJson(url, postData);
        if (sendResult != null)
        {
            result.Success = (sendResult.errcode == CorpReturnCode.请求成功);
            result.ErrorMessage = string.Format("invaliduser:{0},invalidparty:{1},invalidtag:{2}",
                sendResult.invaliduser, sendResult.invalidparty, sendResult.invalidtag);
        }

        return result;
    }
}

6、消息的发送操作和实际效果

定义好相应的发送对象后,我们就可以进行统一的消息发送操作,包括文本、图片、文件、语音等等类型的消息,注意有些消息是需要上传到服务器上,然后在根据mediaId进行发送出去的。

发送文本和图片的操作代码如下所示。

private void btnSendText_Click(object sender, EventArgs e)
{
    //发送文本内容
    ICorpMessageApi bll = new CorpMessageApi();

    CorpSendText text = new CorpSendText("API 中文测试(http://www.iqidi.com)");
    text.touser = "wuhuacong";
    text.toparty = "4";//部门ID
    text.totag = "0";

    text.safe = "0";
    text.agentid = "0";

    CommonResult result = bll.SendMessage(token, text);
    if (result != null)
    {
        Console.WriteLine("发送消息:{0} {1} {2}", text.text.content, (result.Success ? "成功" : "失败"), result.ErrorMessage);
    }
}
private void btnSendImage_Click(object sender, EventArgs e)
{
    btnUpload_Click(sender, e);

    if (!string.IsNullOrEmpty(image_mediaId))
    {
        //发送图片内容
        ICorpMessageApi bll = new CorpMessageApi();

        CorpSendImage image = new CorpSendImage(image_mediaId);
        CommonResult result = bll.SendMessage(token, image);
        if (result != null)
        {
            Console.WriteLine("发送图片消息:{0} {1} {2}", image_mediaId, (result.Success ? "成功" : "失败"), result.ErrorMessage);
        }
    }
}

最后在微信企业号上截图效果如下所示,包括了文本测试、文件测试、图文测试、语音测试均正常。



如果对这个《C#开发微信门户及应用》系列感兴趣,可以关注我的其他文章

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容