Remontée des publications vers Trustt

Faire remonter les liens de contenu publiés (collectés par Trustt SMS via le brief ou ajoutés à la main) vers Trustt, sur le modèle de la réception colis · mise à jour 19/06/2026.

Le retrait colis remonte maintenant automatiquement à Trustt via save_receipt (livré, en prod). On veut faire pareil pour les publications : aujourd'hui l'opérateur reçoit le lien et le recopie à la main dans Trustt. Cette page fait l'inventaire de ce qu'on a, du manque exact côté Trustt, et propose un contrat d'endpoint calé sur le style réel de votre API. Code couleur : livré   à créer   bloquant.

Sommaire

1 État actuel

La réception colis est résolue. La publication reste manuelle.

SignalSensÉtat
Réception / retrait colisTrustt SMS → Trusttlivré via save_receipt (push à la déclaration + réconciliation deux sens)
Posts publiés (lecture)Trustt → Trustt SMSlecture via realizedUgc sur ambassadors (sert à ne relancer que les silencieux)
Posts publiés (écriture)Trustt SMS → Trusttmanuel l'opérateur copie le lien reçu et le colle dans Trustt à la main

Objectif : quand un ambassadeur envoie son lien (via le brief Trustt SMS) ou qu'un opérateur l'ajoute à la main, le pousser à Trustt automatiquement, exactement comme le colis.

2 Ce qu'on a côté Trustt SMS

Tout est prêt côté données et plomberie : c'est une copie du dispositif réception.

BriqueDétail
Donnée publicationPar soumission : postUrl, platform (instagram / tiktok / youtube), status (pending / validated / rejected), submittedAt, source (brief ou ajout manuel).
Lien ambassadeurcandidateUUID (le cid Trustt) connu par jonction, déjà rapproché par téléphone à la synchro.
Lecture des posts TrusttSnapshot par jonction depuis realizedUgc (publié oui/non, nombre, avis).
Infra de remontéeRéutilisable telle quelle : client d'écriture, file BullMQ avec retries, sous-doc d'état + machine de statuts, classifieur d'écart, réconciliation greffée sur la synchro quotidienne + bouton manuel.

3 Ce que Trustt expose aujourd'hui

5 endpoints : 4 en lecture, 1 seul en écriture (save_receipt). Les posts sont en lecture seule, et sans l'URL.

