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();
for (int i = ; 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 = ; 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 - ? "\"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(,) + "'";
DataSet ds = DBHelperSQL.Query(sql, DBHelperSQL.GetDBString(), );
List<NewsList> list = new List<NewsList>();
foreach (DataRow Row in ds.Tables[].Rows)
{
NewsList nlist = new NewsList(); DownloadToLocal(Row["jumpurl"].ToString()); //下载文件到本地 string coverImg = "D:\\test\\" + Row["jumpurl"].ToString().Substring(Row["jumpurl"].ToString().LastIndexOf("/") + );
// 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 = ; }
//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
ASP.NET实现微信功能(2)(服务号高级群发)的更多相关文章
- ASP.NET实现微信功能(1)(创建菜单,验证,给菜单添加事件)
LZ实在 不知道怎么起名字了,索性就取了这个名字,开始吧,说实在的,想给自己的平常的学习做一个总结,总是忘了总结.也只能给工作做一个总结了. 我打算用2篇文章来写,第一篇是关于订阅号的,就是这个号,另 ...
- asp.net微信开发第七篇----高级群发(图文)
上一篇介绍了如何群发文本消息,本篇将介绍如何群发图文信息,上传图文信息所需的素材,界面如下: 我们先看从素材库中获取图文素材的代码,界面: 素材列表,我是使用的repeater控件, 前台代码如下: ...
- asp.net微信开发第六篇----高级群发(文本)
说到高级群发,微信的参考资料http://mp.weixin.qq.com/wiki/14/0c53fac3bdec3906aaa36987b91d64ea.html 首先我们先来讲解一下群发文本信息 ...
- 升讯威微信营销系统开发实践:订阅号和服务号深入分析( 完整开源于 Github)
GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction因为个人精力时间有限,不会再对现有代码进行更新维护,不过微信接口比较稳定,经测试至 ...
- 用c#开发微信 (19) 公众平台接口权限列表说明 - 订阅号、服务号认证后的区别
最新发现有些原来认证服务号的权限对认证的订阅号开放了,这里是官方的文档说明<公众平台接口权限列表说明>,明显比这里说得详细.准确多了<微信公众平台服务号.订阅号的相关说明>.另 ...
- ASP程序写的项目与微信服务号(公众号)完美结合。仅需一个DLL组建WeixinDLL
因ASP程序开发有很多优点,早年间ASP风靡全球,因此如今还在继续运营的ASP开发的项目仍在运行着,但是随着社交网络不断发达,特别是微信支付.微信通讯.小程序等的出现,导致很多ASP项目对接起来就比较 ...
- ASP微信服务号H5客户登陆,且获取客户授权的用户基本信息
ASP微信服务号H5客户登陆,且获取客户授权的用户基本信息是需要客户授权,下面讲解详细步骤: 第一步:客户点击登录页,自动跳转到微信服务器端获取code 第二步:用第一步获取的code去获取客户的ac ...
- ASP.NET MVC4 微信公众号开发之网页授权(一):搭建基础环境
首先你得注册并认证一个个人或企业的微信公众号===服务号从而确保获得以下接口权限: 然后打开公众号设置里的功能设置里找到业务域名和网页授权域名分别填上你的域名(注:已备案的域名),如下图所示: 到这里 ...
- 微信服务号模板消息接口新增"设置行业"和"添加模板"及细节优化
微信服务号模板消息可以向用户发送重要的服务通知,如信用卡刷卡通知,商品购买成功通知等.昨日,微信团队发布公告称模板消息新增“设置行业”和“添加模板”接口及细节优化,详细变动如下 模板消息[业务通知]自 ...
随机推荐
- *HDU1907 博弈
John Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submis ...
- JS 的事件委托机制
以前写上图所示的鼠标点击触发事件,一般都是用如下所示的给每一个表示列表的标签绑定一个click事件(演示用的例子的框架是React): 毫无疑问,这样是比较繁琐的,以后维护修改改个函数名什么的还不方便 ...
- opengles 矩阵计算
总的变换矩阵: matrix = projection * view * model 模型矩阵: modelMatrix=translateMatrix * scaleMatrix * rotateM ...
- CSS 重设文章
CSS 重设 http://blog.bingo929.com/css-reset-collection.html
- JS简介,如何快熟JS。打下结实基础。
JS决定网页的行为,有行为就有逻辑,而计算机只是人工智能,你给它什么样的指令,它就会按照你的指令去运行. 有人会问,既然是给出指令,那还需要什么逻辑? 这里我举一个简单的小例子来说明一下! 到你想输入 ...
- ASP.NET跨平台实践:无需安装Mono的Jexus“独立版”
在Linux上运行ASP.NET网站或WebApi的传统步骤是,先安装libgdiplus,再安装mono,然后安装Jexus.在这个过程中,虽然安装Jexus是挺简便的一件事,但是安装mono就相对 ...
- MSBuild的简单介绍与使用
MSBuild 是 Microsoft 和 Visual Studio的生成系统.它不仅仅是一个构造工具,应该称之为拥有相当强大扩展能力的自动化平台.MSBuild平台的主要涉及到三部分:执行引擎.构 ...
- Android应用安全开发之浅谈网页打开APP
一.网页打开APP简介 Android有一个特性,可以通过点击网页内的某个链接打开APP,或者在其他APP中通过点击某个链接打开另外一个APP(AppLink),一些用户量比较大的APP,已经通过发布 ...
- iOS开发系列—Objective-C之内存管理
概述 我们知道在程序运行过程中要创建大量的对象,和其他高级语言类似,在ObjC中对象时存储在堆中的,系统并不会自动释放堆中的内存(注意基本类型是由系统自己管理的,放在栈上).如果一个对象创建并使用后没 ...
- Step by Step 创建一个WCF Service
原创地址:http://www.cnblogs.com/jfzhu/p/4025448.html 转载请注明出处 (一)创建WCF Service (1)创建WCF Service类库 创建一个Cla ...