米米商聊免打扰功能拆解:消息接收、提醒规则与 @ 例外

简介: 本文解析米米商聊“免打扰”本质:消息照常接收,仅抑制提醒;群内@可设例外触发提醒。通过JS示例厘清消息到达、应用规则、系统通知三层边界,助产品与开发者精准定位问题。(239字)

开启免打扰后,没有听见提示声,是消息没有收到,还是提醒被减少了?群里有人 @ 自己时,又该怎样理解这项设置?

本文以米米商聊的免打扰功能为观察对象,面向产品设计与客户端开发读者,拆解消息接收、应用内提醒规则和系统通知条件之间的关系,再用一个可运行的 JavaScript 示例检查容易混淆的边界。

产品事实依据来自产品方提供的手机端功能说明。代码、字段和情境数据为独立教学示例,不是产品源码;未据此判断其实际消息服务或推送架构。内容及配图使用 AI 辅助,示例已经独立运行核验。

1. 免打扰改变的是提醒方式

目前资料支持以下描述:

功能事实 需要保留的边界
免打扰主要调整提醒方式,消息仍正常接收 不能把这项设置解释为阻止接收消息
群内 @ 提醒存在例外 不能承诺开启后任何情况都没有提醒
聊天可以置顶 置顶是查找与展示安排,不应直接等同于提醒强度

“消息仍正常接收”描述的是免打扰设置的作用,不是断网、进程退出或后台受限时仍然实时送达的承诺。

本文也不把未读红点、未读数字等具体样式作为功能结论。它们需要结合当前客户端与版本核对,不能仅凭某种样式没有出现就判断“消息没收到”。桌面端的完整免打扰流程,本轮没有对应的逐项实测资料,不直接套用手机操作步骤。

2. 消息与提醒至少有三种状态

对类似聊天产品进行设计时,可以把一个事件拆成以下问题:

  1. 消息是否已经进入客户端的数据处理流程?
  2. 应用根据会话偏好与提及规则,是否准备请求提醒?
  3. 系统是否允许并实际呈现这次通知?

这三个问题不应只用一个 success 表示。例如,消息已经进入会话,应用选择不请求系统通知,是一个明确的提醒策略结果;它不等于消息数据处理失败。应用请求了通知,也不等于系统一定已经呈现,更不等于用户已经看见或理解了内容。

消息处理与系统通知请求的独立分支示意

图:通用设计模型。提醒请求被抑制,不代表已到达的消息从会话中消失;不是 App 实际界面或内部链路。

对日志、测试和反馈材料而言,记录“收到事件”“规则决定”“系统请求结果”通常比只记录“通知成功/失败”更有解释力。具体日志字段如何设计仍应根据实际系统决定,本文不将示例字段说成产品已有能力。

3. 用独立函数表达提醒优先级

下面只处理已经交给客户端的消息事件,返回是否建议请求一次系统通知,不发送通知,也不处理消息网络接收。

示例选择以下规则:本人发送、会话不匹配、已经提醒过、当前会话可见时,不额外请求系统通知;系统通知条件不允许时不请求;免打扰抑制普通消息,但可通过 mentionOverride 显式决定是否保留对本人提及的例外。

其中“当前会话可见时不额外请求”是本文的示例策略,不是对米米商聊当前行为的断言。mentionOverride 同样是讲解用配置;产品中具体的 @ 处理应以当前客户端规则为准。

function validId(value) {
   
  return typeof value === "string" && value.length > 0 && value === value.trim();
}

function notificationPlan(message, preferences, environment) {
   
  const no = reason => ({
    requestSystemNotice: false, reason });
  if (!message || !preferences || !environment) return no("invalid-input");
  const ids = [message.id, message.senderId, message.conversationId,
    preferences.currentUserId, preferences.conversationId];
  if (!ids.every(validId)) return no("invalid-input");
  if (!Array.isArray(message.mentionedIds) ||
      ![...message.mentionedIds].every(validId)) return no("invalid-input");
  const flags = [preferences.dnd, preferences.mentionOverride,
    environment.systemAllowed, environment.conversationVisible,
    environment.alreadyNotified];
  if (!flags.every(value => typeof value === "boolean")) return no("invalid-input");

  if (message.conversationId !== preferences.conversationId) return no("wrong-conversation");
  if (message.senderId === preferences.currentUserId) return no("self-message");
  if (environment.alreadyNotified) return no("already-notified");
  if (environment.conversationVisible) return no("conversation-visible");
  if (!environment.systemAllowed) return no("system-not-allowed");

  const mentionsMe = message.mentionedIds.includes(preferences.currentUserId);
  const exception = mentionsMe && preferences.mentionOverride;
  if (preferences.dnd && !exception) return no("conversation-dnd");
  return {
   
    requestSystemNotice: true,
    reason: preferences.dnd ? "mention-exception" : "regular-message"
  };
}

