即时通讯
客户端 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 分别只关闭消息或来电通知。

zim->QuerySelfUserInfo([=](unsigned int seq, const ZIMSelfUserInfo &userInfo,
                           const ZIM::ZIMError &errorInfo) {
    if (errorInfo.code != 0) {
        return;
    }
    // 全量更新:基于查询到的完整规则修改目标字段后整体提交
    ZIMUserOfflinePushRule rule = userInfo.userRule_.offline_push_rule_;
    rule.offline_push_enabled_ = false;            // 关闭全部离线推送
    // rule.message_offline_push_enabled_ = false; // 仅关闭消息类离线推送
    // rule.call_offline_push_enabled_ = false;    // 仅关闭来电类离线推送
    zim->UpdateUserOfflinePushRule(rule, [=](const ZIM::ZIMError &errorInfo) {
        // errorInfo.code == 0 表示修改成功
    });
});

场景二:设置个人免打扰

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

说明

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

ZIMUserOfflinePushDoNotDisturbRule dnd_rule;
dnd_rule.enabled_ = true;
dnd_rule.start_hour_ = 22;     // 22:00 开始
dnd_rule.end_hour_ = 8;        // 次日 08:00 结束(end < start 表示跨零点)
dnd_rule.repeat_mode_ = zim_user_offline_push_do_not_disturb_repeat_mode_daily;
dnd_rule.time_zone_id_ = "Asia/Shanghai"; // 按用户所在时区生效;留空则服务端按 UTC 计算

ZIMUserOfflinePushRule rule;
rule.do_not_disturb_rule_ = dnd_rule;

zim->UpdateUserOfflinePushRule(rule, [=](const ZIM::ZIMError &errorInfo) {
});

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

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

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

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

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

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

ZIMUserOfflinePushRule rule;
// 桌面端(WIN = 1、MAC_OS = 4)在线时……
rule.online_platforms_ = {1, 4};
// ……移动端(ANDROID = 3、IPHONE_OS = 2)不收离线推送
rule.not_to_receive_offline_push_platforms_ = {2, 3};

zim->UpdateUserOfflinePushRule(rule, [=](const ZIM::ZIMError &errorInfo) {
});

查询当前规则

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

zim->QuerySelfUserInfo([=](unsigned int seq, const ZIMSelfUserInfo &userInfo,
                           const ZIM::ZIMError &errorInfo) {
    if (errorInfo.code == 0) {
        auto rule = userInfo.userRule_.offline_push_rule_;
        auto dnd = rule.do_not_disturb_rule_;
        // dnd.once_end_timestamp_ 为一次性免打扰时段的服务端记录结束时刻,
        // 本端设置时传 0 即可,回读在此处获取
    }
});

监听多端规则变更

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

// 继承 ZIMEventHandler 并重写:
void MyHandler::OnUserRuleUpdated(ZIM *zim, const ZIMUserRule &user_rule) {
    auto rule = user_rule.offline_push_rule_;
    // 刷新本地展示
}

注意事项

  • 全量更新语义: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)。

上一篇

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

下一篇

发送表情消息