realizedUgc.posts[] (sur l'endpoint ambassadors, LECTURE) :
{
  "socialTypeId": 2,
  "postTypeId": 4,
  "postTypeLabel": "Story Instagram",
  "status": "pending",
  "dateCrea": "2026-04-30 21:05:24"
}
// pas d'URL du post

Constat : il n'existe aucun endpoint pour déclarer une publication (équivalent de save_receipt côté post), et les posts lus ne portent pas l'URL.

Relevé exhaustif (crawl live 19/06/2026) : tout le compte

Vérifié en appelant l'API en prod sur l'ensemble du compte (pas seulement nos campagnes liées) : 54 entreprises, 98 marques, 334 campagnes, 9594 ambassadeurs, 4141 posts réels. C'est une certitude empirique, plus une lecture de la doc.

DonnéeRéalité observée (4141 posts)
Champs d'un postsocialTypeId, postTypeId, postTypeLabel, status, dateCrea — rien d'autre, jamais
URL / lien / id du postJAMAIS présent (0 sur 4141) : Trustt ne stocke pas le lien
statusvalid (4009) + pending (132). Aucun rejeté.
Types observésVidéo TikTok 2284 · Post Instagram 1415 · Story Instagram 366 · Post Facebook 55 · Vidéo Youtube 14 · Article 5 · Post Pinterest 2
review (avis)rempli 4122 fois, forme { dateCrea, isVideo } — pas de contenu, pas d'URL
merchantReview491 entrées, forme { dateCrea }
testForms4428 entrées, forme { formId, name, dateCrea }
receiptStatus0 (1674), 1 (7916), 2 (4 — valeur non documentée, confirmée)

Trustt auto-détecte déjà les posts. Sur tout le compte, des milliers de posts sont valid sans qu'on ait rien poussé. Trustt a donc son propre pipeline de détection. Le modèle d'un post est par type, pas par lien : aucune URL nulle part, sur 4141 posts.

3b Le contenu suivi : 4 briques (attendu vs réalisé)

Relevé du compte entier (335 campagnes pour l'attendu, 9594 ambassadeurs / 4141 posts pour le réalisé). « Publication » au sens large = 4 briques, pas seulement le post.

BriqueAttendu (campagne)Réalisé (ambassadeur)Possibilités
Post socialexpectedUgc.expectedPost[]realizedUgc.posts[]type + plateforme + quantité
Avis produitexpectedUgc.reviewrealizedUgc.reviewexpected, hasVideo, hasTestingPhotos
Avis marchandexpectedUgc.merchantReviewrealizedUgc.merchantReview[]merchantName, merchantUrl
Formulaire de testexpectedUgc.testForms[]realizedUgc.testForms[]name, nbDaysStart (J+N)

Volumes attendus vs réalisés

LivrableAttendu (sur 335 campagnes)Réalisé
Post social90 (245 n'en demandent aucun)4141 posts
Avis produit173 (+photos 37, +vidéo 2)4122
Avis marchand46 (Farmaline, Peggy Sage, Labo ACM, Cocooncenter, Trustpilot…)491
Formulaire de test136 (J+7/14/21/28…)4428

Types de post : attendu étroit, réalisé large

TypeAttendu (campagnes)Réalisé (posts)
Post Instagram541415
Vidéo TikTok49 (+1 en qty 2)2284
Story Instagramjamais366
Post Facebookjamais55
Vidéo Youtubejamais14
Articlejamais5
Post Pinterestjamais2

Conséquence remontée : l'attendu formel ne décrit que 2 types (Post Instagram, Vidéo TikTok). Les ambassadeurs publient pourtant Story, Facebook, Youtube, Article, Pinterest. Une remontée pilotée seulement par expectedPost raterait tout ce contenu hors IG/TikTok réellement publié.

Combinaisons de contenu attendu (par campagne)

CampagnesContenu attendu
62rien d'attendu formellement
53Avis + 1 formulaire
36Post TikTok
35Avis seul
28Post Instagram
23Avis + Avis marchand + formulaire
15Avis + Avis marchand
10Post Instagram + Post TikTok
queuejusqu'à Post + Avis(+photos) + Avis marchand + formulaire (profil complet)

4 Les deux manques (pas un seul)

#ManqueConséquence si absent
1Endpoint d'écriture de publication (save_post).bloquant on ne peut rien pousser. Même situation que la réception avant save_receipt.
2L'URL traitée comme la clé d'un post chez Trustt (au stockage ET en lecture).bloquant réconciliation sans URL, on ne sait jamais si « notre » post est déjà chez Trustt → on risque de le pousser en double à chaque synchro.

Le risque central, confirmé par le relevé live : Trustt auto-détecte déjà les posts et les compte par type, sans URL. Si on pousse une URL pour un post que Trustt a déjà détecté, il ne peut pas dédupliquer (il ne connaît pas les liens) → il comptera deux posts du même type. Donc tant que l'URL n'est pas la clé d'un post côté Trustt, pousser nos publications est dangereux, pas juste impossible à réconcilier. C'est le vrai prérequis, avant même save_post.

Sous-problème : le type de post

On a une URL et une plateforme grossière (instagram). Trustt range par postTypeId fin (Post Instagram = 3 vs Story Instagram = 4, Post Facebook = 5, Vidéo Youtube = 7, Vidéo TikTok = 9). On ne sait pas distinguer un post d'une story Instagram depuis l'URL.

Donc save_post doit accepter l'URL et inférer le type côté Trustt, ou se contenter d'un socialTypeId (plateforme) quand on ne peut pas fournir mieux.

5 Endpoint proposé : save_post à créer

Calé sur le style réel de votre API (un endpoint par signal, comme save_receipt), pas sur un puits d'évènements générique.

POST https://pro.trustt.io/api_trusttsms/save_post
  ?key=xxx
  &cid=<candidateUUID>
  &url=<url du post, encodee>
  &platform=instagram|tiktok|youtube
  &date=2026-06-05%2012:10:00          (Y-m-d H:i:s)
  [&postTypeId=<int>]                 optionnel
ParamètreFormatObligatoireDescription
keystringouiClé API Trustt SMS
cidUUIDouiAmbassadeur (candidateUUID)
urlstringouiLien du post publié
platformenumouiinstagram / tiktok / youtube (Trustt infère le postTypeId)
datestring (Y-m-d H:i:s)ouiDate de soumission du post
postTypeIdintnonType précis si un jour on peut le fournir

Réponse idéale (pour pouvoir réconcilier)

{
  "data": {
    "uuid_candidate": "679c7491-...",
    "postId": "...",            // id du post cree cote Trustt
    "url": "https://...",       // l'URL, pour le rapprochement
    "postTypeId": 9,            // type resolu cote Trustt
    "status": "pending"         // probablement a valider cote Trustt
  }
}

Dédup idempotente sur (cid, url) : rejouer le même save_post (re-push, réconciliation) ne crée pas de doublon. C'est ce qui permet de pousser sans risque.

À terme : un delete_post (symétrique du futur cancel_receipt) pour un post rejeté ou retiré localement. Hors périmètre de la première phase.

6 Questions de politique à trancher

#QuestionNotre recommandation
1Quels posts veux-tu recevoir : seulement nos validés, ou tout (y compris en attente / rejetés) ?Validés seulement, pour ne pas t'envoyer de liens douteux.
2Un post poussé arrive-t-il en pending chez vous (revalidation Trustt) ou est-il pris tel quel ?Au choix, mais il faut le savoir pour l'afficher honnêtement côté SMS.
3Peux-tu exposer l'URL dans realizedUgc.posts ?Indispensable, sinon pas de réconciliation possible (cf. manque 2).

7 Architecture côté Trustt SMS (dès que l'endpoint arrive)

Copie du dispositif réception, en deux phases.

PhaseContenu
Phase 1Sous-doc d'état de remontée par soumission (pending / pushed / already_in_trustt / failed), client savePost, file trustt-post-push, push à la validation d'un post + réconciliation greffée sur la synchro quotidienne et le bouton « Mettre à jour depuis Trustt », notifications internes en cas d'échec.
Phase 2Dédup / adoption dans les deux sens dès que Trustt renvoie les URLs (manque 2 résolu).

Verdict (revu après relevé live) : bloqué côté Trustt, et le blocage est plus profond qu'un endpoint manquant. Le modèle de post de Trustt est par type, sans URL, et Trustt auto-détecte déjà les posts. Prérequis, dans l'ordre : (1) Trustt traite l'URL comme la clé d'un post (stockage + lecture) pour pouvoir dédupliquer notre push contre sa propre détection ; (2) alors seulement save_post a un sens. Sans (1), pousser nos publications crée des doublons. Côté Trustt SMS, tout est prêt.