微信自动发送消息接口开发(三)

上一篇已经能够成功监听微信的消息了,现在只剩最后一个功能发送消息了.
发消息我只做了两个功能:发送文字和发送图片,其他的不太用的到,就没有做.

首先是发送普通文字消息

发送文字

发送文字很简单,如图只有一个接口webwxsendmsg BaseRequest和之前的监听消息是一样的,另外一个Msg Type:1就是文本消息(Type就是监听消息的时候返回的Type类型)ClientMsgId和LocalID在源码中都是当前时间戳+4位随机数字,FromUserName当然是填自己的UserName了(监听里初始化的时候的自己的UserName),ToUserName当然是填发送方了. Content就是具体要发送的内容了.

如果发送中文出来乱码的话注意发送的data编码得是utf-8

当返回的消息BaseResponse.Ret == 0 的时候,就表示你发送成功了.

接下来是发送图片消息

发送图片通过抓包可以发现是两个接口

1.上传文件 webwxuploadmedia?f=json
上传图片

其他的根据抓到的包来填值都没问题
主要有一个参数是uploadmediarequest要观察一下源码来填内容.
request参数

参数比较多不一一说明,其中FileMd5其实没关系,不用管随便传个值都可以,我是对图片名称+图片大小进行md5加密后传送过去的.

上传图片需要用multipart/form-data形式发送,这里附上我自己封装的上传方法供大家参考

    //上传图片消息
    private HttpResult WebWXUpLoadPicture(Contact model, string filePath)
    {
        string boundary = "----WebKitFormBoundary" + DateTime.Now.Ticks.ToString("x");

        var fileInfo = new FileInfo(filePath);

        List<FormItemModel> data = new List<FormItemModel>();
        //id
        data.Add(new FormItemModel("id", "WU_FILE_" + _fileId++));
        //name
        data.Add(new FormItemModel("name", fileInfo.Name));
        //type
        data.Add(new FormItemModel("type", System.Web.MimeMapping.GetMimeMapping(filePath)));
        //lastModifiedDate
        data.Add(new FormItemModel("lastModifiedDate", fileInfo.LastWriteTime.ToString("yyyy-MM-dd tt hh:mm:ss")));
        //size
        data.Add(new FormItemModel("size", fileInfo.Length.ToString()));
        //mediatype
        data.Add(new FormItemModel("mediatype", "pic"));
        //uploadmediarequest
        string md5 = Utils.EncryptToMD5(fileInfo.Name + fileInfo.Length);
        PicModel pic = new PicModel()
        {
            UploadType = 2,
            BaseRequest = new BaseRequest(this._wxModel),
            TotalLen = fileInfo.Length,
            FromUserName = this.User.UserName,
            ToUserName = model.UserName,
            FileMd5 = md5
        };
        data.Add(new FormItemModel("uploadmediarequest", JsonHelper.SerializeObject(pic)));
        //webwx_data_ticket
        string ticket = this.GetCookie("webwx_data_ticket");
        data.Add(new FormItemModel("webwx_data_ticket", ticket));
        //pass_ticket
        data.Add(new FormItemModel("pass_ticket", this._wxModel.pass_ticket));
        //file
        data.Add(new FormItemModel("filename", fileInfo.Name, filePath));

        var bytes = CreateFileByte(data, boundary);

        HttpItem item = new HttpItem()
        {
            URL = "https://file.wx.qq.com/cgi-bin/mmwebwx-bin/webwxuploadmedia?f=json",
            Method = "POST",
            PostDataType = PostDataType.Byte,
            ContentType = "multipart/form-data; boundary=" + boundary,
            PostEncoding = Encoding.UTF8,
            PostdataByte = bytes
        };
        HttpHelper http = new HttpHelper();

        var rst = http.GetHtml(item);

        return rst;
    }
    //实体类模型
    public class FormItemModel
    {
    public FormItemModel(string key, string value)
    {
        this.Key = key;
        this.Value = value;
    }

    public FormItemModel(string key, string name, string path)
    {
        this.Key = key;
        this.Value = name;
        this.FilePath = path;
    }

    /// <summary>  
    /// 表单键,request["key"]  
    /// </summary>  
    public string Key { set; get; }
    /// <summary>  
    /// 表单值,上传文件时为文件名
    /// </summary>  
    public string Value { set; get; }
    /// <summary>  
    /// 是否是文件  
    /// </summary>  
    public bool IsFile
    {
        get
        {
            if (string.IsNullOrEmpty(FilePath) && FileContent == null) return false;

            return true;
        }
    }

    public byte[] GetFileBytes(Encoding encoding)
    {
        if (encoding == null) encoding = Encoding.UTF8;
        if (IsFile)
        {
            try
            {
                if (!string.IsNullOrEmpty(FilePath))
                {
                    using (FileStream fileStream = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        byte[] bytes = new byte[fileStream.Length];
                        fileStream.Read(bytes, 0, bytes.Length);
                        return bytes;
                    }
                }
                else
                {
                    byte[] bytes = new byte[FileContent.Length];
                    FileContent.Read(bytes, 0, bytes.Length);
                    FileContent.Seek(0, SeekOrigin.Begin);
                    return bytes;
                }
            }
            catch (Exception)
            {
                return null;
            }
        }
        else
        {
            return null;
        }
    }

    //如果是文件,下面两个只要填一个即可.

    /// <summary>  
    /// 上传的文件路径 
    /// </summary>  
    public string FilePath { set; get; }

    /// <summary>
    /// 文件流
    /// </summary>
    public Stream FileContent { get; set; }
}

