基线 SVN r240
SVN-Revision: r240
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
using Lskj.Push.Push;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Common
|
||||
{
|
||||
public class APIRequestException:Exception
|
||||
{
|
||||
|
||||
private ResponseWrapper responseRequest;
|
||||
public APIRequestException(ResponseWrapper responseRequest)
|
||||
: base(responseRequest.exceptionString)
|
||||
{
|
||||
this.responseRequest = responseRequest;
|
||||
}
|
||||
public HttpStatusCode Status
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.responseRequest.responseCode;
|
||||
}
|
||||
}
|
||||
public long MsgId
|
||||
{
|
||||
get
|
||||
{
|
||||
return responseRequest.jpushError.msg_id;
|
||||
}
|
||||
}
|
||||
public int ErrorCode
|
||||
{
|
||||
get
|
||||
{
|
||||
return responseRequest.jpushError.error.code;
|
||||
}
|
||||
}
|
||||
|
||||
public String ErrorMessage
|
||||
{
|
||||
get
|
||||
{
|
||||
return responseRequest.jpushError.error.message;
|
||||
}
|
||||
}
|
||||
private JpushError ErrorObject()
|
||||
{
|
||||
return responseRequest.jpushError;
|
||||
}
|
||||
public int RateLimitQuota()
|
||||
{
|
||||
return responseRequest.rateLimitQuota;
|
||||
}
|
||||
public int RateLimitRemaining()
|
||||
{
|
||||
return responseRequest.rateLimitRemaining;
|
||||
}
|
||||
public int RateLimitReset()
|
||||
{
|
||||
return responseRequest.rateLimitReset;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
using Lskj.Push.Push.Mode;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Common
|
||||
{
|
||||
public class AudienceConverter : JsonConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// Platform whether this instance can convert the specified object type.
|
||||
/// </summary>
|
||||
/// <param name="objectType">Type of the object.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
if (objectType == typeof(Audience))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes the JSON representation of the object.
|
||||
/// </summary>
|
||||
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="serializer">The calling serializer.</param>
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
Audience audience = value as Audience;
|
||||
if (audience == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
audience.Check();
|
||||
if (audience.isAll())
|
||||
{
|
||||
writer.WriteValue(audience.allAudience);
|
||||
//writer.WriteValue("alll");
|
||||
}
|
||||
else
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(audience.dictionary);
|
||||
writer.WriteRawValue(json);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads the JSON representation of the object.
|
||||
/// </summary>
|
||||
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
|
||||
/// <param name="objectType">Type of the object.</param>
|
||||
/// <param name="existingValue">The existing property value of the JSON that is being converted.</param>
|
||||
/// <param name="serializer">The calling serializer.</param>
|
||||
/// <returns>The object value.</returns>
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
Audience audience = Audience.all();
|
||||
if (reader.TokenType == JsonToken.Null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (reader.TokenType == JsonToken.String)
|
||||
{
|
||||
audience.allAudience = reader.Value.ToString();
|
||||
}
|
||||
else if (reader.TokenType == JsonToken.StartObject)
|
||||
{
|
||||
audience.allAudience = null;
|
||||
Dictionary<string, HashSet<string>> dictionary=new Dictionary<string,HashSet<string>>();
|
||||
string key="key";
|
||||
HashSet<string> value=null;
|
||||
while (reader.Read())
|
||||
{
|
||||
Debug.WriteLine("Type:{0},Path:{1}", reader.TokenType, reader.Path);
|
||||
switch (reader.TokenType)
|
||||
{
|
||||
case JsonToken.StartObject:
|
||||
break;
|
||||
case JsonToken.PropertyName:
|
||||
key = reader.Value.ToString();
|
||||
break;
|
||||
case JsonToken.StartArray:
|
||||
value = new HashSet<string>();
|
||||
break;
|
||||
case JsonToken.String:
|
||||
value.Add(reader.Value.ToString());
|
||||
break;
|
||||
case JsonToken.EndArray:
|
||||
{
|
||||
dictionary.Add(key,value);
|
||||
}
|
||||
break;
|
||||
case JsonToken.EndObject:
|
||||
return audience;
|
||||
}
|
||||
}
|
||||
audience.dictionary = dictionary;
|
||||
}
|
||||
return audience;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
using Lskj.Push.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using Newtonsoft.Json;
|
||||
using Lskj.Push.Common.Resp;
|
||||
|
||||
namespace Lskj.Push.Common
|
||||
{
|
||||
class BaseHttpClient
|
||||
{
|
||||
private const String CHARSET = "UTF-8";
|
||||
private const String RATE_LIMIT_QUOTA = "X-Rate-Limit-Limit";
|
||||
private const String RATE_LIMIT_Remaining = "X-Rate-Limit-Remaining";
|
||||
private const String RATE_LIMIT_Reset = "X-Rate-Limit-Reset";
|
||||
|
||||
protected const int RESPONSE_OK = 200;
|
||||
|
||||
//设置连接超时时间
|
||||
private const int DEFAULT_CONNECTION_TIMEOUT = (20 * 1000); // milliseconds
|
||||
//设置读取超时时间
|
||||
private const int DEFAULT_SOCKET_TIMEOUT = (30 * 1000); // milliseconds
|
||||
|
||||
public ResponseWrapper sendPost(String url, String auth, String reqParams)
|
||||
{
|
||||
return this.sendRequest( "POST", url, auth, reqParams);
|
||||
}
|
||||
public ResponseWrapper sendDelete(String url, String auth, String reqParams)
|
||||
{
|
||||
return this.sendRequest("DELETE", url, auth, reqParams);
|
||||
}
|
||||
public ResponseWrapper sendGet(String url, String auth, String reqParams)
|
||||
{
|
||||
return this.sendRequest("GET", url, auth, reqParams);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* method "POST" or "GET"
|
||||
* url
|
||||
* auth 可选
|
||||
*/
|
||||
public ResponseWrapper sendRequest(String method, String url, String auth,String reqParams)
|
||||
{
|
||||
Console.WriteLine("Send request - " + method.ToString() + " " + url + " "+ DateTime.Now);
|
||||
if (null != reqParams)
|
||||
{
|
||||
Console.WriteLine("Request Content - " + reqParams +" "+ DateTime.Now);
|
||||
}
|
||||
ResponseWrapper result = new ResponseWrapper();
|
||||
HttpWebRequest myReq = null;
|
||||
HttpWebResponse response = null;
|
||||
try
|
||||
{
|
||||
myReq = (HttpWebRequest)WebRequest.Create(url);
|
||||
myReq.Method = method;
|
||||
myReq.ContentType = "application/json";
|
||||
if ( !String.IsNullOrEmpty(auth) )
|
||||
{
|
||||
myReq.Headers.Add("Authorization", "Basic " + auth);
|
||||
}
|
||||
if (method == "POST")
|
||||
{
|
||||
byte[] bs = UTF8Encoding.UTF8.GetBytes(reqParams);
|
||||
myReq.ContentLength = bs.Length;
|
||||
using (Stream reqStream = myReq.GetRequestStream())
|
||||
{
|
||||
reqStream.Write(bs, 0, bs.Length);
|
||||
reqStream.Close();
|
||||
}
|
||||
}
|
||||
response = (HttpWebResponse)myReq.GetResponse();
|
||||
HttpStatusCode statusCode = response.StatusCode;
|
||||
result.responseCode = statusCode;
|
||||
if (Equals(response.StatusCode, HttpStatusCode.OK))
|
||||
{
|
||||
using (StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8))
|
||||
{
|
||||
result.responseContent = reader.ReadToEnd();
|
||||
}
|
||||
String limitQuota = response.GetResponseHeader(RATE_LIMIT_QUOTA);
|
||||
String limitRemaining = response.GetResponseHeader(RATE_LIMIT_Remaining);
|
||||
String limitReset = response.GetResponseHeader(RATE_LIMIT_Reset);
|
||||
result.setRateLimit(limitQuota, limitRemaining, limitReset);
|
||||
Console.WriteLine("Succeed to get response - 200 OK" +" "+ DateTime.Now);
|
||||
Console.WriteLine("Response Content - {0}", result.responseContent +" "+ DateTime.Now);
|
||||
}
|
||||
}
|
||||
catch (WebException e)
|
||||
{
|
||||
if (e.Status == WebExceptionStatus.ProtocolError)
|
||||
{
|
||||
HttpStatusCode errorCode = ((HttpWebResponse)e.Response).StatusCode;
|
||||
string statusDescription = ((HttpWebResponse)e.Response).StatusDescription;
|
||||
using (StreamReader sr = new StreamReader(((HttpWebResponse)e.Response).GetResponseStream(), System.Text.Encoding.UTF8))
|
||||
{
|
||||
result.responseContent = sr.ReadToEnd();
|
||||
}
|
||||
result.responseCode = errorCode;
|
||||
result.exceptionString = e.Message;
|
||||
String limitQuota = ((HttpWebResponse)e.Response).GetResponseHeader(RATE_LIMIT_QUOTA);
|
||||
String limitRemaining = ((HttpWebResponse)e.Response).GetResponseHeader(RATE_LIMIT_Remaining);
|
||||
String limitReset = ((HttpWebResponse)e.Response).GetResponseHeader(RATE_LIMIT_Reset);
|
||||
result.setRateLimit(limitQuota, limitRemaining, limitReset);
|
||||
Debug.Print(e.Message);
|
||||
result.setErrorObject();
|
||||
Console.WriteLine(string.Format("fail to get response - {0}", errorCode) + " "+ DateTime.Now);
|
||||
Console.WriteLine(string.Format("Response Content - {0}", result.responseContent) + " "+ DateTime.Now);
|
||||
|
||||
throw new APIRequestException(result);
|
||||
}
|
||||
else
|
||||
{//
|
||||
throw new APIConnectionException(e.Message);
|
||||
}
|
||||
|
||||
}
|
||||
//这里不再抓取非http的异常,如果异常抛出交给开发者自行处理
|
||||
//catch (System.Exception ex)
|
||||
//{
|
||||
// String errorMsg = ex.Message;
|
||||
// Debug.Print(errorMsg);
|
||||
//}
|
||||
finally
|
||||
{
|
||||
if (response != null)
|
||||
{
|
||||
response.Close();
|
||||
}
|
||||
if(myReq != null)
|
||||
{
|
||||
myReq.Abort();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Common
|
||||
{
|
||||
public abstract class BaseResult
|
||||
{
|
||||
public const int ERROR_CODE_NONE = -1;
|
||||
public const int ERROR_CODE_OK = 0;
|
||||
public const String ERROR_MESSAGE_NONE = "None error message.";
|
||||
|
||||
public const int RESPONSE_OK = 200;
|
||||
|
||||
private ResponseWrapper responseResult;
|
||||
|
||||
public ResponseWrapper ResponseResult
|
||||
{
|
||||
get { return responseResult; }
|
||||
set { responseResult = value; }
|
||||
}
|
||||
public abstract bool isResultOK();
|
||||
|
||||
|
||||
|
||||
// public override String getErrorMessage();
|
||||
|
||||
public int getRateLimitQuota() {
|
||||
if (null != responseResult) {
|
||||
return responseResult.rateLimitQuota;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getRateLimitRemaining() {
|
||||
if (null != responseResult) {
|
||||
return responseResult.rateLimitRemaining;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getRateLimitReset() {
|
||||
if (null != responseResult) {
|
||||
return responseResult.rateLimitReset;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
|
||||
|
||||
namespace Lskj.Push.Common
|
||||
{
|
||||
public enum DeviceType
|
||||
{
|
||||
[Description("android")] android,
|
||||
[Description("ios")] ios,
|
||||
[Description("winphone")] winphone
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
using Lskj.Push.Push.Mode;
|
||||
using Lskj.Push.Util;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Common
|
||||
{
|
||||
public class PlatformConverter:JsonConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// Platform whether this instance can convert the specified object type.
|
||||
/// </summary>
|
||||
/// <param name="objectType">Type of the object.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
if (objectType == typeof(Platform))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes the JSON representation of the object.
|
||||
/// </summary>
|
||||
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="serializer">The calling serializer.</param>
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
Platform platform = value as Platform;
|
||||
if (platform == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
platform.Check();
|
||||
if (platform.isAll())
|
||||
{
|
||||
writer.WriteValue(platform.allPlatform);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteStartArray();
|
||||
foreach (var item in platform.deviceTypes)
|
||||
{
|
||||
writer.WriteValue(item);
|
||||
}
|
||||
writer.WriteEndArray();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Reads the JSON representation of the object.
|
||||
/// </summary>
|
||||
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
|
||||
/// <param name="objectType">Type of the object.</param>
|
||||
/// <param name="existingValue">The existing property value of the JSON that is being converted.</param>
|
||||
/// <param name="serializer">The calling serializer.</param>
|
||||
/// <returns>The object value.</returns>
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
Platform platform = Platform.all();
|
||||
if (reader.TokenType == JsonToken.Null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if(reader.TokenType==JsonToken.StartArray)
|
||||
{
|
||||
platform.allPlatform = null;
|
||||
platform.deviceTypes = ReadArray(reader);
|
||||
}
|
||||
else if (reader.TokenType==JsonToken.String)
|
||||
{
|
||||
platform.allPlatform = reader.Value.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return platform;
|
||||
}
|
||||
|
||||
private HashSet<string> ReadArray(JsonReader reader)
|
||||
{
|
||||
HashSet<string> list = new HashSet<string>();
|
||||
while (reader.Read())
|
||||
{
|
||||
switch (reader.TokenType)
|
||||
{
|
||||
case JsonToken.String:
|
||||
list.Add(Convert.ToString(reader.Value, CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case JsonToken.EndArray:
|
||||
return list;
|
||||
case JsonToken.Comment:
|
||||
// skip
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.Serialization.Json;
|
||||
using System.Net;
|
||||
using Lskj.Push.Util;
|
||||
using System.Diagnostics;
|
||||
using Lskj.Push.Push;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Lskj.Push.Common
|
||||
{
|
||||
public class ResponseWrapper
|
||||
{
|
||||
private const int RESPONSE_CODE_NONE = -1;
|
||||
|
||||
//private static Gson _gson = new Gson();
|
||||
public JpushError jpushError;
|
||||
|
||||
public HttpStatusCode responseCode = HttpStatusCode.BadRequest;
|
||||
private String _responseContent;
|
||||
public String responseContent
|
||||
{
|
||||
get
|
||||
{
|
||||
return _responseContent;
|
||||
}
|
||||
set
|
||||
{
|
||||
_responseContent = value;
|
||||
}
|
||||
}
|
||||
public void setErrorObject()
|
||||
{
|
||||
if(!string.IsNullOrEmpty(_responseContent))
|
||||
{
|
||||
jpushError = JsonConvert.DeserializeObject<JpushError>(_responseContent);
|
||||
}
|
||||
}
|
||||
|
||||
public int rateLimitQuota;
|
||||
public int rateLimitRemaining;
|
||||
public int rateLimitReset;
|
||||
|
||||
public bool isServerResponse()
|
||||
{
|
||||
return responseCode == HttpStatusCode.OK;
|
||||
}
|
||||
public String exceptionString;
|
||||
|
||||
public ResponseWrapper() {
|
||||
}
|
||||
public void setRateLimit(String quota, String remaining, String reset) {
|
||||
if (null == quota) return;
|
||||
try
|
||||
{
|
||||
if (quota != "" && StringUtil.IsInt(quota))
|
||||
{
|
||||
rateLimitQuota = int.Parse(quota);
|
||||
}
|
||||
if (remaining!="" && StringUtil.IsInt(remaining))
|
||||
{
|
||||
rateLimitRemaining = int.Parse(remaining);
|
||||
}
|
||||
if (reset!="" && StringUtil.IsInt(reset))
|
||||
{
|
||||
rateLimitReset = int.Parse(reset);
|
||||
}
|
||||
Console.WriteLine(string.Format("JPush API Rate Limiting params - quota:{0}, remaining:{1}, reset:{2} ", quota, remaining, reset) +" "+ DateTime.Now);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Debug.Print(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Common
|
||||
{
|
||||
public class ServiceHelper
|
||||
{
|
||||
private const int MAX_BADGE_NUMBER = 99999;
|
||||
private const int MIN = 100000;
|
||||
private const int MAX = int.MaxValue;
|
||||
|
||||
public static int generateSendno()
|
||||
{
|
||||
Random random = new Random();
|
||||
return random.Next((MAX - MIN) + 1) + MIN;
|
||||
}
|
||||
public static bool isValidIntBadge(int intBadge)
|
||||
{
|
||||
if (intBadge >= 0 && intBadge <= MAX_BADGE_NUMBER)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Common
|
||||
{
|
||||
public enum TimeUnit
|
||||
{
|
||||
|
||||
HOUR,
|
||||
DAY,
|
||||
MONTH
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Common.Resp
|
||||
{
|
||||
public class APIConnectionException:Exception
|
||||
{
|
||||
public APIConnectionException(String message):base(message)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Common.Resp
|
||||
{
|
||||
public class BooleanResult : DefaultResult
|
||||
{
|
||||
public bool result;
|
||||
new public static BooleanResult fromResponse(ResponseWrapper responseWrapper)
|
||||
{
|
||||
BooleanResult tagListResult = new BooleanResult();
|
||||
if (responseWrapper.isServerResponse())
|
||||
{
|
||||
tagListResult = JsonConvert.DeserializeObject<BooleanResult>(responseWrapper.responseContent);
|
||||
}
|
||||
tagListResult.ResponseResult = responseWrapper;
|
||||
return tagListResult;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Common.Resp
|
||||
{
|
||||
public class DefaultResult:BaseResult
|
||||
{
|
||||
|
||||
public static DefaultResult fromResponse(ResponseWrapper responseWrapper)
|
||||
{
|
||||
DefaultResult result = null;
|
||||
|
||||
if (responseWrapper.isServerResponse())
|
||||
{
|
||||
result = new DefaultResult();
|
||||
}
|
||||
|
||||
result.ResponseResult=responseWrapper;
|
||||
|
||||
return result;
|
||||
}
|
||||
public override bool isResultOK()
|
||||
{
|
||||
if (Equals(ResponseResult.responseCode, HttpStatusCode.OK))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using Lskj.Push.Common;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Device
|
||||
{
|
||||
public class AliasDeviceListResult:BaseResult
|
||||
{
|
||||
public List<String> registration_ids ;
|
||||
public AliasDeviceListResult()
|
||||
{
|
||||
registration_ids = null;
|
||||
}
|
||||
public override bool isResultOK()
|
||||
{
|
||||
if (Equals(ResponseResult.responseCode, HttpStatusCode.OK))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static AliasDeviceListResult fromResponse(ResponseWrapper responseWrapper)
|
||||
{
|
||||
AliasDeviceListResult aliasDeviceListResult = new AliasDeviceListResult();
|
||||
if (responseWrapper.isServerResponse())
|
||||
{
|
||||
aliasDeviceListResult = JsonConvert.DeserializeObject<AliasDeviceListResult>(responseWrapper.responseContent);
|
||||
}
|
||||
aliasDeviceListResult.ResponseResult = responseWrapper;
|
||||
return aliasDeviceListResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
using Lskj.Push.Common;
|
||||
using Lskj.Push.Common.Resp;
|
||||
using Lskj.Push.Util;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Device
|
||||
{
|
||||
class DeviceClient : BaseHttpClient
|
||||
{
|
||||
public const String HOST_NAME_SSL = "https://device.jpush.cn";
|
||||
public const String DEVICES_PATH = "/v3/devices";
|
||||
public const String TAGS_PATH = "/v3/tags";
|
||||
public const String ALIASES_PATH = "/v3/aliases";
|
||||
|
||||
private String appKey;
|
||||
private String masterSecret;
|
||||
public DeviceClient(String appKey, String masterSecret)
|
||||
{
|
||||
this.appKey = appKey;
|
||||
this.masterSecret = masterSecret;
|
||||
}
|
||||
public TagAliasResult getDeviceTagAlias(String registrationId)
|
||||
{
|
||||
String url = HOST_NAME_SSL + DEVICES_PATH + "/" + registrationId;
|
||||
String auth = Base64.getBase64Encode(this.appKey + ":" + this.masterSecret);
|
||||
|
||||
ResponseWrapper response = this.sendGet(url, auth, null);
|
||||
|
||||
return TagAliasResult.fromResponse(response);
|
||||
|
||||
}
|
||||
public DefaultResult updateDeviceTagAlias(String registrationId, bool clearAlias, bool clearTag)
|
||||
{
|
||||
Preconditions.checkArgument(clearAlias || clearTag, "It is not meaningful to do nothing.");
|
||||
|
||||
String url = HOST_NAME_SSL + DEVICES_PATH + "/" + registrationId;
|
||||
|
||||
JObject top = new JObject();
|
||||
if (clearAlias) {
|
||||
top.Add("alias", "");
|
||||
}
|
||||
if (clearTag) {
|
||||
top.Add("tags", "");
|
||||
}
|
||||
ResponseWrapper result = sendPost(url, Authorization(), top.ToString());
|
||||
|
||||
return DefaultResult.fromResponse(result);
|
||||
}
|
||||
public DefaultResult updateDeviceTagAlias(String registrationId,
|
||||
String alias,
|
||||
HashSet<String> tagsToAdd,
|
||||
HashSet<String> tagsToRemove)
|
||||
{
|
||||
String url = HOST_NAME_SSL + DEVICES_PATH + "/" + registrationId;
|
||||
|
||||
JObject top = new JObject();
|
||||
if (null != alias) {
|
||||
top.Add("alias", alias);
|
||||
}
|
||||
|
||||
JObject tagObject = new JObject();
|
||||
if (tagsToAdd!=null)
|
||||
{
|
||||
JArray tagsAdd = JArray.FromObject(tagsToAdd);
|
||||
if (tagsAdd.Count > 0)
|
||||
{
|
||||
tagObject.Add("add", tagsAdd);
|
||||
}
|
||||
}
|
||||
if (tagsToRemove != null)
|
||||
{
|
||||
|
||||
JArray tagsRemove = JArray.FromObject(tagsToRemove);
|
||||
if (tagsRemove.Count > 0)
|
||||
{
|
||||
tagObject.Add("remove", tagsRemove);
|
||||
}
|
||||
}
|
||||
|
||||
if (tagObject.Count > 0) {
|
||||
top.Add("tags", tagObject);
|
||||
}
|
||||
ResponseWrapper result = sendPost(url, Authorization(), top.ToString());
|
||||
|
||||
return DefaultResult.fromResponse(result);
|
||||
}
|
||||
public TagListResult getTagList()
|
||||
{
|
||||
String url = HOST_NAME_SSL + TAGS_PATH + "/";
|
||||
String auth = Base64.getBase64Encode(this.appKey + ":" + this.masterSecret);
|
||||
ResponseWrapper response = this.sendGet(url, auth, null);
|
||||
return TagListResult.fromResponse(response);
|
||||
}
|
||||
|
||||
public BooleanResult isDeviceInTag(String theTag, String registrationID)
|
||||
{
|
||||
String url = HOST_NAME_SSL + TAGS_PATH + "/" + theTag + "/registration_ids/" + registrationID;
|
||||
ResponseWrapper response = this.sendGet(url, Authorization(), null);
|
||||
return BooleanResult.fromResponse(response);
|
||||
}
|
||||
public DefaultResult addRemoveDevicesFromTag(String theTag,
|
||||
HashSet<String> toAddUsers,
|
||||
HashSet<String> toRemoveUsers)
|
||||
{
|
||||
String url = HOST_NAME_SSL + TAGS_PATH + "/" + theTag;
|
||||
|
||||
JObject top = new JObject();
|
||||
JObject registrationIds = new JObject();
|
||||
if (null != toAddUsers && toAddUsers.Count > 0)
|
||||
{
|
||||
JArray array = new JArray();
|
||||
foreach (String user in toAddUsers) {
|
||||
array.Add(JToken.FromObject(user));
|
||||
}
|
||||
registrationIds.Add("add", array);
|
||||
}
|
||||
if (null != toRemoveUsers && toRemoveUsers.Count > 0)
|
||||
{
|
||||
JArray array = new JArray();
|
||||
foreach (String user in toRemoveUsers)
|
||||
{
|
||||
array.Add(JToken.FromObject(user));
|
||||
}
|
||||
registrationIds.Add("remove", array);
|
||||
}
|
||||
top.Add("registration_ids", registrationIds);
|
||||
ResponseWrapper response = this.sendPost(url, Authorization(), top.ToString());
|
||||
return DefaultResult.fromResponse(response);
|
||||
}
|
||||
|
||||
public DefaultResult deleteTag(String theTag, String platform)
|
||||
{
|
||||
String url = HOST_NAME_SSL + TAGS_PATH + "/" + theTag;
|
||||
if (null != platform) {
|
||||
url += "?platform=" + platform;
|
||||
}
|
||||
|
||||
ResponseWrapper response = this.sendDelete(url, Authorization(), null);
|
||||
return DefaultResult.fromResponse(response);
|
||||
}
|
||||
// ------------- alias
|
||||
|
||||
public AliasDeviceListResult getAliasDeviceList(String alias, String platform)
|
||||
{
|
||||
String url = HOST_NAME_SSL + ALIASES_PATH + "/" + alias;
|
||||
if (null != platform) {
|
||||
url += "?platform=" + platform;
|
||||
}
|
||||
ResponseWrapper response = this.sendGet(url, Authorization(), null);
|
||||
|
||||
return AliasDeviceListResult.fromResponse(response);
|
||||
}
|
||||
public DefaultResult deleteAlias(String alias, String platform)
|
||||
{
|
||||
String url = HOST_NAME_SSL + ALIASES_PATH + "/" + alias;
|
||||
if (null != platform) {
|
||||
url += "?platform=" + platform;
|
||||
}
|
||||
ResponseWrapper response = this.sendDelete(url, Authorization(), null);
|
||||
return DefaultResult.fromResponse(response);
|
||||
}
|
||||
private String Authorization()
|
||||
{
|
||||
Debug.Assert(!string.IsNullOrEmpty(this.appKey));
|
||||
Debug.Assert(!string.IsNullOrEmpty(this.masterSecret));
|
||||
String origin = this.appKey + ":" + this.masterSecret;
|
||||
return Base64.getBase64Encode(origin);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using Lskj.Push.Common;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Device
|
||||
{
|
||||
public class TagAliasResult:BaseResult
|
||||
{
|
||||
public List<String> tags;
|
||||
public String alias;
|
||||
|
||||
public TagAliasResult()
|
||||
{
|
||||
tags = null;
|
||||
alias = null;
|
||||
}
|
||||
public override bool isResultOK()
|
||||
{
|
||||
if (Equals(ResponseResult.responseCode, HttpStatusCode.OK))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static TagAliasResult fromResponse(ResponseWrapper responseWrapper)
|
||||
{
|
||||
TagAliasResult tagAliasResult = new TagAliasResult();
|
||||
if (responseWrapper.isServerResponse())
|
||||
{
|
||||
tagAliasResult = JsonConvert.DeserializeObject<TagAliasResult>(responseWrapper.responseContent);
|
||||
}
|
||||
tagAliasResult.ResponseResult = responseWrapper;
|
||||
return tagAliasResult;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using Lskj.Push.Common;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Device
|
||||
{
|
||||
public class TagListResult:BaseResult
|
||||
{
|
||||
public List<String> tags ;
|
||||
public TagListResult()
|
||||
{
|
||||
tags = null;
|
||||
}
|
||||
public override bool isResultOK()
|
||||
{
|
||||
if (Equals(ResponseResult.responseCode, HttpStatusCode.OK))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static TagListResult fromResponse(ResponseWrapper responseWrapper)
|
||||
{
|
||||
TagListResult tagListResult = new TagListResult();
|
||||
if (responseWrapper.isServerResponse())
|
||||
{
|
||||
tagListResult = JsonConvert.DeserializeObject<TagListResult>(responseWrapper.responseContent);
|
||||
}
|
||||
tagListResult.ResponseResult = responseWrapper;
|
||||
return tagListResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,595 @@
|
||||
using Lskj.Push.Push.Mode;
|
||||
using Lskj.Push.Push.Notification;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push
|
||||
{
|
||||
/// <summary>
|
||||
/// JPush Api 常用方法,特殊的单独参考文档(http://docs.jpush.io/server/csharp_sdk/)
|
||||
/// </summary>
|
||||
public class JPushApi
|
||||
{
|
||||
#region Android相关API
|
||||
/// <summary>
|
||||
/// 发送所有人(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_All_Content(string content)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.all();
|
||||
pushPayload.notification = new Notification().setAlert(content);
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送所有人(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="extras">附加信息(object:只支持基本类型)</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_All_Content(string content, Dictionary<string, object> extras)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.all();
|
||||
pushPayload.notification = new Notification().setAlert(content);
|
||||
foreach (var item in extras)
|
||||
{
|
||||
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
|
||||
}
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送所有人(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="title">发送标题</param>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_All_TitleWithContent(string title,string content)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.all();
|
||||
pushPayload.notification = Notification.android(content, title);
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送所有人(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="title">发送标题</param>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="extras">附加信息(object:只支持基本类型)</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_All_TitleWithContent(string title, string content, Dictionary<string, object> extras)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.all();
|
||||
pushPayload.notification = Notification.android(content, title);
|
||||
foreach (var item in extras)
|
||||
{
|
||||
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
|
||||
}
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送消息
|
||||
/// </summary>
|
||||
/// <param name="content">发送内容(必填,不能为空)</param>
|
||||
/// <param name="extras">附加信息(object:只支持基本类型)</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Message(string content, string alias, Dictionary<string, object> extras)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_alias(alias);
|
||||
pushPayload.message = Message.content(content);
|
||||
foreach (var item in extras)
|
||||
{
|
||||
pushPayload.message.AddExtras(item.Key, item.Value);
|
||||
}
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定终端(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="alias">指定终端,现为操作员ID</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Alias_Content(string content, string alias)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_alias(alias);
|
||||
pushPayload.notification = new Notification().setAlert(content);
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定终端(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="alias">指定多个终端,现为操作员ID</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Alias_Content(string content, string[] alias)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_alias(alias);
|
||||
pushPayload.notification = new Notification().setAlert(content);
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定终端(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="alias">终端HashSet</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Alias_Content(string content, HashSet<string> alias)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_alias(alias);
|
||||
pushPayload.notification = new Notification().setAlert(content);
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定终端(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="alias">指定多个终端,现为操作员ID</param>
|
||||
/// <param name="extras">附加信息(object:只支持基本类型)</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Alias_Content(string content, string alias, Dictionary<string, object> extras)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_alias(alias);
|
||||
pushPayload.notification = new Notification().setAlert(content);
|
||||
foreach (var item in extras)
|
||||
{
|
||||
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
|
||||
}
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定终端(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="alias">指定多个终端,现为操作员ID</param>
|
||||
/// <param name="extras">附加信息(object:只支持基本类型)</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Alias_Content(string content, string[] alias, Dictionary<string, object> extras)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_alias(alias);
|
||||
pushPayload.notification = new Notification().setAlert(content);
|
||||
foreach (var item in extras)
|
||||
{
|
||||
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
|
||||
}
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定终端(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="alias">终端HashSet</param>
|
||||
/// <param name="extras">附加信息(object:只支持基本类型)</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Alias_Content(string content, HashSet<string> alias, Dictionary<string, object> extras)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_alias(alias);
|
||||
pushPayload.notification = new Notification().setAlert(content);
|
||||
foreach (var item in extras)
|
||||
{
|
||||
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
|
||||
}
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定终端(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="title">发送标题</param>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="alias">指定终端,现为操作员ID</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Alias_TitleWithContent(string title, string content, string alias)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_alias(alias);
|
||||
pushPayload.notification = Notification.android(content, title);
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定终端(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="title">发送标题</param>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="alias">指定终端,现为操作员ID</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Alias_TitleWithContent(string title, string content, string[] alias)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_alias(alias);
|
||||
pushPayload.notification = Notification.android(content, title);
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定终端(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="title">发送标题</param>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="alias">指定终端,现为操作员ID</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Alias_TitleWithContent(string title, string content, HashSet<string> alias)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_alias(alias);
|
||||
pushPayload.notification = Notification.android(content, title);
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定终端(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="title">发送标题</param>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="alias">指定终端,现为操作员ID</param>
|
||||
/// <param name="extras">附加信息(object:只支持基本类型)</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Alias_TitleWithContent(string title, string content, string alias, Dictionary<string, object> extras)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_alias(alias);
|
||||
pushPayload.notification = Notification.android(content, title);
|
||||
foreach (var item in extras)
|
||||
{
|
||||
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
|
||||
}
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定终端(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="title">发送标题</param>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="alias">指定终端,现为操作员ID</param>
|
||||
/// <param name="extras">附加信息(object:只支持基本类型)</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Alias_TitleWithContent(string title, string content, string[] alias, Dictionary<string, object> extras)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_alias(alias);
|
||||
pushPayload.notification = Notification.android(content, title);
|
||||
foreach (var item in extras)
|
||||
{
|
||||
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
|
||||
}
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定终端(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="title">发送标题</param>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="alias">指定终端,现为操作员ID</param>
|
||||
/// <param name="extras">附加信息(object:只支持基本类型)</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Alias_TitleWithContent(string title, string content, HashSet<string> alias, Dictionary<string, object> extras)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_alias(alias);
|
||||
pushPayload.notification = Notification.android(content, title);
|
||||
foreach (var item in extras)
|
||||
{
|
||||
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
|
||||
}
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送消息
|
||||
/// </summary>
|
||||
/// <param name="content">发送内容(必填,不能为空)</param>
|
||||
/// <param name="extras">附加信息(object:只支持基本类型)</param>
|
||||
/// <param name="alias">指定终端,现为操作员ID</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Alias_Message(string content, Dictionary<string, object> extras, params string[] alias)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_alias(alias);
|
||||
pushPayload.message = Message.content(content);
|
||||
foreach (var item in extras)
|
||||
{
|
||||
pushPayload.message.AddExtras(item.Key, item.Value);
|
||||
}
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定群组(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="tags">群组标签</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Tags_Title(string content, string tags)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_tag(tags);
|
||||
pushPayload.notification = new Notification().setAlert(content);
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定群组(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="tags">群组标签</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Tags_Title(string content, string[] tags)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_tag(tags);
|
||||
pushPayload.notification = new Notification().setAlert(content);
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定群组(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="tags">群组标签</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Tags_Title(string content, HashSet<string> tags)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_tag(tags);
|
||||
pushPayload.notification = new Notification().setAlert(content);
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定群组(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="tags">群组标签</param>
|
||||
/// <param name="extras">附加信息(object:只支持基本类型)</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Tags_Title(string content, string tags, Dictionary<string, object> extras)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_tag(tags);
|
||||
pushPayload.notification = new Notification().setAlert(content);
|
||||
foreach (var item in extras)
|
||||
{
|
||||
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
|
||||
}
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定群组(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="tags">群组标签</param>
|
||||
/// <param name="extras">附加信息(object:只支持基本类型)</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Tags_Title(string content, string[] tags, Dictionary<string, object> extras)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_tag(tags);
|
||||
pushPayload.notification = new Notification().setAlert(content);
|
||||
foreach (var item in extras)
|
||||
{
|
||||
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
|
||||
}
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定群组(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="tags">群组标签</param>
|
||||
/// <param name="extras">附加信息(object:只支持基本类型)</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Tags_Title(string content, HashSet<string> tags, Dictionary<string, object> extras)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_tag(tags);
|
||||
pushPayload.notification = new Notification().setAlert(content);
|
||||
foreach (var item in extras)
|
||||
{
|
||||
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
|
||||
}
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定群组(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="title">发送标题</param>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="tags">群组标签</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Tags_TileWithContent(string title, string content, string tags)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_tag(tags);
|
||||
pushPayload.notification = Notification.android(content, title);
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定群组(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="title">发送标题</param>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="tags">群组标签数组</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Tags_TileWithContent(string title, string content, string[] tags)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_tag(tags);
|
||||
pushPayload.notification = Notification.android(content, title);
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定群组(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="title">发送标题</param>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="tags">群组标签集合</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Tags_TileWithContent(string title, string content, HashSet<string> tags)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_tag(tags);
|
||||
pushPayload.notification = Notification.android(content, title);
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定群组(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="title">发送标题</param>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="tags">群组标签</param>
|
||||
/// <param name="extras">附加信息(object:只支持基本类型)</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Tags_TileWithContent(string title, string content, string tags, Dictionary<string, object> extras)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_tag(tags);
|
||||
pushPayload.notification = Notification.android(content, title);
|
||||
foreach (var item in extras)
|
||||
{
|
||||
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
|
||||
}
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定群组(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="title">发送标题</param>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="tags">群组标签数组</param>
|
||||
/// <param name="extras">附加信息(object:只支持基本类型)</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Tags_TileWithContent(string title, string content, string[] tags, Dictionary<string, object> extras)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_tag(tags);
|
||||
pushPayload.notification = Notification.android(content, title);
|
||||
foreach (var item in extras)
|
||||
{
|
||||
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
|
||||
}
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送指定群组(Android终端)
|
||||
/// </summary>
|
||||
/// <param name="title">发送标题</param>
|
||||
/// <param name="content">发送内容</param>
|
||||
/// <param name="tags">群组标签集合</param>
|
||||
/// <param name="extras">附加信息(object:只支持基本类型)</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Tags_TileWithContent(string title, string content, HashSet<string> tags, Dictionary<string, object> extras)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_tag(tags);
|
||||
pushPayload.notification = Notification.android(content, title);
|
||||
foreach (var item in extras)
|
||||
{
|
||||
pushPayload.notification.AndroidNotification.AddExtra(item.Key, item.Value);
|
||||
}
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送消息
|
||||
/// </summary>
|
||||
/// <param name="content">发送内容(必填,不能为空)</param>
|
||||
/// <param name="extras">附加信息(object:只支持基本类型)</param>
|
||||
/// <param name="alias">指定终端,现为操作员ID</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Android_Tags_Message(string content, Dictionary<string, object> extras, params string[] alias)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android();
|
||||
pushPayload.audience = Audience.s_tag(alias);
|
||||
pushPayload.message = Message.content(content);
|
||||
foreach (var item in extras)
|
||||
{
|
||||
pushPayload.message.AddExtras(item.Key, item.Value);
|
||||
}
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置标签别名
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Audience PushObject_Android_SetAlias(string[] alias) {
|
||||
return Audience.s_alias(alias);
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置标签
|
||||
/// </summary>
|
||||
/// <param name="tag"></param>
|
||||
/// <returns></returns>
|
||||
public static Audience PushObject_Android_SetTag(string[] tag) {
|
||||
return Audience.s_tag(tag);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Ios 推送相关
|
||||
public static PushPayload PushObject_Ios_Alias_TitleWithContent(string title, string content, string alias, Dictionary<string, object> extras)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.android_ios();
|
||||
pushPayload.audience = Audience.s_alias(alias);
|
||||
pushPayload.notification = Notification.ios(content);
|
||||
foreach (var item in extras)
|
||||
{
|
||||
pushPayload.notification.IosNotification.AddExtra(item.Key, item.Value);
|
||||
}
|
||||
return pushPayload;
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送消息
|
||||
/// </summary>
|
||||
/// <param name="content">发送内容(必填,不能为空)</param>
|
||||
/// <param name="extras">附加信息(object:只支持基本类型)</param>
|
||||
/// <returns></returns>
|
||||
public static PushPayload PushObject_Ios_Message(string content, string alias, Dictionary<string, object> extras)
|
||||
{
|
||||
PushPayload pushPayload = new PushPayload();
|
||||
pushPayload.platform = Platform.ios();
|
||||
pushPayload.audience = Audience.s_alias(alias);
|
||||
pushPayload.message = Message.content(content);
|
||||
foreach (var item in extras)
|
||||
{
|
||||
pushPayload.message.AddExtras(item.Key, item.Value);
|
||||
}
|
||||
return pushPayload;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
using Lskj.Push.Common;
|
||||
using Lskj.Push.Common.Resp;
|
||||
using Lskj.Push.Device;
|
||||
using Lskj.Push.Push;
|
||||
using Lskj.Push.Push.Mode;
|
||||
using Lskj.Push.Report;
|
||||
using Lskj.Push.Util;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push
|
||||
{
|
||||
/// <summary>
|
||||
/// Main Entrance - 该类为JPush服务的主要入口
|
||||
/// </summary>
|
||||
public class JPushClient
|
||||
{
|
||||
private PushClient _pushClient;
|
||||
private ReportClient _reportClient;
|
||||
private DeviceClient _deviceClient;
|
||||
/// <summary>
|
||||
/// 带两个参数的构造函数,该状态下,ApnsProduction默认为false
|
||||
/// </summary>
|
||||
/// <param name="app_key">Portal上产生的app_key</param>
|
||||
/// <param name="masterSecret">你的API MasterSecret</param>
|
||||
public JPushClient(String app_key, String masterSecret)
|
||||
{
|
||||
_pushClient = new PushClient(app_key, masterSecret);
|
||||
_reportClient = new ReportClient(app_key, masterSecret);
|
||||
_deviceClient = new DeviceClient(app_key, masterSecret);
|
||||
}
|
||||
// ----------------------------- Push API
|
||||
/// <summary>
|
||||
/// 想某个设备或者某设别列表推送一条通知,或者消息
|
||||
/// </summary>
|
||||
/// <param name="PushPayload">推送的数据结构,包含平台信息推送目标,通知内容,消息内容与可选参数</param>
|
||||
/// <returns>成功时返回sendno和messageid,失败时有异常抛出</returns>
|
||||
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
|
||||
/// <exception cref="APIConnectionException">包含错误的信息</exception>
|
||||
/// <see cref="http://docs.jpush.cn/display/dev/Push-API-v3"/>
|
||||
public MessageResult SendPush(PushPayload payload)
|
||||
{
|
||||
Preconditions.checkArgument(payload != null, "pushPayload should not be empty");
|
||||
return _pushClient.sendPush(payload);
|
||||
}
|
||||
/// <summary>
|
||||
/// 想某个设备或者某设别列表推送一条通知,或者消息
|
||||
/// </summary>
|
||||
/// <param name="PushPayload">推送的json结构,包含平台信息推送目标,通知内容,消息内容与可选参数</param>
|
||||
/// <returns>成功时返回sendno和messageid,失败时有异常抛出</returns>
|
||||
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
|
||||
/// <exception cref="APIConnectionException">包含错误的信息</exception>
|
||||
/// <see cref="http://docs.jpush.cn/display/dev/Push-API-v3"/>
|
||||
public MessageResult SendPush(string payloadString)
|
||||
{
|
||||
Preconditions.checkArgument(!string.IsNullOrEmpty(payloadString), "payloadString should not be empty");
|
||||
return _pushClient.sendPush(payloadString);
|
||||
}
|
||||
// ------------------------------- Report API
|
||||
/// <summary>
|
||||
/// Get received report.
|
||||
/// </summary>
|
||||
/// <param name="msgIds">100 msgids to batch getting is supported.</param>
|
||||
/// <returns> Can be printed to JSON.</returns>
|
||||
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
|
||||
/// <exception cref="APIConnectionException">包含错误的信息</exception>
|
||||
/// <see cref="100 msgids to batch getting is supported."/>
|
||||
public ReceivedResult getReceivedApi(String msg_ids)
|
||||
{
|
||||
return _reportClient.getReceiveds(msg_ids);
|
||||
}
|
||||
/// <summary>
|
||||
/// Get received report v3.
|
||||
/// </summary>
|
||||
/// <param name="msgIds">100 msgids to batch getting is supported.</param>
|
||||
///
|
||||
public ReceivedResult getReceivedApi_v3(String msg_ids)
|
||||
{
|
||||
return _reportClient.getReceiveds_v3(msg_ids);
|
||||
}
|
||||
/// <summary>
|
||||
/// 用户统计查询接口,这个接口是vip用户专用
|
||||
/// </summary>
|
||||
/// <param name="timeUnit">时间单位,有三个取值:HOUR、DAY、MONTH</param>
|
||||
/// <param name="start">起始时间</param>
|
||||
/// <param name="duration">持续时间</param>
|
||||
/// <returns>包含ios android的用户情况</returns>
|
||||
public UsersResult getReportUsers(TimeUnit timeUnit, String start, int duration)
|
||||
{
|
||||
return _reportClient.getUsers(timeUnit, start, duration);
|
||||
}
|
||||
/// <summary>
|
||||
/// 消息统计查询接口,这个接口是vip用户专用
|
||||
/// </summary>
|
||||
/// <param name="msgIds">用逗号分隔的多个消息id</param>
|
||||
/// <returns>包含各个mssageid和ios android平台</returns>
|
||||
public MessagesResult getReportMessages(params String[] msgIds)
|
||||
{
|
||||
return _reportClient.getReportMessages(msgIds);
|
||||
}
|
||||
// ------------------------------- Device API
|
||||
/// <summary>
|
||||
/// 获取当前设备的所有属性,包含tags,alias
|
||||
/// </summary>
|
||||
/// <param name="registrationId">设备的registrationID</param>
|
||||
/// <returns>找不到的统计项是null,否则为统计项的值</returns>
|
||||
public TagAliasResult getDeviceTagAlias(String registrationId)
|
||||
{
|
||||
return _deviceClient.getDeviceTagAlias(registrationId);
|
||||
}
|
||||
/// <summary>
|
||||
/// 清理当前设备指定的属性,当前支持tags,alias
|
||||
/// </summary>
|
||||
/// <param name="clearAlias">是否清除alias</param>
|
||||
/// <param name="clearTag">是否清除tags</param>
|
||||
/// <returns>找不到的统计项是null,否则为统计项的值</returns>
|
||||
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
|
||||
/// <exception cref="APIConnectionException">包含错误的信息</exception>
|
||||
/// <see cref="http://docs.jpush.cn/display/dev/Device-API"/>
|
||||
public DefaultResult updateDeviceTagAlias(String registrationId, bool clearAlias, bool clearTag)
|
||||
{
|
||||
return _deviceClient.updateDeviceTagAlias(registrationId, clearAlias, clearTag);
|
||||
}
|
||||
/// <summary>
|
||||
/// 更新当前设备指定的属性,当前支持tags,alias
|
||||
/// </summary>
|
||||
/// <param name="alias">alias名称,传递null:不改变,传递"":清空</param>
|
||||
/// <param name="tagsToAdd">新添加的tags</param>
|
||||
/// <param name="tagsToRemove">删除的tags</param>
|
||||
/// <returns>更新成功时isResultOK==true</returns>
|
||||
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
|
||||
/// <exception cref="APIConnectionException">包含错误的信息</exception>
|
||||
/// <see cref="http://docs.jpush.cn/display/dev/Device-API"/>
|
||||
public DefaultResult updateDeviceTagAlias(String registrationId,
|
||||
String alias,
|
||||
HashSet<String> tagsToAdd,
|
||||
HashSet<String> tagsToRemove)
|
||||
{
|
||||
return _deviceClient.updateDeviceTagAlias(registrationId, alias, tagsToAdd, tagsToRemove);
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取当前应用的所有标签
|
||||
/// </summary>
|
||||
/// <returns>标签列表</returns>
|
||||
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
|
||||
/// <exception cref="APIConnectionException">包含错误的信息</exception>
|
||||
/// <see cref="http://docs.jpush.cn/display/dev/Device-API"/>
|
||||
public TagListResult getTagList()
|
||||
{
|
||||
return _deviceClient.getTagList();
|
||||
}
|
||||
/// <summary>
|
||||
/// 查询某个设备是否在tag下
|
||||
/// </summary>
|
||||
/// <param name="theTag">查询的tag </param>
|
||||
/// <param name="registrationID">需要确认的设备的registrationID</param>
|
||||
/// <returns>成功result=true,失败result=false</returns>
|
||||
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
|
||||
/// <exception cref="APIConnectionException">包含错误的信息</exception>
|
||||
/// <see cref="http://docs.jpush.cn/display/dev/Device-API"/>
|
||||
public BooleanResult isDeviceInTag(String theTag, String registrationID)
|
||||
{
|
||||
return _deviceClient.isDeviceInTag(theTag, registrationID);
|
||||
}
|
||||
/// <summary>
|
||||
/// 为一个标签添加或者删除设备
|
||||
/// </summary>
|
||||
/// <param name="theTag">操作的tag </param>
|
||||
/// <param name="toAddUsers">需要添加的registrationID的集合</param>
|
||||
/// <param name="toRemoveUsers">需要删除的registrationID的集合</param>
|
||||
/// <returns>成功isResultOK()=true,失败isResultOK()=false</returns>
|
||||
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
|
||||
/// <exception cref="APIConnectionException">包含错误的信息</exception>
|
||||
/// <see cref="http://docs.jpush.cn/display/dev/Device-API"/>
|
||||
public DefaultResult addRemoveDevicesFromTag(String theTag,
|
||||
HashSet<String> toAddUsers,
|
||||
HashSet<String> toRemoveUsers)
|
||||
{
|
||||
return _deviceClient.addRemoveDevicesFromTag(theTag, toAddUsers, toRemoveUsers);
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除一个标签,以及标签与设备之间的关联关系
|
||||
/// </summary>
|
||||
/// <param name="theTag">要删除的tag </param>
|
||||
/// <param name="platform">可选参数,不填则默认为所有平台</param>
|
||||
/// <returns>成功result=true,失败result=false</returns>
|
||||
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
|
||||
/// <exception cref="APIConnectionException">包含错误的信息</exception>
|
||||
/// <see cref="http://docs.jpush.cn/display/dev/Device-API"/>
|
||||
public DefaultResult deleteTag(String theTag, String platform)
|
||||
{
|
||||
return _deviceClient.deleteTag(theTag, platform);
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 查询别名
|
||||
/// </summary>
|
||||
/// <param name="alias">要查询的别名 </param>
|
||||
/// <param name="platform">可选参数,不填则默认为所有平台</param>
|
||||
/// <returns>返回alias的列表</returns>
|
||||
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
|
||||
/// <exception cref="APIConnectionException">包含错误的信息</exception>
|
||||
/// <see cref="http://docs.jpush.cn/display/dev/Device-API"/>
|
||||
public AliasDeviceListResult getAliasDeviceList(String alias, String platform)
|
||||
{
|
||||
return _deviceClient.getAliasDeviceList(alias, platform);
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除别名,以及该别名与设别之间的绑定关系
|
||||
/// </summary>
|
||||
/// <param name="alias">要删除的别名 </param>
|
||||
/// <param name="platform">可选参数,不填则默认为所有平台</param>
|
||||
/// <returns>成功isResultOK()=true,失败isResultOK()=false</returns>
|
||||
/// <exception cref="APIRequestException">包含http错误码:如401,404等,错误信息,JPush returen code和JPush returen mssage</exception>
|
||||
/// <exception cref="APIConnectionException">包含错误的信息</exception>
|
||||
/// <see cref="http://docs.jpush.cn/display/dev/Device-API"/>
|
||||
public DefaultResult deleteAlias(String alias, String platform)
|
||||
{
|
||||
return _deviceClient.deleteAlias(alias, platform);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{D77C7B9E-3694-400D-BEE7-AFC99E63E55B}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Lskj.Push</RootNamespace>
|
||||
<AssemblyName>Lskj.Push</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DocumentationFile>..\..\Debug\AllMethodXml\Lskj.Push.XML</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<StartupObject />
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\引用DLL\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Net" />
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.Web.Extensions" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Common\APIRequestException.cs" />
|
||||
<Compile Include="Common\AudienceConverter.cs" />
|
||||
<Compile Include="Common\BaseHttpClient.cs" />
|
||||
<Compile Include="Common\BaseResult.cs" />
|
||||
<Compile Include="Common\DeviceType.cs" />
|
||||
<Compile Include="Common\PlatformConverter.cs" />
|
||||
<Compile Include="Common\ResponseWrapper.cs" />
|
||||
<Compile Include="Common\resp\APIConnectionException.cs" />
|
||||
<Compile Include="Common\resp\BooleanResult.cs" />
|
||||
<Compile Include="Common\resp\DefaultResult.cs" />
|
||||
<Compile Include="Common\ServiceHelper.cs" />
|
||||
<Compile Include="Common\TimeUnit.cs" />
|
||||
<Compile Include="Device\AliasDeviceListResult.cs" />
|
||||
<Compile Include="Device\DeviceClient.cs" />
|
||||
<Compile Include="Device\TagAliasResult.cs" />
|
||||
<Compile Include="Device\TagListResult.cs" />
|
||||
<Compile Include="JPushApi.cs" />
|
||||
<Compile Include="JPushClient.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Push\Audience\AudienceTarget.cs" />
|
||||
<Compile Include="Push\Audience\AudienceType.cs" />
|
||||
<Compile Include="Push\MessageResult.cs" />
|
||||
<Compile Include="Push\Mode\Audience.cs" />
|
||||
<Compile Include="Push\Mode\Message.cs" />
|
||||
<Compile Include="Push\Mode\Notification.cs" />
|
||||
<Compile Include="Push\Mode\Options.cs" />
|
||||
<Compile Include="Push\Mode\Platform.cs" />
|
||||
<Compile Include="Push\Mode\PushPayload.cs" />
|
||||
<Compile Include="Push\Mode\PushUser.cs" />
|
||||
<Compile Include="Push\Notification\AndroidNotification.cs" />
|
||||
<Compile Include="Push\Notification\IosNotification.cs" />
|
||||
<Compile Include="Push\Notification\PlatformNotification.cs" />
|
||||
<Compile Include="Push\Notification\WinphoneNotification.cs" />
|
||||
<Compile Include="Push\PushClient.cs" />
|
||||
<Compile Include="Report\MessagesResult.cs" />
|
||||
<Compile Include="Report\ReceivedResult.cs" />
|
||||
<Compile Include="Report\ReportClient.cs" />
|
||||
<Compile Include="Report\UsersResult.cs" />
|
||||
<Compile Include="Util\Base64.cs" />
|
||||
<Compile Include="Util\JsonTool.cs" />
|
||||
<Compile Include="Util\Md5.cs" />
|
||||
<Compile Include="Util\Preconditions.cs" />
|
||||
<Compile Include="Util\StringUtil.cs" />
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 有关程序集的常规信息通过以下
|
||||
// 特性集控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("Lskj.Push")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Lskj.Push")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// 将 ComVisible 设置为 false 使此程序集中的类型
|
||||
// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
|
||||
// 则将该类型上的 ComVisible 特性设置为 true。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||
[assembly: Guid("4dfb63b4-d0f8-44cd-82fb-4b4a5c124296")]
|
||||
|
||||
// 程序集的版本信息由下面四个值组成:
|
||||
//
|
||||
// 主版本
|
||||
// 次版本
|
||||
// 内部版本号
|
||||
// 修订号
|
||||
//
|
||||
// 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值,
|
||||
// 方法是按如下所示使用“*”:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Lskj.Push.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 一个强类型的资源类,用于查找本地化的字符串等。
|
||||
/// </summary>
|
||||
// 此类是由 StronglyTypedResourceBuilder
|
||||
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
||||
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
||||
// (以 /str 作为命令选项),或重新生成 VS 项目。
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回此类使用的缓存的 ResourceManager 实例。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Lskj.Push.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用此强类型资源类,为所有资源查找
|
||||
/// 重写当前线程的 CurrentUICulture 属性。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Lskj.Push.Util;
|
||||
|
||||
namespace Lskj.Push.Push.Audience
|
||||
{
|
||||
public class AudienceTarget
|
||||
{
|
||||
public AudienceType audienceType{get;private set;}
|
||||
public HashSet<string> valueBuilder { get; private set; }
|
||||
|
||||
private AudienceTarget(AudienceType audienceType, HashSet<string> values)
|
||||
{
|
||||
this.audienceType = audienceType;
|
||||
this.valueBuilder = values;
|
||||
}
|
||||
public static AudienceTarget tag(HashSet<string> values)
|
||||
{
|
||||
return new AudienceTarget(AudienceType.tag,values).Check();
|
||||
|
||||
}
|
||||
public static AudienceTarget tag_and(HashSet<string> values)
|
||||
{
|
||||
return new AudienceTarget(AudienceType.tag_and, values).Check();
|
||||
}
|
||||
public static AudienceTarget alias(HashSet<string> values)
|
||||
{
|
||||
return new AudienceTarget(AudienceType.alias, values).Check();
|
||||
|
||||
}
|
||||
public static AudienceTarget segment(HashSet<string> values)
|
||||
{
|
||||
return new AudienceTarget(AudienceType.segment, values).Check();
|
||||
|
||||
}
|
||||
public static AudienceTarget registrationId(HashSet<string> values)
|
||||
{
|
||||
return new AudienceTarget(AudienceType.registration_id, values).Check();
|
||||
}
|
||||
public AudienceTarget Check()
|
||||
{
|
||||
Preconditions.checkArgument(null != valueBuilder, "Target values should be set one at least.");
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Push.Audience
|
||||
{
|
||||
public enum AudienceType
|
||||
{
|
||||
tag,
|
||||
tag_and,
|
||||
alias,
|
||||
segment,
|
||||
registration_id
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using Lskj.Push.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net;
|
||||
|
||||
|
||||
namespace Lskj.Push.Push
|
||||
{
|
||||
public class MessageResult : BaseResult
|
||||
{
|
||||
public Int64 msg_id{get;set;}
|
||||
public int sendno{ get; set; }
|
||||
|
||||
override public bool isResultOK()
|
||||
{
|
||||
if (Equals(ResponseResult.responseCode, HttpStatusCode.OK))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("sendno:{0},message_id:{1}", sendno, msg_id);
|
||||
}
|
||||
}
|
||||
//"{\"sendno\":\"0\",\"msg_id\":\"1704649583\"}"
|
||||
public class JpushSuccess
|
||||
{
|
||||
public string sendno;
|
||||
public string msg_id;
|
||||
}
|
||||
public class JpushError
|
||||
{
|
||||
public JpushErrorObject error;
|
||||
public long msg_id;
|
||||
}
|
||||
public class JpushErrorObject
|
||||
{
|
||||
public int code;
|
||||
public String message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Lskj.Push.Push.Audience;
|
||||
using System.Diagnostics;
|
||||
using Lskj.Push.Util;
|
||||
|
||||
namespace Lskj.Push.Push.Mode
|
||||
{
|
||||
public class Audience
|
||||
{
|
||||
private const String ALL = "all";
|
||||
public string allAudience;
|
||||
|
||||
private void AddWithAudienceTarget(AudienceTarget target)
|
||||
{
|
||||
Debug.Assert(target != null && target.valueBuilder != null);
|
||||
if (target != null && target.valueBuilder != null)
|
||||
{
|
||||
this.allAudience = null;
|
||||
if (dictionary == null)
|
||||
{
|
||||
dictionary = new Dictionary<string, HashSet<string>>();
|
||||
}
|
||||
if (dictionary.ContainsKey(target.audienceType.ToString()))
|
||||
{
|
||||
HashSet<string> origin = dictionary[target.audienceType.ToString()];
|
||||
foreach (var item in target.valueBuilder)
|
||||
{
|
||||
origin.Add(item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dictionary.Add(target.audienceType.ToString(), target.valueBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Dictionary<string, HashSet<string>> dictionary;
|
||||
private Audience()
|
||||
{
|
||||
allAudience = ALL;
|
||||
dictionary = null;
|
||||
}
|
||||
|
||||
public static Audience all()
|
||||
{
|
||||
return new Audience() { allAudience = ALL, dictionary = null }.Check();
|
||||
}
|
||||
public static Audience s_tag(HashSet<string> values)
|
||||
{
|
||||
return new Audience().tag(values);
|
||||
}
|
||||
public static Audience s_tag(params string[] values)
|
||||
{
|
||||
return new Audience().tag(values);
|
||||
}
|
||||
public static Audience s_tag_and(HashSet<string> values)
|
||||
{
|
||||
return new Audience().tag_and(values);
|
||||
}
|
||||
public static Audience s_tag_and(params string[] values)
|
||||
{
|
||||
return new Audience().tag_and(values);
|
||||
}
|
||||
public static Audience s_alias(HashSet<string> values)
|
||||
{
|
||||
return new Audience().alias(values);
|
||||
}
|
||||
public static Audience s_alias(params string[] values)
|
||||
{
|
||||
return new Audience().alias(values);
|
||||
}
|
||||
public static Audience s_segment(HashSet<string> values)
|
||||
{
|
||||
return new Audience().segment(values);
|
||||
}
|
||||
public static Audience s_segment(params string[] values)
|
||||
{
|
||||
return new Audience().segment(values);
|
||||
}
|
||||
public static Audience s_registrationId(HashSet<string> values)
|
||||
{
|
||||
return new Audience().registrationId(values);
|
||||
}
|
||||
public static Audience s_registrationId(params string[] values)
|
||||
{
|
||||
return new Audience().registrationId(values);
|
||||
}
|
||||
public Audience tag(HashSet<string> values)
|
||||
{
|
||||
if (allAudience != null)
|
||||
{
|
||||
allAudience = null;
|
||||
}
|
||||
AudienceTarget target = AudienceTarget.tag(values);
|
||||
AddWithAudienceTarget(target);
|
||||
return this.Check();
|
||||
}
|
||||
public Audience tag(params string[] values)
|
||||
{
|
||||
if (allAudience != null)
|
||||
{
|
||||
allAudience = null;
|
||||
}
|
||||
var valueList = new HashSet<string>(values);
|
||||
return tag(valueList);
|
||||
|
||||
}
|
||||
public Audience tag_and(HashSet<string> values)
|
||||
{
|
||||
if (allAudience != null)
|
||||
{
|
||||
allAudience = null;
|
||||
}
|
||||
AudienceTarget target = AudienceTarget.tag_and(values);
|
||||
this.allAudience = null;
|
||||
if (dictionary == null)
|
||||
{
|
||||
dictionary = new Dictionary<string, HashSet<string>>();
|
||||
}
|
||||
if (dictionary.ContainsKey(target.audienceType.ToString()))
|
||||
{
|
||||
HashSet<string> origin = dictionary[target.audienceType.ToString()];
|
||||
foreach (var item in values)
|
||||
{
|
||||
origin.Add(item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dictionary.Add(target.audienceType.ToString(), values);
|
||||
}
|
||||
return this.Check();
|
||||
}
|
||||
public Audience tag_and(params string[] values)
|
||||
{
|
||||
if (allAudience != null)
|
||||
{
|
||||
allAudience = null;
|
||||
}
|
||||
HashSet<string> list = new HashSet<string>(values);
|
||||
return tag_and(list);
|
||||
|
||||
}
|
||||
public Audience alias(HashSet<string> values)
|
||||
{
|
||||
if (allAudience != null)
|
||||
{
|
||||
allAudience = null;
|
||||
}
|
||||
AddWithAudienceTarget( AudienceTarget.alias(values));
|
||||
return this.Check();
|
||||
}
|
||||
public Audience alias(params string[] values)
|
||||
{
|
||||
if (allAudience != null)
|
||||
{
|
||||
allAudience = null;
|
||||
}
|
||||
return alias(new HashSet<string>(values));
|
||||
|
||||
}
|
||||
public Audience segment(HashSet<string> values)
|
||||
{
|
||||
if (allAudience != null)
|
||||
{
|
||||
allAudience = null;
|
||||
}
|
||||
AddWithAudienceTarget(AudienceTarget.segment(values));
|
||||
return this.Check();
|
||||
}
|
||||
public Audience segment(params string[] values)
|
||||
{
|
||||
if (allAudience != null)
|
||||
{
|
||||
allAudience = null;
|
||||
}
|
||||
return segment(new HashSet<string>(values));
|
||||
|
||||
}
|
||||
public Audience registrationId(HashSet<string> values)
|
||||
{
|
||||
if (allAudience != null)
|
||||
{
|
||||
allAudience = null;
|
||||
}
|
||||
AddWithAudienceTarget(AudienceTarget.registrationId(values));
|
||||
return this.Check();
|
||||
}
|
||||
public Audience registrationId(params string[] values)
|
||||
{
|
||||
if (allAudience != null)
|
||||
{
|
||||
allAudience = null;
|
||||
}
|
||||
return registrationId(new HashSet<string>(values));
|
||||
|
||||
}
|
||||
public bool isAll(){
|
||||
|
||||
return allAudience != null;
|
||||
}
|
||||
public Audience Check()
|
||||
{
|
||||
Preconditions.checkArgument(!(isAll() && null != dictionary), "Since all is enabled, any platform should not be set.");
|
||||
Preconditions.checkArgument(!(!isAll() && null == dictionary), "No any deviceType is set.");
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
using Lskj.Push.Util;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Push.Mode
|
||||
{
|
||||
public class Message
|
||||
{
|
||||
public String title{get;set;}
|
||||
public String msg_content { get; set; }
|
||||
public String content_type { get; set; }
|
||||
[JsonProperty]
|
||||
private Dictionary<string, object> extras { get; set; }
|
||||
|
||||
private Message()
|
||||
{
|
||||
|
||||
}
|
||||
private Message(String msgContent)
|
||||
{
|
||||
Preconditions.checkArgument(!(msgContent==null), "msgContent should be set");
|
||||
|
||||
this.title = null;
|
||||
this.msg_content = msgContent;
|
||||
this.content_type = null;
|
||||
this.extras = null;
|
||||
}
|
||||
private Message(String msgContent, String title, String contentType)
|
||||
{
|
||||
Preconditions.checkArgument(!(msgContent == null), "msgContent should be set");
|
||||
|
||||
this.title = title;
|
||||
this.msg_content = msgContent;
|
||||
this.content_type = contentType;
|
||||
}
|
||||
public static Message content(string msgContent)
|
||||
{
|
||||
return new Message(msgContent).Check();
|
||||
}
|
||||
public Message setTitle(String title)
|
||||
{
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
public Message setContentType(String ContentType)
|
||||
{
|
||||
this.content_type = ContentType;
|
||||
return this;
|
||||
}
|
||||
public Message AddExtras(string key, string value)
|
||||
{
|
||||
if (extras == null)
|
||||
{
|
||||
extras = new Dictionary<string, object>();
|
||||
}
|
||||
if (value != null)
|
||||
{
|
||||
extras.Add(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public Message AddExtras(string key, int value)
|
||||
{
|
||||
if (extras == null)
|
||||
{
|
||||
extras = new Dictionary<string, object>();
|
||||
}
|
||||
extras.Add(key, value);
|
||||
return this;
|
||||
}
|
||||
public Message AddExtras(string key, bool value)
|
||||
{
|
||||
if (extras == null)
|
||||
{
|
||||
extras = new Dictionary<string, object>();
|
||||
}
|
||||
extras.Add(key, value);
|
||||
return this;
|
||||
|
||||
}
|
||||
public Message AddExtras(string key, object value)
|
||||
{
|
||||
if (extras == null)
|
||||
{
|
||||
extras = new Dictionary<string, object>();
|
||||
}
|
||||
extras.Add(key, value);
|
||||
return this;
|
||||
|
||||
}
|
||||
public Message Check()
|
||||
{
|
||||
Preconditions.checkArgument(!(msg_content==null), "msgContent should be set");
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
using Lskj.Push.Push.Notification;
|
||||
using Lskj.Push.Util;
|
||||
using Newtonsoft.Json;
|
||||
// ------------------------------------------------------------------------------
|
||||
// <autogenerated>
|
||||
// This code was generated by a tool.
|
||||
// Mono Runtime Version: 4.0.30319.1
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </autogenerated>
|
||||
// ------------------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
namespace Lskj.Push.Push.Mode
|
||||
{
|
||||
public class Notification
|
||||
{
|
||||
public String alert{get;set;}
|
||||
[JsonProperty(PropertyName = "ios")]
|
||||
public IosNotification IosNotification { get; set; }
|
||||
[JsonProperty(PropertyName = "android")]
|
||||
public AndroidNotification AndroidNotification { get; set; }
|
||||
[JsonProperty(PropertyName = "winphone")]
|
||||
public WinphoneNotification WinphoneNotification { get; set; }
|
||||
|
||||
public Notification()
|
||||
{
|
||||
this.alert = null;
|
||||
this.IosNotification = null;
|
||||
this.AndroidNotification = null;
|
||||
this.WinphoneNotification = null;
|
||||
}
|
||||
|
||||
public Notification setAlert(string alert)
|
||||
{
|
||||
this.alert = alert;
|
||||
return this;
|
||||
}
|
||||
public Notification setAndroid(AndroidNotification android)
|
||||
{
|
||||
this.AndroidNotification = android;
|
||||
return this;
|
||||
}
|
||||
public Notification setIos(IosNotification ios)
|
||||
{
|
||||
this.IosNotification = ios;
|
||||
return this;
|
||||
}
|
||||
public Notification setWinphone(WinphoneNotification winphone)
|
||||
{
|
||||
this.WinphoneNotification = winphone;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static Notification android(String alert, String title)
|
||||
{
|
||||
var platformNotification = new AndroidNotification().setAlert(alert).setTitle(title);
|
||||
var notificaiton = new Notification().setAlert(alert);
|
||||
notificaiton.AndroidNotification = platformNotification;
|
||||
return notificaiton;
|
||||
}
|
||||
public static Notification ios(String alert)
|
||||
{
|
||||
var iosNotification = new IosNotification().setAlert(alert);
|
||||
var notification = new Notification().setAlert(alert);
|
||||
notification.IosNotification = iosNotification;
|
||||
return notification;
|
||||
}
|
||||
public static Notification ios_auto_badge()
|
||||
{
|
||||
var platformNotification = new IosNotification();
|
||||
platformNotification.autoBadge();
|
||||
var notificaiton = new Notification().setAlert("");;
|
||||
notificaiton.IosNotification = platformNotification;
|
||||
return notificaiton;
|
||||
}
|
||||
public static Notification ios_set_badge(int badge)
|
||||
{
|
||||
var platformNotification = new IosNotification();
|
||||
platformNotification.setBadge(badge);
|
||||
|
||||
var notificaiton = new Notification();
|
||||
notificaiton.IosNotification = platformNotification;
|
||||
return notificaiton;
|
||||
}
|
||||
public static Notification ios_incr_badge(int badge)
|
||||
{
|
||||
var platformNotification = new IosNotification();
|
||||
platformNotification.incrBadge(badge);
|
||||
var notificaiton = new Notification();
|
||||
notificaiton.IosNotification = platformNotification;
|
||||
return notificaiton;
|
||||
}
|
||||
public static Notification winphone(String alert)
|
||||
{
|
||||
var platformNotification = new WinphoneNotification().setAlert(alert);
|
||||
|
||||
var notificaiton = new Notification().setAlert(alert);
|
||||
notificaiton.WinphoneNotification = platformNotification;
|
||||
return notificaiton;
|
||||
}
|
||||
|
||||
public Notification Check()
|
||||
{
|
||||
Preconditions.checkArgument(!(isPlatformEmpty() && null == alert), "No notification payload is set.");
|
||||
if (IosNotification!=null)
|
||||
{
|
||||
Preconditions.checkArgument(!(null==IosNotification.alert && null == alert), "No notification payload is set.");
|
||||
}
|
||||
if(AndroidNotification!=null)
|
||||
{
|
||||
Preconditions.checkArgument(!(null == AndroidNotification.alert && null == alert), "No notification payload is set.");
|
||||
|
||||
}
|
||||
if (WinphoneNotification!=null)
|
||||
{
|
||||
Preconditions.checkArgument(!(null == WinphoneNotification.alert && null == alert), "No notification payload is set.");
|
||||
|
||||
}
|
||||
return this;
|
||||
}
|
||||
private bool isPlatformEmpty()
|
||||
{
|
||||
return (IosNotification == null && AndroidNotification == null && WinphoneNotification == null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
using Lskj.Push.Util;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Push.Mode
|
||||
{
|
||||
public class Options
|
||||
{
|
||||
private const long NONE_TIME_TO_LIVE = -1;
|
||||
|
||||
public Options()
|
||||
{
|
||||
this.sendno = 0;
|
||||
this.override_msg_id = 0;
|
||||
this.time_to_live = NONE_TIME_TO_LIVE;
|
||||
this.big_push_duration = 0;
|
||||
this.apns_production = false;
|
||||
}
|
||||
public Options(int sendno,
|
||||
long overrideMsgId,
|
||||
long timeToLive,
|
||||
int bigPushDuration,
|
||||
bool apnsProduction=false)
|
||||
{
|
||||
this.sendno = sendno;
|
||||
this.override_msg_id = overrideMsgId;
|
||||
this.time_to_live = timeToLive;
|
||||
this.big_push_duration = bigPushDuration;
|
||||
this.apns_production = apnsProduction;
|
||||
}
|
||||
private int _sendno;
|
||||
[DefaultValue(0)]
|
||||
public int sendno
|
||||
{
|
||||
get
|
||||
{
|
||||
return _sendno;
|
||||
}
|
||||
set
|
||||
{
|
||||
Preconditions.checkArgument(value >= 0, "sendno should be greater than 0.");
|
||||
_sendno = value;
|
||||
}
|
||||
}
|
||||
private long _override_msg_id;
|
||||
[DefaultValue(0)]
|
||||
public long override_msg_id
|
||||
{
|
||||
get
|
||||
{
|
||||
return _override_msg_id;
|
||||
}
|
||||
set
|
||||
{
|
||||
Preconditions.checkArgument(value >= 0, "override_msg_id should be greater than 0.");
|
||||
_override_msg_id = value;
|
||||
}
|
||||
}
|
||||
private long _time_to_live;
|
||||
[DefaultValue(NONE_TIME_TO_LIVE)]
|
||||
public long time_to_live
|
||||
{
|
||||
get
|
||||
{
|
||||
return _time_to_live;
|
||||
}
|
||||
set
|
||||
{
|
||||
Preconditions.checkArgument(value >= NONE_TIME_TO_LIVE, "time_to_live should be greater than 0.");
|
||||
_time_to_live = value;
|
||||
}
|
||||
}
|
||||
private long _big_push_duration;
|
||||
[DefaultValue(0)]
|
||||
public long big_push_duration
|
||||
{
|
||||
get
|
||||
{
|
||||
return _big_push_duration;
|
||||
}
|
||||
set
|
||||
{
|
||||
Preconditions.checkArgument(value >= 0, "big_push_duration should be greater than 0.");
|
||||
_big_push_duration = value;
|
||||
}
|
||||
}
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Include)]
|
||||
public bool apns_production { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
using Lskj.Push.Common;
|
||||
using Lskj.Push.Util;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Push.Mode
|
||||
{
|
||||
public class Platform
|
||||
{
|
||||
private const String ALL = "all";
|
||||
[JsonProperty(PropertyName = "winphone")]
|
||||
public string allPlatform{get;set;}
|
||||
private HashSet<string> _deviceTypes;
|
||||
public HashSet<string> deviceTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
return _deviceTypes;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
allPlatform = null;
|
||||
}
|
||||
_deviceTypes = value;
|
||||
}
|
||||
}
|
||||
private Platform()
|
||||
{
|
||||
allPlatform = ALL;
|
||||
deviceTypes = null;
|
||||
}
|
||||
private Platform(bool all, HashSet<string> deviceTypes)
|
||||
{
|
||||
//用来判断all=true时deviceTypes必须为空,反之当all=false时deviceTypes有值,不然json序列化会出错
|
||||
Debug.Assert(all && deviceTypes == null || !all && deviceTypes != null);
|
||||
if (all)
|
||||
{
|
||||
allPlatform = ALL;
|
||||
}
|
||||
this.deviceTypes = deviceTypes;
|
||||
}
|
||||
public static Platform all()
|
||||
{
|
||||
return new Platform(true, null).Check();
|
||||
}
|
||||
public static Platform ios()
|
||||
{
|
||||
HashSet<string> types = new HashSet<string>();
|
||||
types.Add(DeviceType.ios.ToString());
|
||||
return new Platform(false,types).Check();
|
||||
}
|
||||
public static Platform android()
|
||||
{
|
||||
HashSet<string> types = new HashSet<string>();
|
||||
types.Add(DeviceType.android.ToString());
|
||||
return new Platform(false, types).Check();
|
||||
}
|
||||
public static Platform winphone()
|
||||
{
|
||||
HashSet<string> types = new HashSet<string>();
|
||||
types.Add(DeviceType.winphone.ToString());
|
||||
return new Platform(false, types).Check();
|
||||
}
|
||||
public static Platform android_ios()
|
||||
{
|
||||
HashSet<string> types = new HashSet<string>();
|
||||
types.Add(DeviceType.android.ToString());
|
||||
types.Add(DeviceType.ios.ToString());
|
||||
return new Platform(false, types).Check();
|
||||
}
|
||||
public static Platform android_winphone()
|
||||
{
|
||||
HashSet<string> types = new HashSet<string>();
|
||||
types.Add(DeviceType.android.ToString());
|
||||
types.Add(DeviceType.winphone.ToString());
|
||||
return new Platform(false, types).Check();
|
||||
}
|
||||
public static Platform ios_winphone()
|
||||
{
|
||||
HashSet<string> types = new HashSet<string>();
|
||||
types.Add(DeviceType.ios.ToString());
|
||||
types.Add(DeviceType.winphone.ToString());
|
||||
|
||||
return new Platform(false, types).Check();
|
||||
}
|
||||
public bool isAll()
|
||||
{
|
||||
return allPlatform != null;
|
||||
}
|
||||
public void setAll(bool all)
|
||||
{
|
||||
if (all)
|
||||
{
|
||||
allPlatform = ALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
allPlatform = null;
|
||||
}
|
||||
}
|
||||
public Platform Check()
|
||||
{
|
||||
Preconditions.checkArgument(!(isAll() && null != deviceTypes), "Since all is enabled, any platform should not be set.");
|
||||
Preconditions.checkArgument(!(!isAll() && null == deviceTypes), "No any deviceType is set.");
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
using Lskj.Push.Common;
|
||||
using Lskj.Push.Push.Notification;
|
||||
using Lskj.Push.Util;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
namespace Lskj.Push.Push.Mode
|
||||
{
|
||||
public class PushPayload
|
||||
{
|
||||
|
||||
private JsonSerializerSettings jSetting;
|
||||
private const String PLATFORM = "platform";
|
||||
private const String AUDIENCE = "audience";
|
||||
private const String NOTIFICATION = "notification";
|
||||
private const String MESSAGE = "message";
|
||||
private const String OPTIONS = "options";
|
||||
|
||||
private const int MAX_GLOBAL_ENTITY_LENGTH = 1200; // Definition acording to JPush Docs
|
||||
private const int MAX_IOS_PAYLOAD_LENGTH = 220; // Definition acording to JPush Docs
|
||||
|
||||
//serializaiton property
|
||||
[JsonConverter(typeof(PlatformConverter))]
|
||||
public Platform platform{get;set;}
|
||||
[JsonConverter(typeof(AudienceConverter))]
|
||||
public Audience audience{get;set;}
|
||||
public Notification notification { get; set; }
|
||||
public Message message { get; set; }
|
||||
public Options options { get; set; }
|
||||
//construct
|
||||
public PushPayload()
|
||||
{
|
||||
platform = null;
|
||||
audience = null;
|
||||
notification = null;
|
||||
message = null;
|
||||
options = new Options();
|
||||
jSetting = new JsonSerializerSettings();
|
||||
jSetting.NullValueHandling = NullValueHandling.Ignore;
|
||||
jSetting.DefaultValueHandling = DefaultValueHandling.Ignore;
|
||||
}
|
||||
public PushPayload(Platform platform, Audience audience, Notification notification, Message message = null, Options options = null)
|
||||
{
|
||||
Debug.Assert(platform != null);
|
||||
Debug.Assert(audience != null);
|
||||
Debug.Assert(notification != null || message != null);
|
||||
|
||||
this.platform = platform;
|
||||
this.audience = audience;
|
||||
this.notification = notification;
|
||||
this.message = message;
|
||||
this.options = options;
|
||||
|
||||
jSetting = new JsonSerializerSettings();
|
||||
jSetting.NullValueHandling = NullValueHandling.Ignore;
|
||||
jSetting.DefaultValueHandling = DefaultValueHandling.Ignore;
|
||||
}
|
||||
/**
|
||||
* The shortcut of building a simple alert notification object to all platforms and all audiences
|
||||
*/
|
||||
public static PushPayload AlertAll(String alert)
|
||||
{
|
||||
return new PushPayload(Platform.all(),
|
||||
Audience.all(),
|
||||
new Notification().setAlert(alert),
|
||||
null,
|
||||
new Options());
|
||||
}
|
||||
//* The shortcut of building a simple message object to all platforms and all audiences
|
||||
//*/
|
||||
public static PushPayload MessageAll(String msgContent)
|
||||
{
|
||||
return new PushPayload( Platform.all(),
|
||||
Audience.all(),
|
||||
null,
|
||||
Message.content(msgContent),
|
||||
new Options());
|
||||
}
|
||||
public static PushPayload FromJSON(String payloadString)
|
||||
{
|
||||
try
|
||||
{
|
||||
var jSetting = new JsonSerializerSettings();
|
||||
jSetting.NullValueHandling = NullValueHandling.Ignore;
|
||||
jSetting.DefaultValueHandling = DefaultValueHandling.Ignore;
|
||||
|
||||
var jsonObject = JsonConvert.DeserializeObject<PushPayload>(payloadString, jSetting);
|
||||
return jsonObject.Check();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("JSON to PushPayLoad occur error:" + e.Message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public void ResetOptionsApnsProduction(bool apnsProduction)
|
||||
{
|
||||
if (this.options == null)
|
||||
{
|
||||
this.options = new Options();
|
||||
}
|
||||
this.options.apns_production = apnsProduction;
|
||||
}
|
||||
public void ResetOptionsTimeToLive(long timeToLive)
|
||||
{
|
||||
if (this.options == null)
|
||||
{
|
||||
this.options = new Options();
|
||||
}
|
||||
this.options.time_to_live = timeToLive;
|
||||
}
|
||||
public int GetSendno()
|
||||
{
|
||||
if (this.options != null)
|
||||
return this.options.sendno;
|
||||
return 0;
|
||||
}
|
||||
public bool IsGlobalExceedLength()
|
||||
{
|
||||
int messageLength = 0;
|
||||
if (message!= null)
|
||||
{
|
||||
var messageJson = JsonConvert.SerializeObject(this.message, jSetting);
|
||||
messageLength += UTF8Encoding.UTF8.GetBytes(messageJson).Length;
|
||||
}
|
||||
if (this.notification == null)
|
||||
{
|
||||
return messageLength > MAX_GLOBAL_ENTITY_LENGTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
var notificationJson = JsonConvert.SerializeObject(this.notification);
|
||||
if (notificationJson != null)
|
||||
{
|
||||
messageLength += UTF8Encoding.UTF8.GetBytes(notificationJson).Length;
|
||||
}
|
||||
return messageLength > MAX_GLOBAL_ENTITY_LENGTH;
|
||||
}
|
||||
|
||||
}
|
||||
public bool IsIosExceedLength()
|
||||
{
|
||||
if (this.notification != null)
|
||||
{
|
||||
if (this.notification.IosNotification != null)
|
||||
{
|
||||
var iosJson = JsonConvert.SerializeObject(this.notification.IosNotification, jSetting);
|
||||
if (iosJson != null)
|
||||
{
|
||||
return UTF8Encoding.UTF8.GetBytes(iosJson).Length > MAX_IOS_PAYLOAD_LENGTH;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(this.notification.alert==null))
|
||||
{
|
||||
string jsonText;
|
||||
using (StringWriter sw = new StringWriter())
|
||||
{
|
||||
JsonWriter writer = new JsonTextWriter(sw);
|
||||
writer.WriteValue(this.notification.alert);
|
||||
writer.Flush();
|
||||
jsonText = sw.GetStringBuilder().ToString();
|
||||
}
|
||||
return UTF8Encoding.UTF8.GetBytes(jsonText).Length > MAX_IOS_PAYLOAD_LENGTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No iOS Payload
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public string ToJson()
|
||||
{
|
||||
return JsonConvert.SerializeObject(this, jSetting);
|
||||
}
|
||||
public PushPayload Check()
|
||||
{
|
||||
Preconditions.checkArgument(!(null == audience || null == platform), "audience and platform both should be set.");
|
||||
Preconditions.checkArgument(!(null == notification && null == message), "notification or message should be set at least one.");
|
||||
if (audience!=null)
|
||||
{
|
||||
audience.Check();
|
||||
}
|
||||
if (platform != null)
|
||||
{
|
||||
platform.Check();
|
||||
}
|
||||
if (message != null)
|
||||
{
|
||||
message.Check();
|
||||
}
|
||||
if (notification != null)
|
||||
{
|
||||
notification.Check();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Lskj.Push.Push.Mode
|
||||
{
|
||||
public class PushUserObj
|
||||
{
|
||||
public string username { get; set; }
|
||||
public string password { get; set; }
|
||||
public string nickname { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Push.Notification
|
||||
{
|
||||
public class AndroidNotification:PlatformNotification
|
||||
{
|
||||
public const String NOTIFICATION_ANDROID = "android";
|
||||
|
||||
private const String TITLE = "title";
|
||||
private const String BUILDER_ID = "builder_id";
|
||||
|
||||
[JsonProperty]
|
||||
public String title{get;private set;}
|
||||
[JsonProperty]
|
||||
public int builder_id { get; private set; }
|
||||
public AndroidNotification():base()
|
||||
{
|
||||
this.title = null;
|
||||
this.builder_id = 0;
|
||||
}
|
||||
public AndroidNotification setTitle(string title)
|
||||
{
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
public AndroidNotification setBuilderID(int builder_id)
|
||||
{
|
||||
this.builder_id = builder_id;
|
||||
return this;
|
||||
}
|
||||
public AndroidNotification setAlert(String alert)
|
||||
{
|
||||
this.alert = alert;
|
||||
return this;
|
||||
}
|
||||
public AndroidNotification AddExtra(string key, string value)
|
||||
{
|
||||
if (extras == null)
|
||||
{
|
||||
extras = new Dictionary<string, object>();
|
||||
}
|
||||
if (value != null)
|
||||
{
|
||||
extras.Add(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public AndroidNotification AddExtra(string key, int value)
|
||||
{
|
||||
if (extras == null)
|
||||
{
|
||||
extras = new Dictionary<string, object>();
|
||||
}
|
||||
extras.Add(key, value);
|
||||
return this;
|
||||
}
|
||||
public AndroidNotification AddExtra(string key, bool value)
|
||||
{
|
||||
if (extras == null)
|
||||
{
|
||||
extras = new Dictionary<string, object>();
|
||||
}
|
||||
extras.Add(key, value);
|
||||
return this;
|
||||
|
||||
}
|
||||
public AndroidNotification AddExtra(string key, object value)
|
||||
{
|
||||
if (extras == null)
|
||||
{
|
||||
extras = new Dictionary<string, object>();
|
||||
}
|
||||
extras.Add(key, value);
|
||||
return this;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
using Lskj.Push.Common;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Push.Notification
|
||||
{
|
||||
public class IosNotification : PlatformNotification
|
||||
{
|
||||
public const String NOTIFICATION_IOS = "ios";
|
||||
|
||||
private const String DEFAULT_SOUND = "";
|
||||
private const String DEFAULT_BADGE = "+1";
|
||||
|
||||
private const String BADGE = "badge";
|
||||
private const String SOUND = "sound";
|
||||
private const String CONTENT_AVAILABLE = "content-available";
|
||||
private const String CATEGORY = "category";
|
||||
|
||||
|
||||
private const String ALERT_VALID_BADGE = "Badge number should be 0~99999, "
|
||||
+ "and badgeDisabled property must be false";
|
||||
private const String SOUNd_VALID_BADGE = "Sound should not be null or empty, "
|
||||
+ "and disableSound property must be false";
|
||||
|
||||
|
||||
private bool soundDisabled;
|
||||
private bool badgeDisabled;
|
||||
|
||||
[JsonProperty]
|
||||
public String sound { get;private set; }
|
||||
[JsonProperty]
|
||||
public String badge { get; private set; }
|
||||
|
||||
[JsonProperty(PropertyName = "content-available")]
|
||||
public bool contentAvailable { get; private set; }
|
||||
[JsonProperty]
|
||||
public String category { get; private set; }
|
||||
|
||||
public IosNotification()
|
||||
{
|
||||
base.alert = null;
|
||||
base.extras = null;
|
||||
this.soundDisabled = false;
|
||||
this.badgeDisabled = false;
|
||||
this.contentAvailable = false;
|
||||
this.category = null;
|
||||
this.badge = DEFAULT_BADGE;
|
||||
this.sound = DEFAULT_SOUND;
|
||||
}
|
||||
|
||||
public IosNotification disableSound()
|
||||
{
|
||||
this.soundDisabled = true;
|
||||
this.sound = null;
|
||||
return this;
|
||||
}
|
||||
public IosNotification disableBadge()
|
||||
{
|
||||
this.badgeDisabled = true;
|
||||
this.badge = null;
|
||||
return this;
|
||||
}
|
||||
public IosNotification setSound(String sound)
|
||||
{
|
||||
|
||||
if ((sound ==null) || soundDisabled)
|
||||
{
|
||||
Console.WriteLine(SOUNd_VALID_BADGE);
|
||||
return this;
|
||||
}
|
||||
this.sound = sound;
|
||||
return this;
|
||||
}
|
||||
public IosNotification setBadge(int badge)
|
||||
{
|
||||
if (!ServiceHelper.isValidIntBadge(Math.Abs(badge)) || badgeDisabled)
|
||||
{
|
||||
Console.WriteLine(ALERT_VALID_BADGE);
|
||||
return this;
|
||||
}
|
||||
this.badge = badge.ToString();
|
||||
return this;
|
||||
}
|
||||
public IosNotification autoBadge()
|
||||
{
|
||||
return incrBadge(1);
|
||||
|
||||
}
|
||||
public IosNotification incrBadge(int badge)
|
||||
{
|
||||
if (!ServiceHelper.isValidIntBadge(Math.Abs(badge))|| badgeDisabled)
|
||||
{
|
||||
Console.WriteLine(ALERT_VALID_BADGE);
|
||||
return this;
|
||||
}
|
||||
if (badge >= 0)
|
||||
{
|
||||
this.badge = "+" + badge;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.badge = "" + badge;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public IosNotification setAlert(String alert)
|
||||
{
|
||||
this.alert = alert;
|
||||
return this;
|
||||
}
|
||||
public IosNotification setContentAvailable(bool contentAvailable)
|
||||
{
|
||||
this.contentAvailable = contentAvailable;
|
||||
return this;
|
||||
}
|
||||
public IosNotification setCategory(String category)
|
||||
{
|
||||
this.category = category;
|
||||
return this;
|
||||
}
|
||||
public IosNotification AddExtra(string key, string value)
|
||||
{
|
||||
if (extras == null)
|
||||
{
|
||||
extras = new Dictionary<string, object>();
|
||||
}
|
||||
if (value !=null)
|
||||
{
|
||||
extras.Add(key, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public IosNotification AddExtra(string key, int value)
|
||||
{
|
||||
if (extras == null)
|
||||
{
|
||||
extras = new Dictionary<string, object>();
|
||||
}
|
||||
extras.Add(key, value);
|
||||
return this;
|
||||
}
|
||||
public IosNotification AddExtra(string key, bool value)
|
||||
{
|
||||
if (extras == null)
|
||||
{
|
||||
extras = new Dictionary<string, object>();
|
||||
}
|
||||
extras.Add(key, value);
|
||||
return this;
|
||||
}
|
||||
public IosNotification AddExtra(string key, object value)
|
||||
{
|
||||
if (extras == null)
|
||||
{
|
||||
extras = new Dictionary<string, object>();
|
||||
}
|
||||
extras.Add(key, value);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using Lskj.Push.Push.Mode;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Push.Notification
|
||||
{
|
||||
public abstract class PlatformNotification
|
||||
{
|
||||
|
||||
public const String ALERT = "alert";
|
||||
private const String EXTRAS = "extras";
|
||||
[JsonProperty]
|
||||
public String alert{get;protected set;}
|
||||
[JsonProperty]
|
||||
public Dictionary<String, object> extras { get; protected set; }
|
||||
|
||||
public PlatformNotification()
|
||||
{
|
||||
this.alert = null;
|
||||
this.extras = null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Push.Notification
|
||||
{
|
||||
public class WinphoneNotification : PlatformNotification
|
||||
{
|
||||
[JsonProperty]
|
||||
private String title;
|
||||
[JsonProperty(PropertyName = "_open_page")]
|
||||
public String openPage;
|
||||
|
||||
public WinphoneNotification():base()
|
||||
{
|
||||
this.title = null;
|
||||
this.openPage = null;
|
||||
}
|
||||
|
||||
public WinphoneNotification setAlert(String alert)
|
||||
{
|
||||
this.alert = alert;
|
||||
return this;
|
||||
}
|
||||
public WinphoneNotification setOpenPage(String openPage)
|
||||
{
|
||||
this.openPage = openPage;
|
||||
return this;
|
||||
}
|
||||
public WinphoneNotification setTitle(String title)
|
||||
{
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
public WinphoneNotification AddExtra(string key, string value)
|
||||
{
|
||||
if (extras == null)
|
||||
{
|
||||
extras = new Dictionary<string, object>();
|
||||
}
|
||||
if (value!=null)
|
||||
{
|
||||
extras.Add(key, value);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
public WinphoneNotification AddExtra(string key, int value)
|
||||
{
|
||||
if (extras == null)
|
||||
{
|
||||
extras = new Dictionary<string, object>();
|
||||
}
|
||||
extras.Add(key, value);
|
||||
return this;
|
||||
}
|
||||
public WinphoneNotification AddExtra(string key, bool value)
|
||||
{
|
||||
if (extras == null)
|
||||
{
|
||||
extras = new Dictionary<string, object>();
|
||||
}
|
||||
extras.Add(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using Lskj.Push.Common;
|
||||
using Lskj.Push.Push.Mode;
|
||||
using Lskj.Push.Util;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Push
|
||||
{
|
||||
internal class PushClient:BaseHttpClient
|
||||
{
|
||||
private const String HOST_NAME_SSL = "https://api.jpush.cn";
|
||||
private const String PUSH_PATH = "/v3/push";
|
||||
|
||||
private String appKey;
|
||||
private String masterSecret;
|
||||
public PushClient(String appKey,String masterSecret)
|
||||
{
|
||||
this.appKey = appKey;
|
||||
this.masterSecret = masterSecret;
|
||||
}
|
||||
public MessageResult sendPush(PushPayload payload)
|
||||
{
|
||||
Preconditions.checkArgument(payload != null, "pushPayload should not be empty");
|
||||
payload.Check();
|
||||
String payloadJson = payload.ToJson();
|
||||
return sendPush(payloadJson);
|
||||
}
|
||||
public MessageResult sendPush(string payloadString)
|
||||
{
|
||||
Preconditions.checkArgument(!string.IsNullOrEmpty(payloadString), "payloadString should not be empty");
|
||||
|
||||
String url = HOST_NAME_SSL;
|
||||
url += PUSH_PATH;
|
||||
ResponseWrapper result = sendPost(url, Authorization(), payloadString);
|
||||
MessageResult messResult = new MessageResult();
|
||||
messResult.ResponseResult = result;
|
||||
|
||||
JpushSuccess jpushSuccess = JsonConvert.DeserializeObject<JpushSuccess>(result.responseContent);
|
||||
messResult.sendno = int.Parse(jpushSuccess.sendno);
|
||||
//messResult.msg_id = int.Parse(jpushSuccess.msg_id);
|
||||
messResult.msg_id = Convert.ToInt64(jpushSuccess.msg_id);
|
||||
|
||||
return messResult;
|
||||
}
|
||||
private String Authorization(){
|
||||
|
||||
Debug.Assert(!string.IsNullOrEmpty(this.appKey));
|
||||
Debug.Assert(!string.IsNullOrEmpty(this.masterSecret));
|
||||
|
||||
String origin=this.appKey+":"+this.masterSecret;
|
||||
return Base64.getBase64Encode(origin);
|
||||
}
|
||||
}
|
||||
enum MsgTypeEnum
|
||||
{
|
||||
NOTIFICATIFY = 1,
|
||||
COUSTOM_MESSAGE =2
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using Lskj.Push.Common;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Report
|
||||
{
|
||||
public class MessagesResult : BaseResult
|
||||
{
|
||||
public List<Message> messages = new List<Message>();
|
||||
public static MessagesResult fromResponse(ResponseWrapper responseWrapper)
|
||||
{
|
||||
MessagesResult receivedsResult = new MessagesResult();
|
||||
if (responseWrapper.responseCode==HttpStatusCode.OK)
|
||||
{
|
||||
receivedsResult.messages = JsonConvert.DeserializeObject<List<Message>>(responseWrapper.responseContent);
|
||||
}
|
||||
receivedsResult.ResponseResult = responseWrapper;
|
||||
return receivedsResult;
|
||||
}
|
||||
public override bool isResultOK()
|
||||
{
|
||||
if (Equals(ResponseResult.responseCode, HttpStatusCode.OK))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public class Message
|
||||
{
|
||||
public Message()
|
||||
{
|
||||
msg_id = 0;
|
||||
android = null;
|
||||
ios = null;
|
||||
}
|
||||
public long msg_id;
|
||||
public Android android;
|
||||
public Ios ios;
|
||||
}
|
||||
public class Android
|
||||
{
|
||||
|
||||
public Android()
|
||||
{
|
||||
received = 0;
|
||||
target = 0;
|
||||
online_push = 0;
|
||||
click = 0;
|
||||
}
|
||||
public int received;
|
||||
public int target;
|
||||
public int online_push;
|
||||
public int click;
|
||||
}
|
||||
public class Ios
|
||||
{
|
||||
public Ios()
|
||||
{
|
||||
apns_sent = 0;
|
||||
apns_target = 0;
|
||||
click = 0;
|
||||
}
|
||||
public int apns_sent;
|
||||
public int apns_target;
|
||||
public int click;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using Lskj.Push.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Report
|
||||
{
|
||||
public class ReceivedResult : BaseResult
|
||||
{
|
||||
|
||||
private List<Received> receivedList = new List<Received>();
|
||||
|
||||
public List<Received> ReceivedList
|
||||
{
|
||||
get { return receivedList; }
|
||||
set { receivedList = value; }
|
||||
}
|
||||
|
||||
public class Received {
|
||||
public long msg_id;
|
||||
public String android_received;
|
||||
public String ios_apns_sent;
|
||||
}
|
||||
|
||||
public override bool isResultOK()
|
||||
{
|
||||
if (Equals(ResponseResult.responseCode, HttpStatusCode.OK))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public HttpStatusCode getErrorCode()
|
||||
{
|
||||
if (null != ResponseResult)
|
||||
{
|
||||
return ResponseResult.responseCode;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public string getErrorMessage()
|
||||
{
|
||||
if (null != ResponseResult)
|
||||
{
|
||||
return ResponseResult.exceptionString;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
using Lskj.Push.Common;
|
||||
using Lskj.Push.Util;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Report
|
||||
{
|
||||
class ReportClient:BaseHttpClient
|
||||
{
|
||||
private const String REPORT_HOST_NAME = "https://report.jpush.cn";
|
||||
private const String REPORT_RECEIVE_PATH = "/v2/received";
|
||||
private const String REPORT_RECEIVE_PATH_V3 = "/v3/received";
|
||||
private const String REPORT_USER_PATH = "/v3/users";
|
||||
|
||||
private String appKey;
|
||||
private String masterSecret;
|
||||
public ReportClient(String appKey, String masterSecret)
|
||||
{
|
||||
this.appKey = appKey;
|
||||
this.masterSecret = masterSecret;
|
||||
}
|
||||
public ReceivedResult getReceiveds(String msg_ids)
|
||||
{
|
||||
checkMsgids(msg_ids);
|
||||
return getReceiveds_common(msg_ids, REPORT_RECEIVE_PATH);
|
||||
}
|
||||
public ReceivedResult getReceiveds_v3(String msg_ids)
|
||||
{
|
||||
checkMsgids(msg_ids);
|
||||
return getReceiveds_common(msg_ids, REPORT_RECEIVE_PATH_V3);
|
||||
}
|
||||
public UsersResult getUsers(TimeUnit timeUnit, String start, int duration)
|
||||
{
|
||||
String url = REPORT_HOST_NAME + REPORT_USER_PATH
|
||||
+ "?time_unit=" + timeUnit.ToString()
|
||||
+ "&start=" + start + "&duration=" + duration;
|
||||
String auth = Base64.getBase64Encode(this.appKey + ":" + this.masterSecret);
|
||||
ResponseWrapper response = this.sendGet(url, auth, null);
|
||||
|
||||
return UsersResult.fromResponse(response);
|
||||
}
|
||||
public MessagesResult getReportMessages(params String[] msgIds)
|
||||
{
|
||||
return getReportMessages(StringUtil.arrayToString(msgIds));
|
||||
}
|
||||
public String checkMsgids(String msgIds)
|
||||
{
|
||||
|
||||
if (string.IsNullOrEmpty(msgIds)) {
|
||||
throw new ArgumentException("msgIds param is required.");
|
||||
}
|
||||
Regex reg = new Regex(@"[^0-9, ]");
|
||||
if(reg.IsMatch(msgIds))
|
||||
{
|
||||
throw new ArgumentException("msgIds param format is incorrect. "
|
||||
+ "It should be msg_id (number) which response from JPush Push API. "
|
||||
+ "If there are many, use ',' as interval. ");
|
||||
}
|
||||
msgIds = msgIds.Trim();
|
||||
if (msgIds.EndsWith(",")) {
|
||||
msgIds = msgIds.Substring(0, msgIds.Length - 1);
|
||||
}
|
||||
String[] splits = msgIds.Split(',');
|
||||
List<string> list = new List<string>();
|
||||
try {
|
||||
foreach (String s in splits) {
|
||||
string trim = s.Trim();
|
||||
if (!string.IsNullOrEmpty(trim))
|
||||
{
|
||||
int.Parse(trim);
|
||||
list.Add(trim);
|
||||
}
|
||||
}
|
||||
return StringUtil.arrayToString(list.ToArray());
|
||||
} catch (Exception) {
|
||||
throw new Exception("Every msg_id should be valid Integer number which splits by ','");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private ReceivedResult getReceiveds_common(String msg_ids, string path)
|
||||
{
|
||||
String url = REPORT_HOST_NAME + path + "?msg_ids=" + msg_ids;
|
||||
String auth = Base64.getBase64Encode(this.appKey + ":" + this.masterSecret);
|
||||
ResponseWrapper rsp = this.sendGet(url, auth, null);
|
||||
ReceivedResult result = new ReceivedResult();
|
||||
List<ReceivedResult.Received> list = new List<ReceivedResult.Received>();
|
||||
|
||||
Console.WriteLine("recieve content==" + rsp.responseContent);
|
||||
if (rsp.responseCode == System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
list = (List<ReceivedResult.Received>)JsonTool.JsonToObject(rsp.responseContent, list);
|
||||
String content = rsp.responseContent;
|
||||
}
|
||||
result.ResponseResult = rsp;
|
||||
result.ReceivedList = list;
|
||||
return result;
|
||||
}
|
||||
private MessagesResult getReportMessages(String msgIds)
|
||||
{
|
||||
String checkMsgId = checkMsgids(msgIds);
|
||||
String url = REPORT_HOST_NAME + REPORT_RECEIVE_PATH + "?msg_ids=" + checkMsgId;
|
||||
String auth = Base64.getBase64Encode(this.appKey + ":" + this.masterSecret);
|
||||
ResponseWrapper response = this.sendGet(url, auth, null);
|
||||
|
||||
return MessagesResult.fromResponse(response);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
using Lskj.Push.Common;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Report
|
||||
{
|
||||
public class UsersResult : BaseResult
|
||||
{
|
||||
public TimeUnit time_unit;
|
||||
public String start;
|
||||
public int duration;
|
||||
public UsersResult()
|
||||
{
|
||||
time_unit = TimeUnit.DAY;
|
||||
start = null;
|
||||
duration = 0;
|
||||
}
|
||||
public List<User> items = new List<User>();
|
||||
|
||||
public static UsersResult fromResponse(ResponseWrapper responseWrapper)
|
||||
{
|
||||
UsersResult usersResult = new UsersResult();
|
||||
if (responseWrapper.isServerResponse()) {
|
||||
usersResult = JsonConvert.DeserializeObject<UsersResult> (responseWrapper.responseContent);
|
||||
}
|
||||
usersResult.ResponseResult=responseWrapper;
|
||||
return usersResult;
|
||||
}
|
||||
public override bool isResultOK()
|
||||
{
|
||||
if (Equals(ResponseResult.responseCode, HttpStatusCode.OK))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public class User
|
||||
{
|
||||
|
||||
public String time;
|
||||
public Android android;
|
||||
public Ios ios;
|
||||
public User()
|
||||
{
|
||||
time = null;
|
||||
android = null;
|
||||
ios = null;
|
||||
}
|
||||
}
|
||||
|
||||
public class Android
|
||||
{
|
||||
|
||||
[JsonProperty(PropertyName = "new")]
|
||||
public long add;
|
||||
public int online;
|
||||
public int active;
|
||||
public Android()
|
||||
{
|
||||
add = 0;
|
||||
online = 0;
|
||||
active = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public class Ios
|
||||
{
|
||||
[JsonProperty(PropertyName = "new")]
|
||||
public long add;
|
||||
public int online;
|
||||
public int active;
|
||||
public Ios()
|
||||
{
|
||||
add = 0;
|
||||
online = 0;
|
||||
active = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Util
|
||||
{
|
||||
class Base64
|
||||
{
|
||||
public static String getBase64Encode(String str)
|
||||
{
|
||||
byte[] bytes = Encoding.Default.GetBytes(str);
|
||||
//
|
||||
return Convert.ToBase64String(bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Json;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Script.Serialization;
|
||||
using System.Diagnostics;
|
||||
using Lskj.Push.Report;
|
||||
|
||||
namespace Lskj.Push.Util
|
||||
{
|
||||
public class JsonTool
|
||||
{
|
||||
// 从一个对象信息生成Json串
|
||||
public static string ObjectToJson(object obj)
|
||||
{
|
||||
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
|
||||
MemoryStream stream = new MemoryStream();
|
||||
serializer.WriteObject(stream, obj);
|
||||
byte[] dataBytes = new byte[stream.Length];
|
||||
stream.Position = 0;
|
||||
stream.Read(dataBytes, 0, (int)stream.Length);
|
||||
return Encoding.UTF8.GetString(dataBytes).Replace("\\","");
|
||||
}
|
||||
|
||||
// 从一个Json串生成对象信息
|
||||
public static object JsonToObject(string jsonString, object obj)
|
||||
{
|
||||
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
|
||||
MemoryStream mStream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
|
||||
return serializer.ReadObject(mStream);
|
||||
}
|
||||
|
||||
// 从一个对象信息生成Json串
|
||||
public static string DictionaryToJson(Dictionary<String, Object> dict)
|
||||
{
|
||||
StringBuilder json = new StringBuilder();
|
||||
|
||||
foreach (KeyValuePair<String, Object> pair in dict)
|
||||
{
|
||||
json.Append("\"").Append(pair.Key).Append("\"").Append(":").Append(ValueToJson(pair.Value)).Append(",");
|
||||
}
|
||||
//Console.WriteLine("json String ******"+json);
|
||||
if (json.Length > 0)
|
||||
{
|
||||
json.Remove(json.Length -1, 1);
|
||||
}
|
||||
json.Append("}");
|
||||
json.Insert(0, "{");
|
||||
|
||||
return json.ToString();
|
||||
}
|
||||
|
||||
public static List<ReceivedResult.Received> JsonList(string jsonString)
|
||||
{
|
||||
JavaScriptSerializer Serializer = new JavaScriptSerializer();
|
||||
List<ReceivedResult.Received> jsonclassList = Serializer.Deserialize<List<ReceivedResult.Received>>(jsonString);
|
||||
return jsonclassList;
|
||||
}
|
||||
//从dictionary 的value中解析出字符串
|
||||
private static string ValueToJson(object value)
|
||||
{
|
||||
Type type = value.GetType();
|
||||
if(type==typeof(int)){
|
||||
|
||||
return value.ToString();
|
||||
}else if(type==typeof(string)){
|
||||
|
||||
return "\""+value+"\"";
|
||||
|
||||
}else if(type==typeof(List<int>)||type==typeof(List<string>)){
|
||||
|
||||
return ObjectToJson(value);
|
||||
|
||||
}else if(type==typeof(Dictionary<string,object>)){
|
||||
|
||||
return JsonTool.DictionaryToJson((Dictionary<string, object>)value);
|
||||
}
|
||||
else{
|
||||
Debug.WriteLine("Type in Dictionary is error!");
|
||||
return "type erro";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace Lskj.Push.Util
|
||||
{
|
||||
class Md5
|
||||
{
|
||||
public static String getMD5Hash(String str)
|
||||
{
|
||||
// MD5 md5 = new MD5CryptoServiceProvider();
|
||||
//byte[] res = md5.ComputeHash(Encoding.Default.GetBytes(str), 0, str.Length);
|
||||
//char[] temp = new char[res.Length];
|
||||
//System.Array.Copy(res, temp, res.Length);
|
||||
//return new String(temp);
|
||||
|
||||
|
||||
// 创建MD5类的默认实例:MD5CryptoServiceProvider
|
||||
|
||||
|
||||
MD5 md5 = MD5.Create();
|
||||
|
||||
|
||||
byte[] bs = Encoding.UTF8.GetBytes(str);
|
||||
|
||||
|
||||
byte[] hs = md5.ComputeHash(bs);
|
||||
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
|
||||
foreach (byte b in hs)
|
||||
{
|
||||
|
||||
|
||||
// 以十六进制格式格式化
|
||||
|
||||
|
||||
sb.Append(b.ToString("x2"));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
return sb.ToString();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Util
|
||||
{
|
||||
class Preconditions
|
||||
{
|
||||
public static void checkArgument(bool expression)
|
||||
{
|
||||
if (!expression)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
}
|
||||
public static void checkArgument(bool expression, object errorMessage)
|
||||
{
|
||||
if (!expression)
|
||||
{
|
||||
throw new ArgumentException(errorMessage.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lskj.Push.Util
|
||||
{
|
||||
class StringUtil
|
||||
{
|
||||
|
||||
public bool IsNumber(String strNumber)
|
||||
{
|
||||
Regex objNotNumberPattern=new Regex("[^0-9.-]");
|
||||
Regex objTwoDotPattern=new Regex("[0-9]*[.][0-9]*[.][0-9]*");
|
||||
Regex objTwoMinusPattern=new Regex("[0-9]*[-][0-9]*[-][0-9]*");
|
||||
String strValidRealPattern="^([-]|[.]|[-.]|[0-9])[0-9]*[.]*[0-9]+$";
|
||||
String strValidIntegerPattern="^([-]|[0-9])[0-9]*$";
|
||||
Regex objNumberPattern =new Regex("(" + strValidRealPattern +")|(" + strValidIntegerPattern + ")");
|
||||
|
||||
return !objNotNumberPattern.IsMatch(strNumber) &&
|
||||
!objTwoDotPattern.IsMatch(strNumber) &&
|
||||
!objTwoMinusPattern.IsMatch(strNumber) &&
|
||||
objNumberPattern.IsMatch(strNumber);
|
||||
}
|
||||
|
||||
public static bool IsNumeric(string value)
|
||||
{
|
||||
return Regex.IsMatch(value, @"^[+-]?\d*[.]?\d*$");
|
||||
}
|
||||
public static bool IsInt(string value)
|
||||
{
|
||||
return Regex.IsMatch(value, @"^[+-]?\d*$");
|
||||
}
|
||||
public static bool IsUnsign(string value)
|
||||
{
|
||||
return Regex.IsMatch(value, @"^\d*[.]?\d*$");
|
||||
}
|
||||
public static String arrayToString(String[] values)
|
||||
{
|
||||
if (null == values) return "";
|
||||
|
||||
StringBuilder buffer = new StringBuilder(values.Length);
|
||||
for (int i = 0; i < values.Length; i++)
|
||||
{
|
||||
buffer.Append(values[i]).Append(",");
|
||||
}
|
||||
if (buffer.Length > 0)
|
||||
{
|
||||
return buffer.ToString().Substring(0, buffer.Length - 1);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.6.10.0" newVersion="2.6.10.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.6.10.0" newVersion="2.6.10.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user