协同办公

Odoo Discuss 频道为什么分 chat、group、channel:成员上限、公开组授权与邀请边界讲透

Odoo Discuss 里的 chat、group、channel 不是三个 UI 名字,而是三种不同的协作边界模型。源码把成员数量、公开访问、群组授权、父子频道与邮件邀请能力都分得很细,这正是频道治理不失控的基础。

协同办公
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 6 阅读

先说结论

在 Odoo Discuss 里,很多人以为:

  • chat 就是私聊,
  • group 就是群聊,
  • channel 就是频道。

这当然没错,但太浅了。

discuss_channel.pyres_partner.py 的源码看,三者真正的区别不是名字,而是协作边界的设计

  • 谁能加入;
  • 是否可以公开授权;
  • 成员数量怎么约束;
  • 父子频道能不能继承边界;
  • 邀请建议能不能越权。

一句话说:

Odoo Discuss 的频道类型,本质上是在定义不同协作空间的成员治理规则,而不是做三个外观不同的聊天盒子。


这篇主要看哪里

核心源码在:

  • addons/mail/models/discuss/discuss_channel.py
  • addons/mail/models/discuss/res_partner.py

重点可以看:

  • channel_type
  • _constraint_partners_chat()
  • _constraint_group_id_channel()
  • _compute_group_public_id()
  • _compute_is_member()
  • search_for_channel_invite()
  • _search_for_channel_invite()
  • get_mention_suggestions_from_channel()

第一层:三种频道类型不是名字差异,而是权限模型差异

源码里 channel_type 有三种:

  • chat
  • group
  • channel

字段 help 写得很清楚:

  • Chat:私密且唯一地存在于两个人之间;
  • Group:受邀成员之间的私密空间;
  • Channel:可自由加入,但仍取决于配置。

这几句话其实已经透露了 Odoo 的基本治理思想:

chat

重点是一对一唯一性,不追求扩张。

group

重点是受邀制私密协作

channel

重点是可管理的公开协作面

所以你看到的不是聊天形态分类,而是协作开放程度分层。


第二层:为什么 chat 被硬限制为最多两人

_constraint_partners_chat() 直接限制:

  • channel_type == 'chat' 时,成员不能超过两人。

这不是 UI 约束,而是数据层约束。

这意味着 Odoo 不允许“本来是私聊,后来慢慢拉成小群”这种语义漂移。

为什么这很重要?

因为如果允许 chat 任意加人:

  • 历史权限语义会变脏;
  • 私聊期待会被破坏;
  • 前端很多关于直聊的假设会失效;
  • 后续邀请、显示名、成员可见性都难以解释。

Odoo 选择在模型层把这件事卡死,实际上是在保护协作预期。


第三层:为什么只有 channel 能做公开组授权和自动订阅

源码里有两个非常关键的限制:

  • group_public_id
  • group_ids

并且 _constraint_group_id_channel() 明确要求:

  • 只有 channel_type == 'channel' 才能使用基于用户组的授权或自动订阅。

也就是说:

  • group 虽然也是多人空间,但它不是面向公开加入治理的;
  • 真正承接“面向某个组织范围开放”的,是 channel

这非常合理。

因为一旦你允许 group 也同时拥有公开授权和自动订阅,它就会在“私密受邀空间”和“受治理开放空间”之间语义混乱。

Odoo 明确把两者切开了。


第四层:父子频道不是任意嵌套,且类型要一致

_constraint_parent_channel_id() 里有几个很强的约束:

  • 父频道不能本身还是子频道;
  • 父频道类型只能是 channelgroup
  • 子频道必须和父频道同类型。

这说明 Odoo 不希望频道树无限乱长。

它更像是在支持有限层级的协作分区,而不是要做一个复杂社区论坛。

更关键的是“类型必须一致”这条。

因为如果你允许:

  • 公开 channel 下面挂私密 group;
  • 或 group 下面再挂另一套完全不同公开语义的 channel;

成员边界、授权继承、邀请能力都会变得很难解释。

所以 Odoo 直接在模型层面把这种复杂度砍掉了。


第五层:邀请候选并不是想搜谁就能加谁

search_for_channel_invite()_search_for_channel_invite() 也很值得看。

源码会在邀请候选阶段就限制:

  • 不能邀请自己;
  • 对方必须是活跃内部用户;
  • 如果当前频道有 group_public_id,候选人还必须属于该授权组;
  • 已经在频道里的成员不会重复出现。

这说明 Odoo 的邀请搜索不是“全局搜人”,而是“在当前频道治理边界内搜可合法加入的人”。

这跟很多聊天产品的“先搜到再说”不同。

Odoo 把可邀请性提前到候选计算阶段,减少了后置报错和权限歧义。


第六层:必要时还允许按邮箱邀请,但也有限制

如果搜索不到匹配伙伴,且输入看起来像邮箱,源码会进一步判断:

  • 当前频道是否允许通过邮箱邀请;
  • 这个邮箱对应的人是否已经在频道成员里;
  • 是否曾经向这个邮箱发过邀请邮件。

这说明 Odoo 在“开放协作”上也不是一刀切:

  • 它允许把组织外的人拉进来;
  • 但不是无条件开放;
  • 仍然要求频道本身声明“我支持这种邀请方式”。

这正是一个企业协同产品应有的克制。


第七层:提及建议也会继承频道边界

get_mention_suggestions_from_channel() 里,提及候选不仅看搜索词,还会限制在:

  • 当前频道或父频道范围内的成员;
  • 如果有授权组,还得满足 allowed_group

这意味着 Odoo 的设计很一致:

  • 你不能把一个本来无权进入该协作空间的人,仅仅通过“@一下”拉进来;
  • mention 也要服从频道成员和授权边界。

这点非常关键。

否则频道治理会被编辑器提及功能偷偷绕开。


一句话记住

Odoo Discuss 里的 chat、group、channel,不是三种视觉组件,而是三套协作治理规则:

chat 保护一对一直聊,group 保护受邀私密协作,channel 承接受治理的开放协作。

理解这层以后,你再看成员约束、邀请建议、公开授权、父子频道和 mention 边界,就会发现它们其实都在服务同一件事:

让协作空间既能扩展,又不失控。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。