导入的私有讨论未在作者收件箱中显示

你好,我尝试从 vBulletin5 数据库导入私信。

导入成功了,但在作者的个人资料中,该讨论仅出现在“已发送”中,而不会出现在“收件箱”中。

而在其他参与者的个人资料中,该讨论正确地同时出现在“收件箱”和“已发送”中。

作者个人资料:
出现在“已发送”中

但未出现在“收件箱”中

其他参与者个人资料:
同时出现在两者中:

我该如何让该讨论出现在作者的收件箱中?

如果需要,以下是我目前较为混乱的代码:

  def import_pm
    puts "", "正在导入私信主题..."

    pms_count = mysql_query("SELECT COUNT(nodeid) cnt, starter
        FROM #{DB_PREFIX}node
        WHERE (unpublishdate = 0 OR unpublishdate IS NULL)
        AND (approved = 1 AND showapproved = 1)    
          AND starter = 2676436
        AND contenttypeid=#{@pm};"
    ).first["cnt"]

    batches(BATCH_SIZE) do |offset|
      pms = mysql_query <<-SQL
        SELECT pm.nodeid AS pmid, pm.starter, pm.title, pm.parentid AS parentid,pm.open,pm.userid AS postuserid,pm.publishdate AS dateline,
            nv.count views, 1 AS visible, pm.sticky,
            CONVERT(CAST(rawtext AS BINARY)USING utf8) AS raw
        FROM #{DB_PREFIX}node pm
        LEFT JOIN #{DB_PREFIX}nodeview nv ON nv.nodeid=pm.nodeid
        LEFT JOIN #{DB_PREFIX}text txt ON txt.nodeid=pm.nodeid
        WHERE
          pm.contenttypeid = #{@pm}
          AND (pm.unpublishdate = 0 OR pm.unpublishdate IS NULL)
          AND pm.approved = 1 AND pm.showapproved = 1
          AND pm.starter = 2676436
        ORDER BY pm.nodeid
          LIMIT #{BATCH_SIZE}
          OFFSET #{offset}
      SQL

      break if pms.size < 1

      create_posts(pms, total: pms_count, offset: 0) do |pm|
        p = {}

        p[:id] = "pm-#{pm['pmid']}"
        p[:user_id] = user_id_from_imported_user_id(pm['postuserid']) || Discourse::SYSTEM_USER_ID
        p[:raw] = preprocess_post_raw(pm['raw']) rescue nil
        p[:created_at] = parse_timestamp(pm["dateline"]),

        topic_id = nil

        next if p[:raw].blank?

        # 如果是首帖
        if pm['parentid'] == 8 
          #next unless post = topic_lookup_from_imported_post_id("pm-#{pm["pmid"]}")

          target_usernames = []
          target_userids = []
          # 获取用户列表
          userlist = mysql_query("select distinct userid from sentto where nodeid = #{pm["starter"]}")
          userlist.each do |user|
            userid = user_id_from_imported_user_id(user["userid"]) || Discourse::SYSTEM_USER_ID;
            target_userids << userid || Discourse::SYSTEM_USER_ID
            target_usernames << User.find_by(id: userid).try(:username) || "system"
          end

          participants = target_userids
          begin
            participants.sort!
          rescue
            puts "其中一个参与者的 ID 为 nil -- #{participants.inspect}"
          end

          p[:title] = @htmlentities.decode(pm['title']).strip[0...255]
          p[:archetype] = Archetype.private_message
          p[:target_usernames] = target_usernames.join(',')

          if p[:target_usernames].size < 1 # 是否是自己给自己发私信?
            # skip = true
            p[:target_usernames] = "system"
            puts "pm-#{pm['nodeid']} 没有目标用户"
          end
        # 如果不是首帖
        else
          next unless topic = topic_lookup_from_imported_post_id("pm-#{pm["starter"]}")
          p[:topic_id] = topic[:topic_id]

        end
        puts "帖子:#{p}\n"
        p
      end
    end
    exit
  end

从数据浏览器中,我注意到 participant_count 的值有误:
image

显示为 1,但对话中实际上有两个人。
如果我将主题的 participant_count 字段更新为 2,如下所示:

Topic.find_by(id: 218613).update(participant_count: 2)

该主题现在会出现在作者的收件箱中:

我在更新其他字段(例如 reply_count)时并未观察到这种行为,因此这似乎是 participant_count 特有的问题,可能还涉及其他字段。

在我的导入脚本中,我尝试添加以下内容:

p[:participant_count] = target_usernames.count

但这没有生效,我想我们无法在导入器的方法中设置此字段。

所以我现在有点束手无策。我希望我的用户能在收件箱中看到所有包含回复的私信,而不仅仅是那些他们自己发起的私信。

有什么建议吗?

对此有什么想法吗,@kris.kotlarek

感谢你提到这个 bug。我自己也检查了一下,你说得对——当 participant_count 不正确时,消息在消息作者的收件箱中是不可见的。

另外,你说得对,即使你显式地将该参数添加到 create_posts 中,它也不会被正确设置。

这是因为 TopicCreate 有一个明确允许的参数字段列表:

今天我将会向 Discourse 提交一个 PR,以便在导入模式下接受该属性。

在此期间,为了不等待 Discourse 的最新版本,你可以在脚本的最后运行:

Topic.private_messages.map(&:update_statistics) —— 这应该可以修正所有数字。

PR 已就绪 - FIX: topic_creator accepts participant_count in import mode by KrisKotlarek · Pull Request #10632 · discourse/discourse · GitHub

合并并部署后,您可以这样使用:

create_posts(pms, total: pms_count, offset: 0) do |pm|
...
  p[:topic_opts][:participant_count] = target_usernames.count 
...
end

它必须位于 [:topic_opts] 下,因为 create_posts 方法会评估 post_creator,从而触发 topic_creator