这里故意保留 reason。单个 false 无法解释究竟是本人消息、当前正在查看、系统条件不允许,还是会话免打扰在起作用。

mentionedIds 用账号标识表达提及对象,不通过正文中的“@某个昵称”字符串判断。模型希望避免把引用文字或同名昵称直接当成一次有效提及;实际产品如何解析提及对象,仍需要其真实协议与实现资料。

alreadyNotified 是调用方提供的状态,函数没有维护去重记录。工程接入时,需要明确它代表哪一个动作已经完成,以及失败重试怎样处理;不能把“消息已接收”直接写成“提醒已完成”。

4. 系统通知条件应由平台适配层提供

应用内会话偏好和系统通知许可属于不同来源的条件。例如,在支持的 Web 环境中,Notification.permission 有 granted、denied、default 三种状态,不能把尚未授权的 default 当成允许。MDN:Notification.permission

Android 官方文档也说明了 Android 13 起的通知运行时权限及相关适用情形。Android:通知运行时权限

两种平台的接口并不相同。本文函数中的 systemAllowed 是为了让模型保持独立而使用的布尔输入,实际接入应由对应平台适配层计算,不代表米米商聊使用了 Web Notification API。

即使条件允许,函数返回 true 也只是建议提出请求。展示、声音和失败处理应由真实平台调用结果与对应设置决定,不能把纯函数测试当作系统通知呈现测试。

5. 用明确预期检查普通消息与例外

将下段代码接在前一段后,可以直接用 Node.js 运行。测试使用虚构账号和会话标识,不读取真实聊天内容。

const assert = require("node:assert/strict");
const M = extra => ({
    id: "m1", senderId: "peer", conversationId: "room",
  mentionedIds: [], ...extra });
const P = extra => ({
    currentUserId: "me", conversationId: "room",
  dnd: false, mentionOverride: true, ...extra });
const E = extra => ({
    systemAllowed: true, conversationVisible: false,
  alreadyNotified: false, ...extra });

const cases = [
  ["普通消息", M(), P(), E(), true, "regular-message"],
  ["免打扰普通消息", M(), P({
   dnd:true}), E(), false, "conversation-dnd"],
  ["对本人提及例外", M({
   mentionedIds:["me"]}), P({
   dnd:true}), E(), true, "mention-exception"],
  ["提及其他人", M({
   mentionedIds:["other"]}), P({
   dnd:true}), E(), false, "conversation-dnd"],
  ["例外未启用", M({
   mentionedIds:["me"]}), P({
   dnd:true,mentionOverride:false}), E(), false, "conversation-dnd"],
  ["系统条件不允许", M(), P(), E({
   systemAllowed:false}), false, "system-not-allowed"],
  ["提及不绕过系统条件", M({
   mentionedIds:["me"]}), P({
   dnd:true}), E({
   systemAllowed:false}), false, "system-not-allowed"],
  ["当前会话可见", M(), P(), E({
   conversationVisible:true}), false, "conversation-visible"],
  ["提及不改变可见会话策略", M({
   mentionedIds:["me"]}), P({
   dnd:true}), E({
   conversationVisible:true}), false, "conversation-visible"],
  ["本人发送", M({
   senderId:"me"}), P(), E(), false, "self-message"],
  ["会话不匹配", M({
   conversationId:"other-room"}), P(), E(), false, "wrong-conversation"],
  ["已经提醒过", M(), P(), E({
   alreadyNotified:true}), false, "already-notified"],
  ["字符串不是布尔配置", M(), P({
   dnd:"false"}), E(), false, "invalid-input"],
  ["缺少有效用户ID", M(), P({
   currentUserId:""}), E(), false, "invalid-input"],
  ["正文文字不是结构化提及", M({
   body:"@me"}), P({
   dnd:true}), E(), false, "conversation-dnd"]
];

for (const [name, message, prefs, env, allowed, reason] of cases) {
   
  assert.deepEqual(notificationPlan(message, prefs, env),
    {
   requestSystemNotice:allowed, reason}, name);
}

for (const [, message, prefs, env] of cases) {
   
  assert.deepEqual(notificationPlan(message, {
   ...prefs,pinned:true}, env),
    notificationPlan(message, {
   ...prefs,pinned:false}, env), "置顶不改变本模型提醒策略");
}

