ia_dev/gitea-issues/TICKETS_SPOOL_FORMAT.md

6.0 KiB
Raw Blame History

Format JSON du spooler tickets (projects//data/issues/)

Les mails et réponses sont stockés dans projects//data/issues/ (sous ia_dev, par projet). Filtrage par expéditeurs autorisés (conf.json → tickets.authorized_emails), sans sappuyer sur le statut « non lu ». Le traitement se base uniquement sur le statut des issues ; aucun enregistrement nest supprimé.

Emplacement et nommage des fichiers

  • Racine : ia_dev/projects/<id>/data/issues/ (id = slug projet, ex. contenu de ai_project_id ou .ia_project à la racine du dépôt)
  • Messages entrants : <date>_<from_sanitized>_<uid>.<status> (le _<uid> assure lunicité par message IMAP)
    • date : YYYY-MM-DDTHHmmss (ex. 2026-03-14T094530)
    • from_sanitized : adresse expéditeur rendue sûre pour le système de fichiers (ex. user_example.com pour user@example.com : @_, caractères interdits remplacés ou supprimés)
    • uid : UID IMAP (évite les doublons pour un même expéditeur à la même seconde)
    • status : pending | inprogress | done
  • Réponses envoyées : <date>_<from_sanitized>.response (même base de nom que le message entrant associé, extension .response)
  • Pièces jointes (pj) : pour un message entrant de base <base> (ex. 2026-03-14T094530_laurence_lecoffre.io_42), les pièces jointes sont dans le répertoire <base>.d/ (ex. 2026-03-14T094530_laurence_lecoffre.io_42.d/). Nommage des fichiers : <index>_<nom_fichier_sanitifé> (ex. 0_document.pdf, 1_capture.png). Le JSON du message contient le tableau attachments avec pour chaque entrée le chemin relatif à data/issues/, le type MIME et la taille pour que lagent qui traite les tickets puisse les utiliser.

Exemples :

  • 2026-03-14T094530_laurence_lecoffre.io.pending — message entrant en attente
  • 2026-03-14T094530_laurence_lecoffre.io.inprogress — en cours de traitement
  • 2026-03-14T094530_laurence_lecoffre.io.done — traité
  • 2026-03-14T101200_laurence_lecoffre.io.response — réponse envoyée

Schéma JSON — message entrant (incoming)

Fichiers .pending, .inprogress, .done.

{
  "version": 1,
  "type": "incoming",
  "message_id": "<original.Message-ID@host>",
  "from": "laurence@lecoffre.io",
  "to": ["ai.support.lecoffreio@4nkweb.com"],
  "subject": "Demande d'information",
  "date": "Fri, 14 Mar 2026 09:45:30 +0100",
  "body": "Texte brut du corps du mail.",
  "references": ["<id1@host>", "<id2@host>"],
  "in_reply_to": "<id2@host>",
  "uid": "42",
  "created_at": "2026-03-14T09:45:35Z",
  "issue_number": null,
  "status": "pending",
  "attachments": [
    {
      "filename": "document.pdf",
      "path": "2026-03-14T094530_laurence_lecoffre.io_42.d/0_document.pdf",
      "content_type": "application/pdf",
      "size": 12345
    },
    {
      "filename": "capture.png",
      "path": "2026-03-14T094530_laurence_lecoffre.io_42.d/1_capture.png",
      "content_type": "image/png",
      "size": 6789
    }
  ]
}
Champ Type Description
version number Version du schéma (1)
type string "incoming"
message_id string En-tête Message-ID du mail
from string Adresse de lexpéditeur
to string[] Adresses destinataires
subject string Sujet
date string Date denvoi (RFC2822 ou ISO8601)
body string Corps du message (texte brut)
references string[] En-tête References (liste de Message-IDs)
in_reply_to string | null En-tête In-Reply-To
uid string UID IMAP (pour référence, pas pour marquer lu)
created_at string Date décriture dans le spool (ISO8601)
issue_number number | null Numéro dissue Gitea si une issue a été créée
status string pending | inprogress | done
attachments array Pièces jointes : tableau dobjets (voir ci-dessous). path est relatif à data/issues/ ; les fichiers sont dans <base>.d/. Lagent qui traite les tickets peut les lire depuis projects/<id>/data/issues/<path>.

Objet pièce jointe : filename (nom dorigine), path (chemin relatif sous projects/<id>/data/issues/), content_type (MIME), size (octets).

Schéma JSON — réponse envoyée (response)

Fichiers .response.

{
  "version": 1,
  "type": "response",
  "in_reply_to_message_id": "<original.Message-ID@host>",
  "to": "laurence@lecoffre.io",
  "subject": "Re: Demande d'information",
  "body": "Texte de la réponse envoyée par l'agent.",
  "sent_at": "2026-03-14T10:12:00Z",
  "created_at": "2026-03-14T10:12:00Z"
}
Champ Type Description
version number Version du schéma (1)
type string "response"
in_reply_to_message_id string Message-ID du mail auquel on répond
to string Destinataire de la réponse
subject string Sujet de la réponse (ex. Re: …)
body string Corps de la réponse envoyée
sent_at string Date denvoi (ISO8601)
created_at string Date de création du fichier (ISO8601)

Configuration projet (conf.json)

  • ticketing_url et la config ticketing sont sous la clé tickets (et non plus sous git).
  • tickets contient :
    • ticketing_url : URL des issues Gitea
    • authorized_emails :
      • to : récupérer uniquement les mails envoyés à cette adresse (destinataire).
      • from : récupérer uniquement les mails envoyés par ces adresses (expéditeurs autorisés).

Exemple :

"tickets": {
  "ticketing_url": "https://git.4nkweb.com/4nk/lecoffre_ng/issues",
  "authorized_emails": {
    "to": "ai.support.lecoffreio@4nkweb.com",
    "from": ["ai.support.lecoffreio@4nkweb.com", "laurence@lecoffre.io"]
  }
}

La récupération ne prend que les messages envoyés à authorized_emails.to et expédités par une des adresses de authorized_emails.from. Aucun marquage « lu / non lu » ; aucun enregistrement du spool nest supprimé.