问题亡灵复生:从 Mattermost 迁移

问题

我想了解一下从 Mattermost 团队版实例迁移到 Discourse 实例(我同时管理这两个实例)的当前最佳建议。

我已经阅读了有关如何协调迁移的建议,因此现在我正在寻找有关数据迁移的技术资源和建议。

背景

现在是 2025 年 10 月,我发现自己处于一个类似于 2018 年这个问题的境地[1]

然而,我面临的压力更加明确——Mattermost 实际上正在关闭其团队版[2](技术上并没有,但我认为这些更改违反了他们的开源承诺)。

最初的讨论始于建议合并这两个平台,然后以 Discourse 现在拥有相当不错的聊天功能(确实如此,尤其是即将推出的聊天搜索)的声明结束。然而,它没有包含任何关于迁移的建议。


  1. 讨论以 Discourse 团队成员表示 Discourse 使用 Mattermost 的说法结束 ↩︎

  2. 讽刺的是,公告是使用 Discourse 发布 ↩︎

5 个赞

你好 Anton!

将 Mattermost 迁移到 Discourse 是完全可行的,但这需要构建一个自定义的导入脚本,因为目前还没有现成的脚本(在此处查看可用的导入脚本)。你可以参考现有的脚本进行学习,但请务必仔细检查它们的最后更新日期并进行相应调整,因为有些脚本可能包含过时的 Discourse 表格引用。

社区非常欢迎提供 Mattermost 导入脚本的拉取请求!

频道和数据映射

你可以将所有内容导入为聊天频道,但也可以将它们映射为其他类型:

  • 频道作为分类: 将每个 Mattermost 频道导入为 Discourse 分类。频道内的帖子可以成为主题,每个消息成为一个回复。或者,单个帖子也可以成为主题的 OP。
  • 频道作为主题: 另一种方法是将每个 Mattermost 频道作为一个主题,消息作为回复,在这种情况下,帖子将按顺序显示。
  • 私信: 它们也可以被导入为私信。这对于需要归档的讨论是个好主意。

仔细考虑哪种方法最适合你的社区和内容量。

主题标题

将聊天映射到主题和帖子时,你需要为每个主题创建标题。一个很棒的方法是使用 Discourse AI 来生成具有实际主题上下文的标题。

使用 AI 生成主题标题

简而言之,使用此方法:

def gen_title(llm, system_prompt, topic)
  begin
  content = topic.posts.map(&:cooked).join("\n").slice(0..10_000)
  message = [{type: :user, content: content}]
  prompt = DiscourseAi::Completions::Prompt.new(system_prompt, messages: message)

  title = llm.generate(
      prompt,
      user: Discourse.system_user,
      temperature: 0.3,
      feature_name: "ai_helper"
  )

  topic.title = title
  topic.save!
  puts "Topic: #{topic.id}, changed sucessfully."
  rescue ActiveRecord::RecordInvalid
    puts "validation error"
  end
end

这需要一个 LLM 和一个主提示

llm = DiscourseAi::Completions::Llm.proxy(SiteSetting.ai_helper_model)

system_prompt = <<-PROMPT
  I want you to act as a title generator for written pieces. I will provide you with a text,
  and you will generate a title. Please keep the title concise and under 20 words,
  and ensure that the meaning is maintained. The title will utilize the language type of the topic.
  I want you to only reply the proposed title and nothing else, do not write explanations.
  Never ever use colons in the title. Always use sentence case, using a capital letter at
  the start of the title, never start the title with a lower case letter. Proper nouns in the title
  can have a capital letter, and acronyms like LLM can use capital letters. Format some titles
  as questions, some as statements. Make sure to use question marks if the title is a question.
PROMPT

然后你可以根据需要循环遍历主题列表:

# gen everything
Topic
  .joins(:_custom_fields)
  .where('topic_custom_fields.name = ?', 'import_id')
  .find_each { |topic| gen_title(llm, system_prompt, topic) }

# filter PMs
Topic
  .joins(:_custom_fields)
  .where('topic_custom_fields.name = ?', 'import_id')
  .where.not(archetype: "private_message")
  .find_each { |topic| gen_title(llm, system_prompt, topic) }

重要注意事项

  • 反应: Mattermost 支持每条帖子有多个反应。如果导入为 Discourse 帖子,你需要限制为一条,除非你将其映射到 Discourse Chat(它原生支持多个反应)。
  • 自定义表情符号: 你可以迁移自定义表情符号,请参阅 Discourse Reactions 插件文档
  • 团队和权限: Mattermost 的“团队”不直接映射到 Discourse,但你可以设置具有适当基于组的访问控制的分类/频道。
  • 附件: Mattermost 的附件(图片和文档)不像 Discourse 那样嵌入在内容中。导入时,你需要附加附件链接(Markdown)或将它们嵌入到帖子正文中。

参考资料


我们有聊天平台迁移的经验,如果你想获得我们团队的帮助,请参阅我们的 Discourse 迁移服务页面

如果在脚本开发或映射决策过程中有任何具体问题,请随时在 Meta 上提问以获得指导!

5 个赞

非常感谢您提供的这个非常好的摘要!我将在迁移时进行研究。如果我最终编写了脚本,我一定会与社区分享。

目前我倾向于将聊天导入聊天频道。除了缺乏搜索功能(该功能将很快实现)之外,还有其他相关考虑因素吗?

2 个赞

在这种情况下,大部分工作将花在解析消息上。一些相关事项是:

4 个赞