.NET微信公众号客服接口
程序员文章站
2023-11-25 13:40:16
本文实例为大家分享了微信公众号客服接口.net代码,供大家参考,具体内容如下
kf_account.cs代码:
public partial class kf...
本文实例为大家分享了微信公众号客服接口.net代码,供大家参考,具体内容如下
kf_account.cs代码:
public partial class kf_account : form { private readonly datatable adt_user = new datatable(); private readonly string as_inifile = application.startuppath + "\\user.ini"; public kf_account() { binduser(); } private void binduser() { if (!file.exists(as_inifile)) { var str = new stringbuilder(); str.append(";内容由程序自动生成,请不要修改此文件内容\r\n"); str.append("[total]\r\n"); str.append("total=\r\n"); str.append("[count]\r\n"); str.append("count=\r\n"); str.append("[user]\r\n"); //streamwriter sw = default(streamwriter); //sw = file.createtext(ls_inifile); //sw.writeline(str.tostring()); //sw.close(); file.writealltext(as_inifile, str.tostring(), encoding.unicode); file.setattributes(as_inifile, fileattributes.hidden); } checkforillegalcrossthreadcalls = false; initializecomponent(); icon = resource1.ico; lkl_num.text = inifile.contentvalue("total", "total", as_inifile); lkl_num_c.text = inifile.contentvalue("count", "count", as_inifile); picturebox1.visible = true; var sr = new streamreader(as_inifile, encoding.unicode); string line; int li_count = 0; adt_user.columns.clear(); adt_user.columns.add("username", type.gettype("system.string")); adt_user.columns.add("openid", type.gettype("system.string")); while ((line = sr.readline()) != null) { li_count++; if (li_count > 6) { line = sysvisitor.current.getformatstr(line); datarow newrow; newrow = adt_user.newrow(); newrow["username"] = line.substring(0, line.lastindexof('=')); newrow["openid"] = line.substring(line.lastindexof('=') + 1); adt_user.rows.add(newrow); } } sr.close(); datagridview1.autogeneratecolumns = false; datagridview1.datasource = adt_user; //datagridview1.autosizecolumnsmode = system.windows.forms.datagridviewautosizecolumnsmode.displayedcells; lbl_count.text = "共" + (li_count - 6) + "行"; picturebox1.visible = false; } private void btn_getuser_click(object sender, eventargs e) { if (messagebox.show(@"拉取用户信息的速度取决于你的关注数与网络速度, 可能需要几分钟甚至更长时间。 使用此功能将消耗大量用户管理接口配额。 要继续此操作吗?", "提示:", messageboxbuttons.yesno) == dialogresult.no) { return; } var thr = new thread(get_user_list); thr.start(); } private void get_user_list() { file.delete(as_inifile); var str = new stringbuilder(); str.append(";内容由程序自动生成,请不要修改此文件内容\r\n"); str.append("[total]\r\n"); str.append("total=\r\n"); str.append("[count]\r\n"); str.append("count=\r\n"); str.append("[user]\r\n"); file.writealltext(as_inifile, str.tostring(), encoding.unicode); file.setattributes(as_inifile, fileattributes.hidden); string ls_appid = inifile.contentvalue("weixin", "appid"); string ls_secret = inifile.contentvalue("weixin", "appsecret"); string access_token = ""; string menu = ""; if (ls_appid.length != 18 || ls_secret.length != 32) { messagebox.show("你的appid或appsecret不对,请检查后再操作"); return; } access_token = sysvisitor.current.get_access_token(ls_appid, ls_secret); if (access_token == "") { messagebox.show("appid或appsecret不对,请检查后再操作"); return; } menu = sysvisitor.current.getpageinfo("https://api.weixin.qq.com/cgi-bin/user/get?access_token=" + access_token); if (menu.substring(2, 7) == "errcode") { messagebox.show("拉取失败,返回消息:\r\n" + menu); } jobject json = jobject.parse(menu); lkl_num.text = json["total"].tostring(); inifile.setinistring("total", "total", lkl_num.text, as_inifile); lkl_num_c.text = json["count"].tostring(); inifile.setinistring("count", "count", lkl_num_c.text, as_inifile); int li_count = int.parse(json["count"].tostring()); btn_getuser.enabled = false; picturebox1.visible = true; filestream fs = null; encoding encoder = encoding.unicode; for (int i = 0; i < li_count; i++) { string openid, username; openid = get_username(json["data"]["openid"][i].tostring()); username = json["data"]["openid"][i].tostring(); //inifile.setinistring("user", openid, username, as_inifile); byte[] bytes = encoder.getbytes(openid + "=" + username + " \r\n"); fs = file.openwrite(as_inifile); //设定书写的開始位置为文件的末尾 fs.position = fs.length; //将待写入内容追加到文件末尾 fs.write(bytes, 0, bytes.length); fs.close(); lab_nums.text = "已拉取" + i + "个,还剩" + (li_count - i) + "个,请耐心等待"; } lab_nums.text = ""; //binduser(); btn_getuser.enabled = true; picturebox1.visible = false; messagebox.show("已全部拉取完毕,请重新打开该窗口"); } /// <summary> /// 获取用户信息详情,返回json /// </summary> /// <param name="as_openid"></param> private string get_user(string as_openid) { string ls_json = ""; string access_token = ""; access_token = sysvisitor.current.get_access_token(); ls_json = sysvisitor.current.getpageinfo("https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + access_token + "&openid=" + as_openid + "&lang=zh_cn"); return ls_json; } /// <summary> /// 获取用户用户的昵称 /// </summary> private string get_username(string as_openid) { string ls_json = ""; ls_json = get_user(as_openid); string username = ""; jobject json = jobject.parse(ls_json); username = json["nickname"].tostring(); username = sysvisitor.current.getformatstr(username); return username; } private void btn_search_click(object sender, eventargs e) { string username = txt_search.text.trim(); if (string.isnullorwhitespace(username)) { return; } datarow[] datarows = adt_user.select("username like '%" + username + "%'"); var ldt = new datatable(); ldt.columns.clear(); ldt.columns.add("username", type.gettype("system.string")); ldt.columns.add("openid", type.gettype("system.string")); ldt = todatatable(datarows); try { lbl_count.text = ldt.rows.count.tostring(); } catch { } datagridview1.autogeneratecolumns = false; datagridview1.datasource = ldt; } public datatable todatatable(datarow[] rows) { if (rows == null || rows.length == 0) return null; datatable tmp = rows[0].table.clone(); // 复制datarow的表结构 foreach (datarow row in rows) tmp.rows.add(row.itemarray); // 将datarow添加到datatable中 return tmp; } private void datagridview1_cellmouseclick(object sender, datagridviewcellmouseeventargs e) { try { sysvisitor.current.wx_openid = datagridview1.rows[datagridview1.currentcell.rowindex].cells[1].value.tostring(); sysvisitor.current.wx_username = datagridview1.rows[datagridview1.currentcell.rowindex].cells[0].value.tostring(); //messagebox.show(str); grb_chat.enabled = true; grb_chat.text = sysvisitor.current.wx_username; } catch { } webbrowser_msg.documenttext = ""; string url = string.format("https://api.weixin.qq.com/cgi-bin/customservice/getrecord?access_token={0}", sysvisitor.current.get_access_token()); string ls_text = @"{"; ls_text += "\"starttime\" : " + datetime.now.adddays(-3).ticks + ","; ls_text += "\"endtime\" : " + datetime.now.ticks + ","; ls_text += "\"openid\" : \"" + sysvisitor.current.wx_openid + "\","; ls_text += "\"pagesize\" : 1000,"; ls_text += "\"pageindex\" : 1,"; ls_text += "}"; string ls_history = sysvisitor.current.postpage(url, ls_text); webbrowser_msg.documenttext = ls_history; } private void btn_send_click(object sender, eventargs e) { string ls_msg = richtextbox_msg.text; string ls_text = @"{"; ls_text += "\"touser\":\"" + sysvisitor.current.wx_openid + "\","; ls_text += "\"msgtype\":\"text\","; ls_text += "\"text\":"; ls_text += "{"; ls_text += "\"content\":\"" + ls_msg + "\""; ls_text += "}"; ls_text += "}"; string url = string.format("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={0}", sysvisitor.current.get_access_token()); string ls_isright = sysvisitor.current.postpage(url, ls_text); webbrowser_msg.documenttext += "<p align=right><font size=3>" + ls_isright + "</font></p>"; } private void btn_addkf_click(object sender, eventargs e) { string url = string.format("https://api.weixin.qq.com/customservice/kfaccount/add?access_token={0}", sysvisitor.current.get_access_token()); //客服账号 设置 xxx@你的公众号 这样的格式才是正确的哟。 string ls_text = "{"; ls_text += "\"kf_account\":test2@gz-sisosoft,"; ls_text += "\"nickname\":\"客服2\","; ls_text += "\"password\":\"12345\","; ls_text += "}"; string ls_kf = @"{ 'kf_account' : 'test1@gz-sisosoft', 'nickname' : '客服1', 'password' : '123456', }"; string ls_isok = sysvisitor.current.postpage(url, ls_text); messagebox.show(ls_isok); } private void kf_account_load(object sender, eventargs e) { } }
sysvisitor.cs代码:
class sysvisitor { private static sysvisitor visit = null; public static sysvisitor current { get { if (visit == null) visit = new sysvisitor(); return visit; } } /// <summary> /// 获取access_token /// </summary> /// <param name="appid">appid</param> /// <param name="secret">appsecret</param> /// <returns></returns> public string get_access_token(string appid, string appsecret) { string secondappid = inifile.contentvalue("weixin", "secondappid"); if (appid.tolower() == secondappid.tolower()) { string ls_time = inifile.contentvalue("weixin", "gettime"); decimal ldt; try { ldt = convert.todecimal(ls_time); if (convert.todecimal(datetime.now.tostring("yyyymmddhhmmss")) - ldt < 7100)//每两个小时刷新一次 { return inifile.contentvalue("weixin", "access_token"); } } catch { } } string ls_appid = appid.replace(" ", ""); string ls_secret = appsecret.replace(" ", ""); string access_token = ""; string url = string.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", ls_appid, ls_secret); string json_access_token = getpageinfo(url); //datatable dt = json.jsontodatatable(json_access_token); datatable dt = jsonhelper.jsontodatatable(json_access_token); try { access_token = dt.rows[0]["access_token"].tostring(); } catch { return ""; } inifile.setinistring("weixin", "gettime", datetime.now.tostring("yyyymmddhhmmss")); inifile.setinistring("weixin", "access_token", access_token); inifile.setinistring("weixin", "secondappid", ls_appid); return access_token; } /// <summary> /// 获取access_token /// </summary> public string get_access_token() { string ls_appid = inifile.contentvalue("weixin", "appid"); string ls_secret = inifile.contentvalue("weixin", "appsecret"); return get_access_token(ls_appid, ls_secret); } /// <summary> /// get方法请求url并接收返回消息 /// </summary> /// <param name="strurl">url地址</param> /// <returns></returns> public string getpageinfo(string url) { httpwebrequest request = (httpwebrequest)httpwebrequest.create(url); httpwebresponse response = (httpwebresponse)request.getresponse(); string ret = string.empty; stream s; string strdate = ""; string strvalue = ""; if (response.statuscode == httpstatuscode.ok) { s = response.getresponsestream(); ////在这儿处理返回的文本 streamreader reader = new streamreader(s, encoding.utf8); while ((strdate = reader.readline()) != null) { strvalue += strdate + "\r\n"; } //strvalue = reader.readtoend(); } return strvalue; } /// <summary> /// post方法 /// </summary> /// <param name="posturl">url</param> /// <param name="postdata">post数据</param> /// <returns></returns> public string postpage(string posturl, string postdata) { stream outstream = null; stream instream = null; streamreader sr = null; httpwebresponse response = null; httpwebrequest request = null; encoding encoding = encoding.utf8; byte[] data = encoding.getbytes(postdata); // 准备请求... try { // 设置参数 request = webrequest.create(posturl) as httpwebrequest; cookiecontainer cookiecontainer = new cookiecontainer(); request.cookiecontainer = cookiecontainer; request.allowautoredirect = true; request.method = "post"; request.contenttype = "application/x-www-form-urlencoded"; request.contentlength = data.length; outstream = request.getrequeststream(); outstream.write(data, 0, data.length); outstream.close(); //发送请求并获取相应回应数据 response = request.getresponse() as httpwebresponse; //直到request.getresponse()程序才开始向目标网页发送post请求 instream = response.getresponsestream(); sr = new streamreader(instream, encoding); //返回结果网页(html)代码 string content = sr.readtoend(); string err = string.empty; return content; } catch (exception ex) { string err = ex.message; return string.empty; } } /// <summary> /// 格式化字符串 /// </summary> /// <param name="str"></param> /// <returns></returns> public string getformatstr(string str) { if ("" == str) return ""; else { str = str.trim(); str = str.replace("'", "'"); str = str.replace("〈", "<"); str = str.replace("〉", ">"); str = str.replace(",", ","); return str; } } string ls_username = ""; /// <summary> /// 用户名 /// </summary> public string wx_username { get { return ls_username; } set { ls_username = value; } } string ls_openid = ""; /// <summary> /// openid /// </summary> public string wx_openid { get { return ls_openid; } set { ls_openid = value; } } }
inifile.cs代码:
class inifile { ///// <summary> ///// 设置ini文件参数 ///// </summary> ///// <param name="section">ini文件中的段落</param> ///// <param name="key">ini文件中的关键字</param> ///// <param name="val">ini文件中关键字的数值</param> ///// <param name="filepath">ini文件的完整的路径和名称</param> ///// <returns></returns> //[dllimport("kernel32")] //private static extern long writeprivateprofilestring( // string section, string key, string val, string filepath); ///// <summary> ///// 获取ini文件参数 ///// </summary> ///// <param name="section">ini文件中的段落名称</param> ///// <param name="key">ini文件中的关键字</param> ///// <param name="def">无法读取时候时候的缺省数值</param> ///// <param name="retval">读取数值</param> ///// <param name="size">数值的大小</param> ///// <param name="filepath">ini文件的完整路径和名称</param> //[dllimport("kernel32")] //private static extern int getprivateprofilestring( // string section, string key, string def, stringbuilder retval, int size, string filepath); //static string gs_filename = system.appdomain.currentdomain.basedirectory + "config.ini"; ///// <summary> ///// 获取ini文件参数 ///// </summary> ///// <param name="as_section">ini文件中的段落名称</param> ///// <param name="as_key">ini文件中的关键字</param> ///// <param name="as_filename">ini文件的完整路径和名称</param> //public static string getinistring(string as_section, string as_key, string as_filename) //{ // stringbuilder temp = new stringbuilder(255); // int i = getprivateprofilestring(as_section, as_key, "", temp, 255, as_filename); // return temp.tostring(); //} ///// <summary> ///// 获取ini文件参数 ///// </summary> ///// <param name="as_section">ini文件中的段落名称</param> ///// <param name="as_key">ini文件中的关键字</param> ///// <param name="as_filename">ini文件的完整路径和名称</param> //public static string getinistring(string as_section, string as_key) //{ // return getinistring(as_section, as_key, gs_filename); //} ///// <summary> ///// 设置ini文件参数 ///// </summary> ///// <param name="as_section">ini文件中的段落</param> ///// <param name="as_key">ini文件中的关键字</param> ///// <param name="as_value">ini文件中关键字的数值</param> ///// <param name="as_filename">ini文件的完整路径和名称</param> //public static long setinistring(string as_section, string as_key, string as_value, string as_filename) //{ // return writeprivateprofilestring(as_section, as_key, as_value, as_filename); //} ///// <summary> ///// 设置ini文件参数 ///// </summary> ///// <param name="as_section">ini文件中的段落</param> ///// <param name="as_key">ini文件中的关键字</param> ///// <param name="as_value">ini文件中关键字的数值</param> //public static long setinistring(string as_section, string as_key, string as_value) //{ // return setinistring(as_section, as_key, as_value, gs_filename); //} /// <summary> /// 写入ini文件 /// </summary> /// <param name="section">节点名称[如[typename]]</param> /// <param name="key">键</param> /// <param name="val">值</param> /// <param name="filepath">文件路径</param> /// <returns></returns> [dllimport("kernel32")] public static extern long writeprivateprofilestring(string section, string key, string val, string filepath); [dllimport("kernel32.dll")] public extern static int getprivateprofilesectionnamesa(byte[] buffer, int ilen, string filename); /// <summary> /// 写入ini文件(section:节点名称 key:键 val:值) /// </summary> /// <param name="section">节点名称</param> /// <param name="key">键</param> /// <param name="val">值</param> /// <returns></returns> public static long setinistring(string section, string key, string val, string as_filepath = "") { if (as_filepath == "") { return (writeprivateprofilestring(section, key, val, strfilepath)); } else { return (writeprivateprofilestring(section, key, val, as_filepath)); } } /// <summary> /// 读取ini文件 /// </summary> /// <param name="section">节点名称</param> /// <param name="key">键</param> /// <param name="def">值</param> /// <param name="retval">stringbulider对象</param> /// <param name="size">字节大小</param> /// <param name="filepath">文件路径</param> /// <returns></returns> [dllimport("kernel32")] public static extern int getprivateprofilestring(string section, string key, string def, stringbuilder retval, int size, string filepath); public static string strfilepath = application.startuppath + "\\config.ini";//获取ini文件默认路径 public static string strsec = ""; //ini文件名 /// <summary> /// 读取ini文件中的内容方法 (section 节点名称;key 键) /// </summary> /// <param name="section">节点名称</param> /// <param name="key">键</param> /// <returns></returns> public static string contentvalue(string section, string key, string as_filepath = "") { stringbuilder temp = new stringbuilder(1024); if (as_filepath == "") { getprivateprofilestring(section, key, "", temp, 1024, strfilepath); } else { getprivateprofilestring(section, key, "", temp, 1024, as_filepath); } return temp.tostring(); } /// <summary> /// 获取指定小节所有项名和值的一个列表 /// </summary> /// <param name="section">节 段,欲获取的小节。注意这个字串不区分大小写</param> /// <param name="buffer">缓冲区 返回的是一个二进制的串,字符串之间是用"\0"分隔的</param> /// <param name="nsize">缓冲区的大小</param> /// <param name="filepath">初始化文件的名字。如没有指定完整路径名,windows就在windows目录中查找文件</param> /// <returns></returns> [dllimport("kernel32")] public static extern int getprivateprofilesection(string section, byte[] buffer, int nsize, string filepath); /// <summary> /// 获取指定段section下的所有键值对 返回集合的每一个键形如"key=value" /// </summary> /// <param name="section">指定的段落</param> /// <param name="filepath">ini文件的绝对路径</param> /// <returns></returns> public static list<string> readkeyvalues(string section, string as_filepath = "") { byte[] buffer = new byte[32767]; list<string> list = new list<string>(); int length = 0; if (as_filepath == "") { length = getprivateprofilesection(section, buffer, buffer.getupperbound(0), strfilepath); } else { length = getprivateprofilesection(section, buffer, buffer.getupperbound(0), as_filepath); } string temp; int postion = 0; for (int i = 0; i < length; i++) { if (buffer[i] == 0x00) //以'\0'来作为分隔 { temp = system.text.asciiencoding.default.getstring(buffer, postion, i - postion).trim(); postion = i + 1; if (temp.length > 0) { list.add(temp); } } } return list; } /// <summary> /// 删除指定的key /// </summary> /// <param name="section">要写入的段落名</param> /// <param name="key">要删除的键</param> /// <param name="filename">ini文件的完整路径和文件名</param> public static void delkey(string section, string key, string as_filepath = "") { if (as_filepath == "") { writeprivateprofilestring(section, key, null, strfilepath); } else { writeprivateprofilestring(section, key, null, as_filepath); } } /// <summary> /// 返回该配置文件中所有section名称的集合 /// </summary> public static arraylist readsections() { byte[] buffer = new byte[65535]; int rel = getprivateprofilesectionnamesa(buffer, buffer.getupperbound(0), strfilepath); int icnt, ipos; arraylist arraylist = new arraylist(); string tmp; if (rel > 0) { icnt = 0; ipos = 0; for (icnt = 0; icnt < rel; icnt++) { if (buffer[icnt] == 0x00) { tmp = system.text.asciiencoding.utf8.getstring(buffer, ipos, icnt - ipos).trim(); ipos = icnt + 1; if (tmp != "") arraylist.add(tmp); } } } return arraylist; } }
运行结果:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: ASP.NET MVC从视图传参到控制器的几种形式
下一篇: 银川十大小吃,羊羔肉必吃,大部分是面食