极光推送-服务端API开发

极光推送-服务端开发

参数:

https://docs.jiguang.cn

https://community.jiguang.cn

REST API 基本约束

API 被设计为符合HTTP,REST规范.例如:查询请求使用GET方法;提交请求使用POST请求.

API 资源列表

描述资源URL
推送消息APIPOST /v3/pushhttps://api.jpush.cn
操作Tag,AliasGET /v3/deviceshttps://device.jpush.cn
获取统计数据GET /v3/receivedhttps://report.jpush.cn

鉴权方式

  • 极光RSET API采用HTTP基本认证的验证方式.

  • 基本做法为: HTTP Header(头)里加Authorization:

Authorization: Basic $(base64_auth_string)
  • Header名称是”Authorization",值是Base64加密后的”username:password”.

在JPushAPI的场景里,username是appKey,密码是masterSecret.

  • 配置文件配置类
@Getter
@Component
@ConfigurationProperties("jpush")
public class JPushProperties {
  @ApiModelProperty("应用程序:app_key&&master_secret")
	private Map<String, Map<String, String>> applications = new HashMap<>(4);
  
  private String appKey;
  private String masterSecret;
  
  public void initProperties(JpushAppEnum appEnum) {
    Map<String, String> appMap = this.applications.get(appEnum.getCode());
    this.appKey = appMap.get("app_key");
    this.masterSecret = appMap.get("master_secret");
  }
}
  • 构建不同的HTTP请求
@Component
public class JpushUtils {
  private JpushUtils {}

  @Autowired
  private JPushProperties properties;
  
  private IHttpClient httpClient;
  /**
   * @param appEnum 应用(不同的应用有不同的appKey和masterSecret)
   */
  private synchronized IHttpClient initInstance(JpushAppEnum appEnum) {
    switch(appEnum) {
      case xxx:
        if (null != httpClient) {
          properties.initProperties(appEnum);
          String basicAuthorization = ServiceHelper.getBasicAuthorization(properties.getAppKey(), properties.getMasterSecret());
          // 使用ApacheHttpClient
          httpClient = new ApacheHttpClient(basicAuthorization, null, config);
        }
        break;
      case xxx:
        if (null != httpClient) {
          properties.initProperties(appEnum);
          String basicAuthorization = ServiceHelper.getBasicAuthorization(properties.getAppKey(), properties.getMasterSecret());
          // 使用NativeHttpClient(极光默认的HttpClient:JPushClient)
          httpClient = new NativeHttpClient(basicAuthorization, null, config);
        }
        break;
      case xxx:
        if (null != httpClient) {
          properties.initProperties(appEnum);
          String basicAuthorization = ServiceHelper.getBasicAuthorization(properties.getAppKey(), properties.getMasterSecret());
          // 使用NettyHttpClient
          httpClient = new NettyHttpClient(basicAuthorization, null, config);
        }
        break;
      default:
        if (null != httpClient) {
          properties.initProperties(appEnum);
          String basicAuthorization = ServiceHelper.getBasicAuthorization(properties.getAppKey(), properties.getMasterSecret());
          // 使用Http2Client
          httpClient = new Http2Client(basicAuthorization, null, config);
        }
        break
    }
  }
}

PUSH API

完全基于HTTPS,不再提供HTTP访问;

使用Http Basic Authentication的方式做访问授权.这样整个API请求可以使用常见的HTTP工具来完成;

推送内容完全使用JSON格式;

支持多tag的与或操作;可单独发送通知或者自定义消息,也可以同时推送通知与自定义消息.

推送对象

一个推送对象,以JSON格式表示,表示一条推送相关的所有信息.

关键字选项含义
platform必填推送平台设置
audience必填推送设备指定
notification可选通知内容体.与message二者必须有其一
message可选消息内容体.与notification二者必须有其一
sms_message可选短信渠道补充送达内容体
options可选推送参数
cid可选用于防止api调用端重试造成服务端的重复推送而定义的一个标识符
platform: 推送平台
  • JPush当前支持Android,ios,WindowsPhone.其中关键字为: “android”, “ios”, “winphone”
  • 注意: 如果目标平台为ios平台,推送Notification时需要在options中通过apns_production字段来设定推送环境.True表示推送生产环境,False表示要推送开发环境.如果不指定则为推送生产环境,一次只能推送给一个环境
audience: 推送目标
  • 推送设备对象,表示一条推送可以被推送到哪些设备列表.确认推送设备对象,JPush提供了多种方式,比如:别名,标签,注册ID,分群,广播等
关键字类型含义说明备注
allJSONArray全部设备.(广播)
tagJSONArrayOR数组.多个标签之间的OR的关系一个推送最多20个.每个tag的长度限制为40字节
tag_andJSONArrayAND数组.多个标签之间是AND的关系注意与tag的区别.一次推送最多20个
tag_notJSONArrayNOT数组.多个标签之间,先取多标签的并集,再对该结果取补集一次推送最多20个
aliasJSONArray别名数组.多个别名之间是OR关系一个设备只能绑定一个别名;一次推送最多1000个;每个alias的长度限制为40字节
Registration_idJSONArray注册ID数组.多个注册ID之间是OR关系设备标识.一次推送最多1000个,客户端集成SDK后可获取到该设备
notification: 通知
  • 通知对象.是一条推送的实体内容对象之一
  • alter : 通知的内容在各个平台上,都可能只有一个最基本的属性”alter”
message: 自定义消息
  • 应用内消息.(自定义消息,透传消息)
  • 此部分内容不会展示到通知栏上,JPushSDK收到消息内容后透传给APP,需要APP自行处理.
