public class Client
{
public Client(User user)
{
this.User = user;
this.HttpHelper = new HttpHelper(Encoding.UTF8);
}
public User User { get; private set; }
public HttpHelper HttpHelper { get; private set; }
public bool IsLogin { get; private set; }
public string Token { get; private set; }
private string frommsgid;
private readonly static string loginUrl = "https://mp.weixin.qq.com/cgi-bin/loginpage?t=wxm2-login&lang=zh_CN";
private readonly static string loginActiveUrl = "https://mp.weixin.qq.com/cgi-bin/login";
private readonly static string messageUrl = "https://mp.weixin.qq.com/cgi-bin/message?t=message/list&count=20&day=7&token={0}&lang=zh_CN";
private readonly static string messagePageUrl = "https://mp.weixin.qq.com/cgi-bin/message?t=message/list&action=&keyword=&frommsgid={0}&offset={1}&count=20&day=7&filterivrmsg=&token={2}&lang=zh_CN";
private Regex pageTotalRegex = new Regex("total_count : (?<value>\\d+),");
private Regex msgRegex = new Regex("list : [(](?<value>[\\s\\S]+?)[)].msg_item");
private Regex tokenRegex = new Regex("token=(?<value>\\d+)");
private Regex fidRegex = new Regex("frommsgid[\\s]?:[\\s]?\"(?<value>\\d+)\"");
public void Login()
{
IsLogin = false;
string data = string.Format("username={0}&pwd={1}&imgcode=&f=json", User.Uname, User.EnPassword.ToLower());
HttpHelper.GetHtml(loginUrl);
string html = HttpHelper.PostHtml(loginActiveUrl, data, "https://mp.weixin.qq.com/");
LoginResult result = JsonConvert.DeserializeObject<LoginResult>(html);
if (result.base_resp.ret == 0)
{
IsLogin = true;
Token = tokenRegex.Match(result.redirect_url).Groups["value"].Value;
html = HttpHelper.GetHtml(string.Format("https://mp.weixin.qq.com{0}", result.redirect_url), "https://mp.weixin.qq.com/");
}
}
public Message[] ExportMessage()
{
List<Message> list = new List<Message>();
string html = HttpHelper.GetHtml(string.Format(messageUrl, Token), "https://mp.weixin.qq.com/");
var msgList = ReadMessage(html);
if (msgList != null)
{
list.AddRange(msgList);
}
int pageTotal = GetPageTotal(html);
for (var i = 1; i < pageTotal; i++)
{
html = HttpHelper.GetHtml(string.Format(messagePageUrl, frommsgid, i * 20, Token), "https://mp.weixin.qq.com/");
msgList = ReadMessage(html);
if (msgList != null)
{
list.AddRange(msgList);
}
}
return list.ToArray();
}
public int GetPageTotal(string html)
{
string pTotal = pageTotalRegex.Match(html).Groups["value"].Value;
int total = string.IsNullOrEmpty(pTotal) ? 1 : Convert.ToInt32(pTotal);
return ((total - 1) / 20) + 1;
}
public string GetFormId(string html)
{
return fidRegex.Match(html).Groups["value"].Value;
}
private Message[] ReadMessage(string html)
{
frommsgid = GetFormId(html);
string messageInfo = msgRegex.Match(html).Groups["value"].Value;
MessageList msgList = JsonConvert.DeserializeObject<MessageList>(messageInfo);
OnReadMessageCompleted(new MessageEventArgs(msgList.msg_item));
return msgList.msg_item;
}
public event EventHandler<MessageEventArgs> ReadMessageCompleted;
private void OnReadMessageCompleted(MessageEventArgs e)
{
if (ReadMessageCompleted != null)
{
ReadMessageCompleted(this, e);
}
}
}
public class LoginResult
{
public BaseResponse base_resp { get; set; }
public string redirect_url { get; set; }
}
public class BaseResponse
{
public int ret { get; set; }
public string err_msg { get; set; }
}
public class MessageList
{
public Message[] msg_item { get; set; }
}
public class Message
{
public string id { get; set; }
public int type { get; set; }
public string fakeid { get; set; }
public string nick_name { get; set; }
[JsonConverter(typeof(UnixDateTimeConverter))]
public DateTime date_time { get; set; }
public string content { get; set; }
public string source { get; set; }
public int msg_status { get; set; }
public string remark_name { get; set; }
public int has_reply { get; set; }
public string refuse_reason { get; set; }
public long to_uin { get; set; }
}
public class SendState
{
public int total { get; set; }
public int succ { get; set; }
public int fail { get; set; }
}
public class UnixDateTimeConverter : DateTimeConverterBase
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType != JsonToken.Integer)
{
throw new Exception(String.Format("日期格式錯誤,got {0}.", reader.TokenType));
}
var ticks = (long)reader.Value;
var date = new DateTime(1970, 1, 1);
date = date.AddSeconds(ticks);
return date;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
long ticks;
if (value is DateTime)
{
var epoc = new DateTime(1970, 1, 1);
var delta = ((DateTime)value) - epoc;
if (delta.TotalSeconds < 0)
{
throw new ArgumentOutOfRangeException("時間格式錯誤.1");
}
ticks = (long)delta.TotalSeconds;
}
else
{
throw new Exception("時間格式錯誤.2");
}
writer.WriteValue(ticks);
}
}