/// <summary>
        /// 根据分组进行群发【订阅号与服务号认证后均可用】
        /// 请注意:在返回成功时,意味着群发任务提交成功,并不意味着此时群发已经结束,
        /// 所以,仍有可能在后续的发送过程中出现异常情况导致用户未收到消息,如消息有时会进行审核、服务器不稳定等。
        /// 此外,群发任务一般需要较长的时间才能全部发送完毕,请耐心等待。
        /// </summary>
        /// <param name="access_token"></param>
        /// <param name="content">图文消息,语音,图片,视频:media_id; 文本:文本消息</param>
        /// <param name="type"></param>
        /// <param name="group_id">群发到的分组的group_id,参加用户管理中用户分组接口,若is_to_all值为true,可不填写group_id</param>
        /// <param name="is_to_all">用于设定是否向全部用户发送,值为true或false,选择true该消息群发给所有用户,选择false可根据group_id发送给指定群组的用户</param>
        /// <returns>success:{"errcode":0,"errmsg":"send job submission success","msg_id":34182 }</returns>
        public static dynamic Replay(string access_token, string content, WeixinArtcleType type, string group_id, bool is_to_all = false)
        {
            var url     = string.Format("https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token={0}", access_token);
            var client  = new HttpClient();
            var builder = new StringBuilder();

            builder.Append("{")
            .Append('"' + "filter" + '"' + ":")
            .Append("{")
            .Append('"' + "is_to_all" + '"').Append(is_to_all)
            .Append('"' + "group_id" + '"').Append(group_id)
            .Append("},");

            switch (type)
            {
            case WeixinArtcleType.News:
                builder.Append('"' + "mpnews" + '"' + ":")
                .Append("{")
                .Append('"' + "media_id" + '"').Append(content)
                .Append("},")
                .Append('"' + "msgtype" + '"').Append("mpnews");
                break;

            case WeixinArtcleType.Text:
                builder.Append('"' + "text" + '"' + ":")
                .Append("{")
                .Append('"' + "content" + '"').Append(content)
                .Append("},")
                .Append('"' + "msgtype" + '"').Append("text");
                break;

            case WeixinArtcleType.Voice:
                builder.Append('"' + "voice" + '"' + ":")
                .Append("{")
                .Append('"' + "media_id" + '"').Append(content)
                .Append("},")
                .Append('"' + "msgtype" + '"').Append("voice");
                break;

            case WeixinArtcleType.Image:
                builder.Append('"' + "image" + '"' + ":")
                .Append("{")
                .Append('"' + "media_id" + '"').Append(content)
                .Append("},")
                .Append('"' + "msgtype" + '"').Append("image");
                break;

            case WeixinArtcleType.Video:
                builder.Append('"' + "mpvideo" + '"' + ":")
                .Append("{")
                .Append('"' + "media_id" + '"').Append(content)
                .Append("},")
                .Append('"' + "msgtype" + '"').Append("mpvideo");
                break;
            }
            builder.Append("}");
            var result = client.PostAsync(url, new StringContent(builder.ToString())).Result;

            return(DynamicJson.Parse(result.Content.ReadAsStringAsync().Result));
        }
        /// <summary>
        /// 根据分组进行群发【订阅号与服务号认证后均可用】
        /// 请注意:在返回成功时,意味着群发任务提交成功,并不意味着此时群发已经结束,
        /// 所以,仍有可能在后续的发送过程中出现异常情况导致用户未收到消息,如消息有时会进行审核、服务器不稳定等。
        /// 此外,群发任务一般需要较长的时间才能全部发送完毕,请耐心等待。
        /// </summary>
        /// <param name="access_token"></param>
        /// <param name="content">图文消息,语音,图片,视频:media_id; 文本:文本消息</param>
        /// <param name="type"></param>
        /// <param name="group_id">群发到的分组的group_id,参加用户管理中用户分组接口,若is_to_all值为true,可不填写group_id</param>
        /// <param name="is_to_all">用于设定是否向全部用户发送,值为true或false,选择true该消息群发给所有用户,选择false可根据group_id发送给指定群组的用户</param>
        /// <returns>success:{"errcode":0,"errmsg":"send job submission success","msg_id":34182 }</returns>
        public static dynamic Replay(string access_token, string content, WeixinArtcleType type, string group_id, bool is_to_all = false)
        {
            var url = string.Format("https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token={0}", access_token);
            var client = new HttpClient();
            var builder = new StringBuilder();
            builder.Append("{")
                   .Append('"' + "filter" + '"' + ":")
                                           .Append("{")
                                           .Append('"' + "is_to_all" + '"' + ":").Append(is_to_all).Append(",")
                                           .Append('"' + "group_id" + '"' + ":").Append(group_id)
                                           .Append("},");

            switch (type)
            {
                case WeixinArtcleType.News:
                    builder.Append('"' + "mpnews" + '"' + ":")
                                           .Append("{")
                                           .Append('"' + "media_id" + '"' + ":").Append(content)
                                           .Append("},")
                              .Append('"' + "msgtype" + '"' + ":").Append("mpnews");
                    break;
                case WeixinArtcleType.Text:
                    builder.Append('"' + "text" + '"' + ":")
                                           .Append("{")
                                           .Append('"' + "content" + '"' + ":").Append(content)
                                           .Append("},")
                              .Append('"' + "msgtype" + '"' + ":").Append("text");
                    break;
                case WeixinArtcleType.Voice:
                    builder.Append('"' + "voice" + '"' + ":")
                                           .Append("{")
                                           .Append('"' + "media_id" + '"' + ":").Append(content)
                                           .Append("},")
                              .Append('"' + "msgtype" + '"' + ":").Append("voice");
                    break;
                case WeixinArtcleType.Image:
                    builder.Append('"' + "image" + '"' + ":")
                                           .Append("{")
                                           .Append('"' + "media_id" + '"' + ":").Append(content)
                                           .Append("},")
                              .Append('"' + "msgtype" + '"' + ":").Append("image");
                    break;
                case WeixinArtcleType.Video:
                    builder.Append('"' + "mpvideo" + '"' + ":")
                                           .Append("{")
                                           .Append('"' + "media_id" + '"' + ":").Append(content)
                                           .Append("},")
                              .Append('"' + "msgtype" + '"' + ":").Append("mpvideo");
                    break;
            }
            builder.Append("}");
            var result = client.PostAsync(url, new StringContent(builder.ToString())).Result;
            return DynamicJson.Parse(result.Content.ReadAsStringAsync().Result);
        }
        /// <summary>
        /// 根据OpenID列表群发【订阅号不可用,服务号认证后可用】
        /// </summary>
        /// <param name="access_token"></param>
        /// <param name="content">图文消息,语音,图片,视频:media_id; 文本:文本消息</param>
        /// <param name="type"></param>
        /// <param name="touser"></param>
        /// <returns>success:{"errcode":0,"errmsg":"send job submission success","msg_id":34182}</returns>
        public static dynamic ReplayOpenids(string access_token, string content, WeixinArtcleType type, IEnumerable<string> touser, string videoTitle, string videoDesc)
        {
            var url = string.Format("https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token={0}", access_token);
            var client = new HttpClient();
            var builder = new StringBuilder();
            builder.Append("{")
                   .Append('"' + "touser" + '"' + ":")
                   .Append("[");
            foreach (var t in touser)
            {
                builder.Append('"' + t + '"').Append(",");
            }
            builder.Append("],");

            switch (type)
            {
                case WeixinArtcleType.News:
                    builder.Append('"' + "mpnews" + '"' + ":")
                                           .Append("{")
                                           .Append('"' + "media_id" + '"' + ":").Append(content)
                                           .Append("},")
                              .Append('"' + "msgtype" + '"' + ":").Append("mpnews");
                    break;
                case WeixinArtcleType.Text:
                    builder.Append('"' + "text" + '"' + ":")
                                           .Append("{")
                                           .Append('"' + "content" + '"' + ":").Append(content)
                                           .Append("},")
                              .Append('"' + "msgtype" + '"' + ":").Append("text");
                    break;
                case WeixinArtcleType.Voice:
                    builder.Append('"' + "voice" + '"' + ":")
                                           .Append("{")
                                           .Append('"' + "media_id" + '"' + ":").Append(content)
                                           .Append("},")
                              .Append('"' + "msgtype" + '"' + ":").Append("voice");
                    break;
                case WeixinArtcleType.Image:
                    builder.Append('"' + "image" + '"' + ":")
                                           .Append("{")
                                           .Append('"' + "media_id" + '"' + ":").Append(content)
                                           .Append("},")
                              .Append('"' + "msgtype" + '"' + ":").Append("image");
                    break;
                case WeixinArtcleType.Video:
                    builder.Append('"' + "video" + '"' + ":")
                                           .Append("{")
                                           .Append('"' + "media_id" + '"' + ":").Append(content).Append(",")
                                           .Append('"' + "title" + '"' + ":").Append(videoTitle).Append(",")
                                           .Append('"' + "description" + '"' + ":").Append(videoDesc)
                                           .Append("},")
                              .Append('"' + "msgtype" + '"' + ":").Append("video");
                    break;
            }
            builder.Append("}");
            var result = client.PostAsync(url, new StringContent(builder.ToString())).Result;
            return DynamicJson.Parse(result.Content.ReadAsStringAsync().Result);
        }
        /// <summary>
        /// 根据OpenID列表群发【订阅号不可用,服务号认证后可用】
        /// </summary>
        /// <param name="access_token"></param>
        /// <param name="content">图文消息,语音,图片,视频:media_id; 文本:文本消息</param>
        /// <param name="type"></param>
        /// <param name="touser"></param>
        /// <returns>success:{"errcode":0,"errmsg":"send job submission success","msg_id":34182}</returns>
        public static dynamic ReplayOpenids(string access_token, string content, WeixinArtcleType type, IEnumerable <string> touser, string videoTitle, string videoDesc)
        {
            var url     = string.Format("https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token={0}", access_token);
            var client  = new HttpClient();
            var builder = new StringBuilder();

            builder.Append("{")
            .Append('"' + "touser" + '"' + ":")
            .Append("[");
            foreach (var t in touser)
            {
                builder.Append('"' + t + '"').Append(",");
            }
            builder.Append("],");

            switch (type)
            {
            case WeixinArtcleType.News:
                builder.Append('"' + "mpnews" + '"' + ":")
                .Append("{")
                .Append('"' + "media_id" + '"').Append(content)
                .Append("},")
                .Append('"' + "msgtype" + '"').Append("mpnews");
                break;

            case WeixinArtcleType.Text:
                builder.Append('"' + "text" + '"' + ":")
                .Append("{")
                .Append('"' + "content" + '"').Append(content)
                .Append("},")
                .Append('"' + "msgtype" + '"').Append("text");
                break;

            case WeixinArtcleType.Voice:
                builder.Append('"' + "voice" + '"' + ":")
                .Append("{")
                .Append('"' + "media_id" + '"').Append(content)
                .Append("},")
                .Append('"' + "msgtype" + '"').Append("voice");
                break;

            case WeixinArtcleType.Image:
                builder.Append('"' + "image" + '"' + ":")
                .Append("{")
                .Append('"' + "media_id" + '"').Append(content)
                .Append("},")
                .Append('"' + "msgtype" + '"').Append("image");
                break;

            case WeixinArtcleType.Video:
                builder.Append('"' + "video" + '"' + ":")
                .Append("{")
                .Append('"' + "media_id" + '"').Append(content)
                .Append('"' + "title" + '"').Append(videoTitle)
                .Append('"' + "description" + '"').Append(videoDesc)
                .Append("},")
                .Append('"' + "msgtype" + '"').Append("video");
                break;
            }
            builder.Append("}");
            var result = client.PostAsync(url, new StringContent(builder.ToString())).Result;

            return(DynamicJson.Parse(result.Content.ReadAsStringAsync().Result));
        }