Discussion privée importée n'apparaît pas dans la boîte de réception de l'auteur

Bonjour, j’essaie d’importer des messages privés depuis une base de données vBulletin5.

Cela fonctionne, mais dans le profil de l’auteur, la discussion n’apparaît que dans « envoyés », et non dans « boîte de réception ».

En revanche, dans le profil de l’autre participant, la discussion apparaît correctement à la fois dans « boîte de réception » et dans « envoyés ».

Profil de l’auteur :
Apparaît dans « envoyés »

Mais pas dans « boîte de réception »

Profil de l’autre participant :
Apparaît dans les deux :

Comment puis-je faire en sorte que la discussion apparaisse dans la boîte de réception de l’auteur ?

Voici mon code actuel, assez désordonné, si nécessaire :

  def import_pm
    puts "", "importation des sujets de MP..."

    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?

        # s'il s'agit du premier message
        if pm['parentid'] == 8 
          #next unless post = topic_lookup_from_imported_post_id("pm-#{pm["pmid"]}")

          target_usernames = []
          target_userids = []
          # obtenir la liste des utilisateurs
          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 "l'un des identifiants de participant est 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 # MP avec soi-même ?
            # skip = true
            p[:target_usernames] = "system"
            puts "pm-#{pm['nodeid']} n'a pas de destinataire"
          end
        # s'il ne s'agit pas du premier message
        else
          next unless topic = topic_lookup_from_imported_post_id("pm-#{pm["starter"]}")
          p[:topic_id] = topic[:topic_id]

        end
        puts "post : #{p}\n"
        p
      end
    end
    exit
  end

Depuis l’explorateur de données, j’ai remarqué que la valeur de participant_count est incorrecte :
image

Il est indiqué 1, mais il y a deux personnes dans la conversation.
Si je mets à jour le champ participant_count du sujet à 2 comme ceci :

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

le sujet apparaît désormais dans la boîte de réception de l’auteur :

Je n’ai pas remarqué ce comportement en mettant à jour d’autres champs comme reply_count, par exemple, il semble donc spécifique à participant_count et peut-être à d’autres champs.

Dans mon script d’importation, j’ai essayé d’ajouter ceci :

p[:participant_count] = target_usernames.count

Mais cela n’a pas fonctionné. Je suppose qu’on ne peut pas définir ce champ dans les méthodes des importateurs.

Je suis donc un peu bloqué ici. J’aimerais que tous mes utilisateurs aient leurs MP avec des réponses dans leur boîte de réception, et pas seulement ceux qu’ils n’ont pas initiés eux-mêmes.

Une idée ?

Qu’en pensez-vous, @kris.kotlarek ?

Merci d’avoir signalé ce bug. Je l’ai vérifié moi-même et vous avez raison : lorsque participant_count est incorrect, le message n’est pas visible dans la boîte de réception de l’auteur du message.

Vous avez également raison de dire que même si vous ajoutez explicitement ce paramètre à create_posts, il n’est pas défini correctement.

Cela est dû au fait que TopicCreate possède une liste explicite des paramètres autorisés :

Aujourd’hui, je vais créer une PR pour Discourse afin d’accepter cet attribut en mode import.

En attendant, pour ne pas avoir à attendre la dernière version de Discourse, vous pouvez exécuter à la toute fin de votre script :

Topic.private_messages.map(&:update_statistics) - cela devrait corriger tous les chiffres.

La PR est prête - FIX: topic_creator accepts participant_count in import mode by KrisKotlarek · Pull Request #10632 · discourse/discourse · GitHub

Une fois fusionnée et déployée, vous pourrez l’utiliser comme suit :

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

Cela doit être placé sous [:topic_opts] car la méthode create_posts évalue post_creator, ce qui déclenche topic_creator.