const inputs = [M({
   mentionedIds:["me"]}), P({
   dnd:true}), E()];
const before = JSON.stringify(inputs);
notificationPlan(...inputs);
assert.equal(JSON.stringify(inputs), before, "不改写输入对象");
console.log("17组检查通过");

本次在 Node.js v24.19.0 实际运行了文章中的两个代码块:15组明确预期样例、置顶不变性和输入不被改写两组检查,全部通过。范围是独立函数,不包含产品客户端、真实消息服务或系统通知 API 的集成测试。

6. 实际验收怎样避免判断错对象

对类似聊天系统做验收时,适合分别记录以下观察结果:

观察项 可以回答什么问题
会话中是否出现目标消息 已到达事件是否进入对应界面的处理流程
规则返回的结果与原因 哪一个提醒条件在起作用
系统通知请求的实际结果 请求是否被平台接受或失败
用户是否打开并查看内容 不能只凭发出提醒就推断用户已看见

这些是验收建议,不是当前客户端日志或回执功能的清单。收到事件、提出提醒、系统呈现与人的实际阅读分别是什么状态,应按真实材料说明。

免打扰功能的专业拆解,重点是明确设置作用于哪一层。当接收与提醒被分别描述,用户容易理解为何普通消息没有提示却仍在会话中,开发者也更容易定位是会话规则、提及例外,还是平台通知条件影响了结果。

相关文章
|
9天前
|
人工智能 JSON API
全网刷屏的 Jev 模型正式开放!一手实战测评 + 保姆级教程
全网爆火的 Jev 模型是什么?有什么用?怎么使用?怎么接入 AI 编程工具?效果真的好么?傻子可懂的 Jev 保姆级实战教程 + 项目实战测评来啦
7709 13
|
8天前
|
人工智能 测试技术 API
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
Jev是TypeSafe AI推出的“系统一模型”,不生成文本,专做毫秒级结构化决策:Choice(多选)、Score(打分)、Noul(是非概率)。响应快193倍、成本低444倍,适合工单路由、内容审核、测试定级等高频判断场景。
1661 4
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
|
4天前
|
人工智能 JavaScript 芯片
DeepSeek 官方偷偷上传 Harness 桌面端安装包,我已经用上了。。附最新下载地址
DeepSeek Harness 官方的桌面端安装包被网友扒出来了,2 分钟讲明白如何使用,体验如何,适合作为 AI 编程工具么?附最新 Windows 和 Mac 双端的下载地址
1429 1
|
8天前
|
人工智能 并行计算 PyTorch
秋叶 ComfyUI 2026 整合包 v3.2 完整部署教程:Python 3.13 + Torch 2.13 全栈升级
秋叶aaaki ComfyUI 2026年8月整合包v3.2正式发布!全面升级Python 3.13.11、PyTorch 2.13.0+cu130及ComfyUI v0.30.2,原生支持MiniMax H3、Wan 2.2、Qwen-Image-2.1等2026主流音视频/图像模型,解压即用,无需环境配置。
1231 10
|
21天前
|
人工智能 自然语言处理 安全
阿里云千问办公 QwenWork详细介绍:产品核心能力、典型场景、价格及常见问题解答
千问办公是阿里云推出的一站式AI办公平台,主打"不止于对话,更注重交付",依托通义千问旗舰大模型,用户一句话即可完成数据分析、PPT生成、视频剪辑等复杂任务,直接输出可用成果。产品深度打通钉钉生态与企业OA,覆盖桌面端、网页端,提供企业标准版198元/人/月等多档订阅方案,新用户注册即赠2000积分,适配工程师、HR、财务等多职业办公场景,成为能动手干活的"全能AI同事"。
3684 10
|
6天前
|
人工智能 编解码 并行计算
MiniMax-H3 一键整合包技术文档:8G 显存运行 AI 漫剧制作 —— 角色替换 / 动作迁移 / 文图生视频部署与调参指南
MiniMax H3 是 MiniMax 开源的全模态视频生成模型,支持文/图/音/视多条件输入,输出最高2K、15秒带双声道音频视频。本文档详述其Int8量化版在8GB显存下的本地一键部署、三段式工作流(EDIT/REPLACE/CONTINUE)、参数调优及常见问题排查。(239字)
|
16天前
|
缓存 IDE Java
【保姆级】Android Studio下载、安装和汉化教程(2026最新)
Android Studio 是 Google 官方推出的免费 Android 应用开发集成环境,基于 IntelliJ IDEA,内置模拟器、调试器、性能分析及 Compose 界面工具,功能全面,文档丰富,是安卓开发首选工具。(239字)
1752 1

热门文章

最新文章