zoukankan      html  css  js  c++  java
  • ASP.NET实现微信功能(2)(服务号高级群发)

    前面写了一篇文章,关于微信的:http://www.cnblogs.com/kmsfan/p/4047097.html

    今天打算来写本系列的第二批文章,服务号后台群发。

    在写本篇文章之前,我们先来看看腾讯的后台群发是怎么实现的,因为我们无论做什么事情都要知道原理。开始吧。

    由于本人的奉献精神,等下回把实现源码的框架全部公开,里面什么东西都有,由于自己才识浅薄,只弄了图文消息的群发,那么今天只会介绍图文消息的群发。

    框架的源码文章最后会提到,这本来是一个开源的框架,经过一些大神的二次修改而更加的完善。

    由于可以群发多条消息,那么我们今天就来说说服务号的后台群发(多篇文章)。

    我们来分析一下,上面的图 :标题,封面,正文,这3项在微信里填写是必须的,也就是说,我们如果要从后台C#去推送消息,那么这3项肯定也是必须的。

    但是够了吗?不够,我们群发可以根据组去群发,也可以对所有人群发,对吧?

    那么这里的人,就是我们的粉丝,每个粉丝在微信里有一个唯一的东西,那就是ID,我们需要获得那些要推送的人的IDS,那样才可以发送。

    另外跟大家说一下,微信的接口调用每天是100次,但是群发一周是一次,也就是说,如果你群发成功了多次,也只会以第一次的群发的消息为准。

    好了,做了这么多的准备工作,大家也有点迫不及待了吧?!那我们就开始研究代码吧。

    我用的是一个开源的微信框架,其中的EXTENSION是某位大神写的,我们这次只研究群发功能SendNews.因为我自己只做了群发。

    其中填写APPID 和APPSECRET的地方在REQUEST下的AccessTokenGetRequest.cs文件里,大家可以把这些写在配置文件里哦

    我们先来研究一下这个SendUser方法,首先我们需要明白的一点是这下面的几个参数的含义,

    1.data :就是你要传递的图文消息的集合,这个稍后会提到。

    2.userIDList:粉丝的ID。

    3.msgType:是否图文消息

    4.accesstoken,这个是凭证,不用我多说了,

    5.impclient:框架自带的东西,具体的我没研究,大家有兴趣的自己去研究

    大家看过官方的文档的都知道,其实我们是向那个调用的接口发送一段规定格式的XML。

    那么下面也基本上是拼接好规定格式的字符串。

    其中大家注意到了一个东西,那就是media_Id,这个东西怎么获得呢?

    这个东西其实就是我们上传的封面图片之后,然后服务器返回给我们的ID,这个ID是必须的。

            private static string accessToken;
            private static IMpClient mpClient;
    
            public static string SendUser(object data, List<string> UserIDList, bool msgType, string accessToken, IMpClient mpClient)
            {
                SendNews.accessToken = accessToken;
                SendNews.mpClient = mpClient;
                StringBuilder postData = new StringBuilder("{");
                postData.AppendFormat(""touser":{0},", JsonConvert.SerializeObject(UserIDList));
                if (msgType)
                {
                    var msgId = UpdateNews(data as List<Model.NewsList>);
                    if (string.IsNullOrEmpty(msgId)) { return "-1"; }
                    postData.Append(" "mpnews":{  "media_id":"" + msgId + ""},"msgtype":"mpnews"");
                }
                else
                {
                    postData.Append(""msgtype": "text","text": { "content":"" + data.ToString() + ""}}");
                }
                var rdata = HttpHelper.Example.GetWebData(new BrowserPara()
                {
                    Uri = string.Format("https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token={0}", accessToken),
                    PostData = postData.ToString()
                });
                return !HasError(rdata) ? Tools.GetJosnValue(rdata, "errcode") : "-1";
            }

    下面我们来看一下这个updateNews 方法,然后我再带大家看看实体类,就是这个newsList.

    下面是实体类

    其中有几点大家要注意:

    1.NID:就是点击微信文章进去后的超链接地址,就相当于你要建立一个Preview页面,这个页面是任何人可以访问的,然后这个页面带的ID不同,显示不同的文章。

    2.CoverImage:这个是封面图片的地址,注意:微信只接受 本地图片,不接受IIS地址,所以你先要把IIS上的文件下载到本地,然后再从本地上传。

    3.其他的没注释掉的,是不能删除的,否则会报空指针异常,比如SUMMARY,大家可以 根据需求酌情修改。

    namespace Model
    {
        using System;
        using System.Collections.Generic;
        
        public partial class NewsList
        {
            public string  NID { get; set; }
            public string Title { get; set; }
            public string CoverImage { get; set; }
            public string NContent { get; set; }
            public string Summary { get; set; }
           // public int nType { get; set; }
           // public bool Marking { get; set; }
            public System.DateTime AddTime { get; set; }
            //public bool isDel { get; set; }
        }
    }

    下面是UpdateNews方法。大家看看就好,反正就是从object data里,也就是newsList里面遍历数据。

            #region 2.0 上传图文新闻 static string UpdateNews(List<Model.ViewModel.NewsListEditModel> newsList)
            /// <summary>
            /// 上传图文新闻
            /// </summary>
            /// <param name="newsList"></param>
            /// <returns></returns>
            public static string UpdateNews(List<Model.NewsList> newsList)
            {
    
    
                StringBuilder postData = new StringBuilder(512);
                for (int i = 0; i < newsList.Count; i++)
                {
                    UploadMediaRequest request = new UploadMediaRequest()
                    {
                        AccessToken = accessToken,
                        Type = "image",
                        FileName = newsList[i].CoverImage
                    };
                    UploadMediaResponse response = mpClient.Execute(request);
                    if (!response.IsError)
                    {
                        newsList[i].CoverImage = response.MediaId;
                    }
                    else
                    {
                        return string.Empty;
                    }
    
                }
                postData.Append("{"articles": [");
                for (int j = 0; j < newsList.Count; j++)
                {
                    postData.Append("{");
                    postData.AppendFormat(" "thumb_media_id":"{0}",", newsList[j].CoverImage);
                    postData.AppendFormat(" "title":"{0}",", newsList[j].Title.Replace(""", "").Replace("'", ""));
                    postData.AppendFormat(" "content_source_url":"{0}",", newsList[j].NID);
                    postData.AppendFormat(" "content":"{0}",", newsList[j].Summary.Replace(""", "").Replace("'", ""));
                    postData.AppendFormat(" "digest":"{0}",", newsList[j].Summary.Replace(""", "").Replace("'", ""));
                    postData.Append(j == newsList.Count - 1 ? ""show_cover_pic":"1"}" : ""show_cover_pic":"1"},");
                }
    
                postData.Append("]}");
    
                var rdata = HttpHelper.Example.GetWebData(new BrowserPara()
                     {
                         Uri = string.Format("https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token={0}", accessToken),
                         PostData = postData.ToString()
                     });
    
                return !HasError(rdata) ? Tools.GetJosnValue(rdata, "media_id") : string.Empty;
            }

    下面最后再来介绍一下调用,如果你是4.0的框架,可以不用往下面看了,因为下面的是基于4.0以下的框架的调用方法。

    我这里用的是WebService去调用,因为网站是2.0的,而框架是4.0的。

    首先第一步,我们必须引用这个项目,我为了方便,引用的是解决方案,大家如果要发布的话,会自动生成DLL文件的,这个不必担心。

    下面的是方法,如果ReturnVal最后的值是0的话,恭喜你,操作成功!

    方法是先得到关注者的IDS,然后遍历List,把数据填充到List里面去,如果 你的opeNID能取到所有关注者的IDS那么就成功了。

       [WebMethod(Description = "处理微信群发功能", EnableSession = true)]
            public string ProcessWeiXinGroupPush()
            {
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                SysBaseTag sysbase = new SysBaseTag();
                string temp = "";
                Mobile_msg msg = new Mobile_msg();
                sysbase.data = new List<object>();
    
                //得到关注着的IDLIST;
                var idlist = new List<string>();
    
                //得到关注着的IDS
                var uidRequest = new GetAttentionsRequest() 
                { 
                AccessToken=OperateContextMP.Current.GetAccessToken.AccessToken.AccessToken
                };
    
                var createResponse = OperateContextMP.Current.MpClient.Execute(uidRequest);
    
                if (createResponse.IsError)
                {
    
                }
                else
                {
                    idlist = createResponse.Attentions.data.opeNID;
                
                }
    
                try
                {
                    string sql = "select * from cms_core_content a,CMS_EXT_NEWS b,CMS_WECHAT c where a.ID=b.ID and c.newsid=b.ID and c.datetime='" + DateTime.Now.ToShortDateString().Substring(0,10) + "'";
                    DataSet ds = DBHelperSQL.Query(sql, DBHelperSQL.GetDBString(), 2);
                    List<NewsList> list = new List<NewsList>();
                    foreach (DataRow Row in ds.Tables[0].Rows)
                    {
                        NewsList nlist = new NewsList();
    
                        DownloadToLocal(Row["jumpurl"].ToString()); //下载文件到本地
    
                        string coverImg = "D:\test\" + Row["jumpurl"].ToString().Substring(Row["jumpurl"].ToString().LastIndexOf("/") + 1);
                       // string mapPath = "http://localhost/"
                        nlist.Title = Row["title"].ToString();
                        nlist.NContent = Row["text"].ToString();
                        nlist.NID = Row["id"].ToString();
                        nlist.CoverImage = coverImg;
                        // nlist.summary = "测试推送"; //暂时先这么写
                        nlist.Summary = Row["title"].ToString(); //描述:必填项
                        list.Add(nlist);
                        sysbase.data.Add(nlist);
                       
    
                    }
    
                    sysbase.message = "成功";
                    sysbase.result = true;
                    sysbase.count = sysbase.data.Count;
    
                    //从数据库中获取图文消息并添加
                     var newsList = new List<NewsList>();
                    string returnVal = SendNews.SendUser(list, idlist, true, OperateContextMP.Current.GetAccessToken.AccessToken.AccessToken, OperateContextMP.Current.MpClient);
    
                     temp = returnVal;
    
                }
                catch (Exception e)
                {
                    sysbase.message = e.Message;
                    sysbase.result = false;
                    sysbase.count = 0;
    
                }
                //return serializer.Serialize(sysbase);
                return temp;
            }

    大家还要注意下,封面必须下载到本地,这里我的图片本来是在IIS中的,建议封面图片专门用一个字段去存储。

            //下载服务器上的封面文件保存到本地机器上。
            public void DownloadToLocal(string filePath)
            {
    
                string filePath_ = ConfigurationManager.AppSettings["basicIP"] + filePath;
    
    
                //在D盘新建一个TEST目录
                WebClient wc = new WebClient();
                string path = @"D:WX_ESP_PIC";
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
    
                wc.DownloadFile(filePath_, path+"\"+filePath_.Substring(filePath_.LastIndexOf("/")));
            }

    好了,说了这么多,下面的是框架源码。

    大家拿去用就是的了。

    http://pan.baidu.com/s/1c0Chn3a 

    提取码:peye

  • 相关阅读:
    3D Bezier Curve, Matlab Code
    Matlab Bezier
    python与matlab混合编程
    Matlab P文件——加快Matlab程序,保护你的算法(z)
    Simens NX (原UG)内部代码逆向分析 / Inner code Reverse analysis of NX software
    Matlab扩展编程
    《数值分析及其MATLAB实现》(任玉杰)扫描版[PDF]
    NURBS Toolbox by D.M. Spink (matlab)
    贝塞尔曲线
    BSpline & NURBS (Matlab Code)
  • 原文地址:https://www.cnblogs.com/kmsfan/p/4058227.html
Copyright © 2011-2022 走看看