//核心postdata 字节创建方法
private byte[] CreateFileByte(List<FormItemModel> formItems, string boundary, Encoding encoding = null)
    {
        if (encoding == null) encoding = Encoding.UTF8;
        Stream postStream = new MemoryStream();
        //文件模板
        string fileFormdataTemplate =
        "\r\n--" + boundary +
        "\r\nContent-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"" +
        "\r\nContent-Type: application/octet-stream" +
        "\r\n\r\n";
        //文本数据模板  
        string dataFormdataTemplate =
            "\r\n--" + boundary +
            "\r\nContent-Disposition: form-data; name=\"{0}\"" +
            "\r\n\r\n{1}";

        foreach (var item in formItems)
        {
            string formdata = null;
            if (item.IsFile)
            {   //文件
                formdata = string.Format(
                fileFormdataTemplate,
                item.Key, //表单键  
                item.Value);
            }
            else
            {   //文本
                formdata = string.Format(
                dataFormdataTemplate,
                item.Key,
                item.Value);
            }

            byte[] formdataBytes = null;

            if (postStream.Length == 0)
                formdataBytes = encoding.GetBytes(formdata.Substring(2));
            else
                formdataBytes = encoding.GetBytes(formdata);

            //写入流
            postStream.Write(formdataBytes, 0, formdataBytes.Length);

            if (item.IsFile)
            {
                var bytes = item.GetFileBytes(encoding);
                if (bytes == null)
                {
                    this.PrintErrlog("读取文件错误:" + JsonHelper.SerializeObject(item));
                    throw new Exception("读取文件错误");
                }
                postStream.Write(bytes, 0, bytes.Length);
            }
        }

        var footer = encoding.GetBytes("\r\n--" + boundary + "--\r\n");
        postStream.Write(footer, 0, footer.Length);

        byte[] buffer = StreamToBytes(postStream);

        return buffer;

    }





如果上传图片成功,服务器会返回一个MediaId,相当于图片已经成功上传到微信服务器了,这个就是图片的key

文件上传返回

2.发送图片消息 webwxsendmsgimg

发送图片消息

发送图片接口就比较简单了,和文字消息差不多,要改的就是Msg中的Type换成3,再加上刚才得到的MediaId,其他的都基本差不多,当返回的消息BaseResponse.Ret == 0 的时候,你就成功了

接下来那些发送小视频,声音等等的由于本人实际需求用不到,就没有继续写了.本来还想写个自动抢红包的,发现网页版根本不支持抢红包,就无从写起了...

标签: none

添加新评论