关键字类型选项含义
msg_contentstring必填消息内容本身
titlestring可选消息标题
content_typestring可选消息内容类型
extrasJSONObject可选JSON格式的可选参数

案例说明

  • 推送对象
@Data
private class JPushParam {
  private Platform platform;
  private Audience audience;
  private JPushMessage message;
}
  • 消息体
@Data
public class JPushMessage {
  private String title;
  private String msgContent;
  private String contentType;
  private Map<String, String> extras;
  private Map<String, JsonObject> jsonExtras;
} 
  • 构建消息体
public class BuildPayloadUtils {
  public static PushPayload getPayload(JpushParam param) {
    JPushMessage message = param.getMessage();
    PushPayload.Builder pushBuilder = PushPayload.newBuilder();
    // 构建推送平台
    if (null != param.getPlatform) {
      pushBuilder.setPlatform(param.getPlatform());
    } else {
      pushBuilder.setPlatform(Platform.all());
    }
    // 构建推送目标
    if (null != param.getAudience) {
      pushBuilder.setAudience(param.getAudience());
    } else {
      pushBuilder.setAudience(param.all());
    }
    // 构建通知和自定义消息
    setMessageOrAlter(pushBuilder, message, PushWayEnum.ALL);
  }
  
  /**
   * @param wayEnum 通知和消息(只选其一还是两者都有)
   */
  private static void setMessageOrAlter(PushPayload.Builder pushBuilder, JPushMessage message, PushWayEnum wayEnum) {
        switch (wayEnum) {
            case ALL:
                pushBuilder.setNotification(Notification.newBuilder()
                        .setAlert(message.getMsgContent())
                        .addPlatformNotification(getAndroidNotificationBuilder(message).build())
                        .addPlatformNotification(getIosNotificationBuilder(message).build())
                        .build())
                        .setMessage(getMessageBuilder(message).build());
                break;
            case ALTER:
                pushBuilder.setNotification(Notification.newBuilder()
                        .setAlert(message.getMsgContent())
                        .addPlatformNotification(getAndroidNotificationBuilder(message).build())
                        .addPlatformNotification(getIosNotificationBuilder(message).build())
                        .build());
                break;
            case MESSAGE:
                pushBuilder.setMessage(getMessageBuilder(message).build());
                break;
            default:
                break;
        }
    }
  
  private static AndroidNotification.Builder getAndroidNotificationBuilder(JPushMessage message) {
        AndroidNotification.Builder androidBuilder = AndroidNotification.newBuilder();
        if (StringUtils.isNotEmpty(message.getTitle())) {
            androidBuilder.setTitle(message.getTitle());
        }
        if (StringUtils.isNotEmpty(message.getMsgContent())) {
            androidBuilder.setAlert(message.getMsgContent());
        }
        if (!CollectionUtils.isEmpty(message.getExtras())) {
            androidBuilder.addExtras(message.getExtras());
        }
        return androidBuilder;
    }

    private static IosNotification.Builder getIosNotificationBuilder(JPushMessage message) {
        IosNotification.Builder iosBuilder = IosNotification.newBuilder().incrBadge(1);
        if (StringUtils.isNotEmpty(message.getMsgContent())) {
            iosBuilder.setAlert(message.getMsgContent());
        }
        if (!CollectionUtils.isEmpty(message.getExtras())) {
            iosBuilder.addExtras(message.getExtras());
        }
        return iosBuilder;
    }
  
    private static Message.Builder getMessageBuilder(JPushMessage message) {
        Message.Builder messageBuilder = Message.newBuilder();
        if (StringUtils.isNotEmpty(message.getTitle())) {
            messageBuilder.setTitle(message.getTitle());
        }
        if (StringUtils.isNotEmpty(message.getMsgContent())) {
            messageBuilder.setMsgContent(message.getMsgContent());
        }
        if (!CollectionUtils.isEmpty(message.getExtras())) {
            messageBuilder.addExtras(message.getExtras());
        }
        if (!CollectionUtils.isEmpty(message.getJsonExtras())) {
            Map<String, JsonObject> jsonExtras = message.getJsonExtras();
            for (Map.Entry<String, JsonObject> entry : jsonExtras.entrySet()) {
                messageBuilder.addExtra(entry.getKey(), entry.getValue());
            }
        }
        return messageBuilder;
    }
}

注意: 推送的消息体有大小限制.Android平台Notification+Message长度限制为4000字节.IOS中Notification中“ios”:{}及大括号内的总体长度不超过2000字节.IOS的Message部分长度不超过4000字节.

  • 推送方法
private PushResult getPushResult(JPushAppEnum appEnum, PushPayload payload, String url) {
  PushResult result = null;
  try {
    ResponseWrapper response = httpClient.sendPost(url, payload.toString());
    result = BaseResult.fromResponse(response, PushResult,class);
  } catch (ApiConnectionException e) {
    log.error("[push] Connection error, should retry later", e);
    log.warn("[push] push again. start....");
    // 如果是因为连接超时导致推送失败,这里做个重新推送的操作(不过正常情况下,需要做下限制:比如多次推送都失败,就不应该让他一直重试.)
    getPushResult(appEnum, payload, url);
  } catch (APIRequestException e) {
    log.error("[push] Should review the error, and fix the request", e);
    log.error("[push] HTTP Status: " + e.getStatus());
    log.error("[push] Error Code: " + e.getErrorCode());
    log.error("[push] Error Message: " + e.getErrorMessage());
  }
  return result;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值