这里有新鲜出炉的精品教程,程序狗速度看过来!
微信(英文名:wechat)是腾讯公司于2011年1月21日推出的一个为智能终端提供即时通讯服务的免费应用程序,微信支持跨通信运营商、跨操作系统平台通过网络快速发送免费语音短信、视频、图片和文字,同时,也可以使用通过共享流媒体内容的资料和基于位置的社交插件“摇一摇”、“漂流瓶”、“朋友圈”、”公众平台“、”语音记事本“等服务插件。
这篇文章主要介绍了微信公众号开发客服接口的相关资料,并附简单实例,需要的朋友可以参考下
最近,开发微信公众号,负责开发客服功能,这里简单记录下:
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">
- 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 += "
- " + ls_isright + "
- "; } 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 name="secret">appsecret
- /// <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地址
- /// <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 name="postData">Post数据
- /// <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">
- /// <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 name="key">INI文件中的关键字
- /////<param name="val">INI文件中关键字的数值
- /////<param name="filePath">INI文件的完整的路径和名称
- ///// <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 name="key">INI文件中的关键字
- /////<param name="def">无法读取时候时候的缺省数值
- /////<param name="retVal">读取数值
- /////<param name="size">数值的大小
- /////<param name="filePath">INI文件的完整路径和名称
- //[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 name="as_key">INI文件中的关键字
- /////<param name="as_FileName">INI文件的完整路径和名称
- //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 name="as_key">INI文件中的关键字
- /////<param name="as_FileName">INI文件的完整路径和名称
- //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 name="as_key">INI文件中的关键字
- /////<param name="as_Value">INI文件中关键字的数值
- /////<param name="as_FileName">INI文件的完整路径和名称
- //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 name="as_key">INI文件中的关键字
- /////<param name="as_Value">INI文件中关键字的数值
- //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 name="key">键
- ///<param name="val">值
- ///<param name="filepath">文件路径
- /// <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 name="key">键
- ///<param name="val">值
- /// <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 name="key">键
- ///<param name="def">值
- ///<param name="retval">stringbulider对象
- ///<param name="size">字节大小
- ///<param name="filePath">文件路径
- /// <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 name="key">键
- /// <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 name="buffer">缓冲区 返回的是一个二进制的串,字符串之间是用"\0"分隔的
- ///<param name="nSize">缓冲区的大小
- ///<param name="filePath">初始化文件的名字。如没有指定完整路径名,windows就在Windows目录中查找文件
- /// <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 name="filePath">ini文件的绝对路径
- /// <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 name="key">要删除的键
- ///<param name="fileName">INI文件的完整路径和文件名
- 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;
- }
- }</string></string></string>
运行结果:
这里写图片描述
来源: http://www.phperz.com/article/17/0901/341771.html