即时通讯
客户端 SDK
发布日志
升级指南
错误码
当前页

配置离线推送规则

2026-11-09

功能简介

本文介绍了如何使用 ZIM SDK 配置当前用户的离线推送规则,包括推送总开关与分类开关、多端在线时抑制指定端推送,以及免打扰时段(支持每天重复、自定义星期重复与指定时区)。

前提条件

已参考 快速开始 集成 ZIM SDK 并登录。

规则结构说明

离线推送规则由 ZIMUserOfflinePushRule 描述,包含以下成员:

成员类型说明
offlinePushEnabledboolean离线推送总开关,默认开。关闭后任何离线推送(消息与来电)都不下发。
messageOfflinePushEnabledboolean是否接收消息类离线推送,默认开。只影响消息推送,不影响来电推送。
callOfflinePushEnabledboolean是否接收来电类离线推送,默认开。只影响来电推送,不影响消息推送。
onlinePlatformsList<int>与 notToReceiveOfflinePushPlatforms 搭配使用:此处指定平台在线时,后者指定的平台不收离线推送。平台取值见 ZIMPlatformType(如 WIN = 1、IPHONE_OS = 2、ANDROID = 3、MAC_OS = 4)。
notToReceiveOfflinePushPlatformsList<int>被抑制推送的平台列表,语义同上。
doNotDisturbRuleZIMUserOfflinePushDoNotDisturbRule免打扰时段规则,对消息类与来电类推送同时生效。

免打扰时段规则 ZIMUserOfflinePushDoNotDisturbRule 的成员如下:

成员类型说明
enabledboolean是否启用免打扰,默认关。
startHour / startMinuteint开始时间,取值 [0, 23] / [0, 59]。
endHour / endMinuteint结束时间,取值 [0, 23] / [0, 59]。结束时间早于开始时间表示跨零点时段(如 22:00 - 次日 08:00)。
repeatModeenum重复模式,见下表。
customRepeatDaysint自定义重复日的位掩码,bit0 = 周一 … bit6 = 周日。仅自定义模式生效。
onceEndTimestampunsigned long long一次性免打扰时段的结束时间戳(UNIX 秒)。该值由服务端在保存规则时记录,本端设置时无需填写,回读时获取。
timeZoneIDstring免打扰时段所在时区的 IANA 名称,如 "Asia/Shanghai"。为空表示未指定(服务端按 UTC 计算)。SDK 纯透传,不校验合法性;需要按用户当地时区生效时请显式传入。

重复模式 ZIMUserOfflinePushDoNotDisturbRepeatMode:

取值含义
Unknown(-1)未设置,或服务端返回了本 SDK 未识别的模式。更新规则时 SDK 按"不重复"上报。
None(1)不重复:规则仅在保存当日生效一次。
Daily(2)每天重复。
Custom(3)自定义重复:配合 customRepeatDays 位掩码指定每周几生效。

推送过滤的判定优先级

用户收到离线推送前,服务端按以下优先级链过滤(前台在线时不走推送链路,正常投递):

总开关 > 免打扰窗口(按 timeZoneID 折算时段 + 重复日判定)> 分类开关 = 在线平台规则

同级取与、任一层命中即不推送。各开关覆盖的产生离线推送的接口范围如下:

开关覆盖范围
offlinePushEnabled(总开关)一切离线推送通知,不限于消息与来电两类。
messageOfflinePushEnabled(消息通知)仅 sendMessage(单聊 / 群聊;房间消息不产生离线推送)与 revokeMessage(撤回通知),与消息类型无关。
callOfflinePushEnabled(来电通知)callInvite、callInviting、callCancel、callQuit、callEnd 呼叫链路产生的全部离线推送。
注意
  • 群 / 好友 / 社群申请审批类接口(如 sendGroupJoinApplication、sendFriendApplication 等)产生的通知推送不属于两个分类开关的管辖范围,仅受总开关与免打扰约束。
  • @ 提及消息不穿透任何一层:总开关、消息开关或免打扰任一生效时,@ 消息推送与普通消息同样被拦截。
  • 用户级各层与发送端既有的消息级推送配置(pushConfig.enablePush / callInviteConfig.enableOfflinePush)为叠加关系,两层均放行才会推送。

设置离线推送规则

通过 updateUserOfflinePushRule 可以修改当前用户的离线推送规则。

注意

updateUserOfflinePushRule 的调用为全量更新:每次调用都会按传入对象的全部成员覆盖服务端存储的规则,传入空值时会使用默认规则配置,而不是保留旧规则配置。

如需只修改某一项规则,请先通过 querySelfUserInfo 获取现有的完整规则,在返回的副本上修改目标字段后整体提交。不要新构造规则配置直接提交,新的规则有未设置的成员会使用默认值覆盖(例如,开关回到 true、免打扰关闭、时区清空)。

场景一:关闭个人通知

按需求选择关闭方式:offlinePushEnabled 关闭全部离线推送(消息与来电都不再下发);messageOfflinePushEnabled、callOfflinePushEnabled 分别只关闭消息或来电通知。

try {
  const zim = ZIM.getInstance();
  const result = await zim.querySelfUserInfo();
  // 全量更新:基于查询到的完整规则修改目标字段后整体提交
  const rule = result.selfUserInfo.userRule.offlinePushRule;
  rule.offlinePushEnabled = false;          // 关闭全部离线推送
  // rule.messageOfflinePushEnabled = false; // 仅关闭消息类离线推送
  // rule.callOfflinePushEnabled = false;    // 仅关闭来电类离线推送
  await zim.updateUserOfflinePushRule(rule);
} catch (error) {
  // error.code 为错误码
}

