using Jiguang.JPush.Model; using System; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; using System.Collections.Generic; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace Jiguang.JPush { public class JPushClient { public const string BASE_URL_PUSH_DEFAULT = "https://api.jpush.cn/v3/push"; public const string BASE_URL_PUSH_BEIJING = "https://bjapi.push.jiguang.cn/v3/push"; private string BASE_URL = BASE_URL_PUSH_DEFAULT; public DeviceClient Device; public ScheduleClient Schedule; private ReportClient report; public ReportClient Report { get => report; set => report = value; } public static HttpClient HttpClient; static JPushClient() { HttpClient = new HttpClient(); HttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); } public JPushClient(string appKey, string masterSecret) { if (string.IsNullOrEmpty(appKey)) throw new ArgumentNullException(nameof(appKey)); if (string.IsNullOrEmpty(masterSecret)) throw new ArgumentNullException(nameof(masterSecret)); var auth = Convert.ToBase64String(Encoding.UTF8.GetBytes(appKey + ":" + masterSecret)); HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", auth); Report = new ReportClient(); Device = new DeviceClient(); Schedule = new ScheduleClient(); } /// /// 设置 push 功能的 API 调用地址。 /// /// 如果极光应用分配在北京机房(极光控制台 “应用设置” -> “应用信息” 中可以看到),并且开发者接口调用的服务器也位于北京,则可以调用如下地址: /// /// https://bjapi.push.jiguang.cn/v3/push /// 可以提升 API 的响应速度。 /// /// /// or public void SetBaseURL(string url) { BASE_URL = url; } public async Task SendPushAsync(string jsonBody) { if (string.IsNullOrEmpty(jsonBody)) throw new ArgumentNullException(nameof(jsonBody)); HttpContent httpContent = new StringContent(jsonBody, Encoding.UTF8); HttpResponseMessage msg = await HttpClient.PostAsync(BASE_URL, httpContent).ConfigureAwait(false); var content = await msg.Content.ReadAsStringAsync().ConfigureAwait(false); return new HttpResponse(msg.StatusCode, msg.Headers, content); } /// /// /// public async Task SendPushAsync(PushPayload payload) { if (payload == null) throw new ArgumentNullException(nameof(payload)); string body = payload.ToString(); return await SendPushAsync(body); } /// /// 进行消息推送。 /// /// /// 推送对象。 public HttpResponse SendPush(PushPayload pushPayload) { Task task = Task.Run(() => SendPushAsync(pushPayload)); task.Wait(); return task.Result; } public async Task IsPushValidAsync(string jsonBody) { if (string.IsNullOrEmpty(jsonBody)) throw new ArgumentNullException(nameof(jsonBody)); HttpContent httpContent = new StringContent(jsonBody, Encoding.UTF8); var url = BASE_URL + "/validate"; HttpResponseMessage msg = await HttpClient.PostAsync(url, httpContent).ConfigureAwait(false); var content = await msg.Content.ReadAsStringAsync().ConfigureAwait(false); return new HttpResponse(msg.StatusCode, msg.Headers, content); } /// /// /// public async Task IsPushValidAsync(PushPayload payload) { if (payload == null) throw new ArgumentNullException(nameof(payload)); var body = payload.ToString(); return await IsPushValidAsync(body); } /// /// 校验推送能否成功。与推送 API 的区别在于:不会实际向用户发送任何消息。 其他字段说明和推送 API 完全相同。 /// /// 推送对象。 public HttpResponse IsPushValid(PushPayload pushPayload) { Task task = Task.Run(() => IsPushValidAsync(pushPayload)); task.Wait(); return task.Result; } /// /// /// public async Task GetCIdListAsync(int? count, string type) { if (count != null && count < 1 && count > 1000) throw new ArgumentOutOfRangeException(nameof(count)); var url = BASE_URL + "/cid"; if (count != null) { url += ("?count=" + count); if (!string.IsNullOrEmpty(type)) url += ("&type=" + type); } HttpResponseMessage msg = await HttpClient.GetAsync(url).ConfigureAwait(false); var content = await msg.Content.ReadAsStringAsync().ConfigureAwait(false); return new HttpResponse(msg.StatusCode, msg.Headers, content); } /// /// 获取 CId(推送的唯一标识符) 列表。 /// /// /// 不传默认为 1。范围为[1, 1000] /// CId 的类型。取值:"push" (默认) 或 "schedule" public HttpResponse GetCIdList(int? count, string type) { Task task = Task.Run(() => GetCIdListAsync(count, type)); task.Wait(); return task.Result; } /// /// 针对RegID方式批量单推(VIP专属接口) /// 如果您在给每个用户的推送内容都不同的情况下,可以使用此接口。 /// /// /// 批量单推的载体列表 public async Task BatchPushByRegidAsync(List singlePayLoadList) { var url = BASE_URL + "/batch/regid/single"; return await BatchPushAsync(url, singlePayLoadList); } /// /// 针对RegID方式批量单推(VIP专属接口) /// 如果您在给每个用户的推送内容都不同的情况下,可以使用此接口。 /// /// /// 批量单推的载体列表 public HttpResponse BatchPushByRegid(List singlePayLoadList) { Task task = Task.Run(() => BatchPushByRegidAsync(singlePayLoadList)); task.Wait(); return task.Result; } /// /// 针对Alias方式批量单推(VIP专属接口) /// 如果您在给每个用户的推送内容都不同的情况下,可以使用此接口。 /// /// /// 批量单推的载体列表 public async Task BatchPushByAliasAsync(List singlePayLoadList) { var url = BASE_URL + "/batch/alias/single"; return await BatchPushAsync(url, singlePayLoadList); } /// /// 针对Alias方式批量单推(VIP专属接口) /// 如果您在给每个用户的推送内容都不同的情况下,可以使用此接口。 /// /// /// 批量单推的载体列表 public HttpResponse BatchPushByAlias(List singlePayLoadList) { Task task = Task.Run(() => BatchPushByAliasAsync(singlePayLoadList)); task.Wait(); return task.Result; } private async Task BatchPushAsync(String url, List singlePayLoadList) { HttpResponse cidResponse = await this.GetCIdListAsync(singlePayLoadList.Count, "push"); JObject jObject = (JObject) JsonConvert.DeserializeObject(cidResponse.Content); JArray jArray = ((JArray) jObject["cidlist"]); BatchPushPayload batchPushPayload = new BatchPushPayload(); batchPushPayload.Pushlist = new Dictionary(); for (int i = 0; i < singlePayLoadList.Count; i++) { batchPushPayload.Pushlist.Add((String) jArray[i], singlePayLoadList[i]); } HttpContent httpContent = new StringContent(batchPushPayload.ToString(), Encoding.UTF8); HttpResponseMessage msg = await HttpClient.PostAsync(url, httpContent).ConfigureAwait(false); var content = await msg.Content.ReadAsStringAsync().ConfigureAwait(false); return new HttpResponse(msg.StatusCode, msg.Headers, content); } } }