场景二:设置个人免打扰

doNotDisturbRule.enabled = true 时,每次提交都必须同份显式携带完整时段参数(起止时分 + repeatMode;custom 模式另带 customRepeatDays;需按非 UTC 时区生效的必须显式带 timeZoneID)——不存在「先开启、后补时段」的用法。仅关闭免打扰(enabled = false)时无此要求。

说明

结束时间早于开始时间表示跨零点时段。

const zim = ZIM.getInstance();
const dndRule = {
  enabled: true,
  startHour: 22,      // 22:00 开始
  startMinute: 0,
  endHour: 8,         // 次日 08:00 结束(end < start 表示跨零点)
  endMinute: 0,
  repeatMode: ZIMUserOfflinePushDoNotDisturbRepeatMode.Daily,
  customRepeatDays: 0,
  onceEndTimestamp: 0, // 只读字段,设置时传 0
  timeZoneID: 'Asia/Shanghai' // 按用户所在时区生效;留空则服务端按 UTC 计算
};

const rule = {
  onlinePlatforms: [],
  notToReceiveOfflinePushPlatforms: [],
  offlinePushEnabled: true,
  messageOfflinePushEnabled: true,
  callOfflinePushEnabled: true,
  doNotDisturbRule: dndRule
};

await zim.updateUserOfflinePushRule(rule);

如需仅每周指定几天生效,将 repeatMode 改为 CUSTOM,并通过 customRepeatDays 位掩码指定星期:

星期所在位数值
周一bit01
周二bit12
周三bit24
周四bit38
周五bit416
周六bit532
周日bit664

将需要生效的星期对应数值按位或运算后填入,如工作日(一 ~ 五)为 31(0b011111)、周末(六、日)为 96(0b1100000)、周一三五为 21(0b10101)。

注意
  • customRepeatDays = 0 表示无重复日,规则在任何一天都不会屏蔽推送。
  • 该字段仅在 repeatMode = Custom 时生效;切换到其他模式后服务端联动清零,回读为 0。

场景三:桌面端在线时,移动端不接收离线推送

多端登录场景下,onlinePlatforms 指定的平台在线时,notToReceiveOfflinePushPlatforms 指定的平台将不会收到离线推送。

const zim = ZIM.getInstance();
const rule = {
  // 桌面端(Win、MacOS)在线时……
  onlinePlatforms: [ZIMPlatformType.Win, ZIMPlatformType.MacOS],
  // ……移动端(IPhoneOS、Android)不收离线推送
  notToReceiveOfflinePushPlatforms: [ZIMPlatformType.IPhoneOS, ZIMPlatformType.Android],
  offlinePushEnabled: true,
  messageOfflinePushEnabled: true,
  callOfflinePushEnabled: true,
  doNotDisturbRule: {
    enabled: false, startHour: 0, startMinute: 0, endHour: 0, endMinute: 0,
    repeatMode: ZIMUserOfflinePushDoNotDisturbRepeatMode.Unknown,
    customRepeatDays: 0, onceEndTimestamp: 0, timeZoneID: ''
  }
};

await zim.updateUserOfflinePushRule(rule);

查询当前规则

调用 querySelfUserInfo 获取当前用户信息,其中 userRule.offlinePushRule 即当前生效的离线推送规则。修改规则前的"先查后改"也依赖此接口。

try {
  const zim = ZIM.getInstance();
  const result = await zim.querySelfUserInfo();
  const rule = result.selfUserInfo.userRule.offlinePushRule;
  const dnd = rule.doNotDisturbRule;
  // dnd.onceEndTimestamp 为一次性免打扰时段的服务端记录结束时刻,
  // 本端设置时传 0 即可,回读在此处获取
} catch (error) {
  // error.code 为错误码
}

监听多端规则变更

任一端调用 updateUserOfflinePushRule 成功后,该用户所有在线端都会收到 onUserRuleUpdated 回调。建议各端在收到回调后刷新本地设置页展示。

const zim = ZIM.getInstance();
zim.on('userRuleUpdated', (zim, result) => {
  const rule = result.userRule.offlinePushRule;
  // 刷新本地展示
});

注意事项

  • 全量更新语义:updateUserOfflinePushRule 每次调用都会覆盖全部成员。单项修改务必"先 onUserRuleUpdated 查全量、改副本、再整体提交"。
  • 重复模式回读:对外仅提供不重复 / 每天 / 自定义三种模式;「工作日 / 周末」等需求请用 custom 模式位掩码表达(工作日 = 0b011111 = 31、周末 = 0b1100000 = 96)。不设置 repeatMode 是合法用法(等价仅当日生效一次),更新时 SDK 按不重复上报,回读为 None(1)。
  • 版本兼容:旧版本 SDK 端(不含新字段)调用 updateUserOfflinePushRule 不会清除新版本端已配置的开关与免打扰设置。
  • 时区:timeZoneID 为 IANA 名称(如 "Asia/Shanghai"),服务端按该时区(含夏令时规则)计算免打扰窗口;留空表示未指定,服务端按 UTC 计算。
  • 跨零点:结束时间早于开始时间即表示跨零点时段(22:00 - 08:00 = 22:00 至次日 08:00)。

上一篇

实现消息阅后即焚与定时销毁

下一篇

发送表情消息