Guide 07 - Lecture directe via l'API Tencent Docs OpenAPI (Voie A, polling)
✅ Chemin principal retenu le 2026-07-13 après abandon de HiFlow (bloqué par « get appid error ») et constat que le document est un tableur classique
/sheet/- donc l'API WeCom Smart Sheet (guide 02) est inutilisable. Voir ADR 0001.
n8n lit périodiquement le tableur Tencent Docs via l'OpenAPI officielle, compare à PostgreSQL, et n'agit que sur les nouvelles lignes avec tracking_number. L'anti-doublon UNIQUE (numero_commande, tracking_number) (ADR 0004) rend le polling idempotent.
Vue d'ensemble
[1 fois] App développeur + OAuth (scan QR) ─────────► refresh_token (valable 1 an)
[boucle] Schedule n8n ─► refresh access_token (30j) ─► GET plage de cellules ─► delta ─► email
1. Créer l'application développeur (bloquant, côté toi)
- Aller sur https://docs.qq.com/open/developers/ et s'inscrire comme développeur.
- Créer une application tierce. Renseigner un
redirect_uri(URL de callback ; ex. une page n8n ou une URL statique que tu contrôles). - Soumettre à l'approbation (审核). ⚠️ Selon les scopes demandés, une authentification entreprise (企业认证) peut être exigée - le doc est en « Enterprise Edition », donc c'est probable. L'approbation peut prendre quelques jours.
- Une fois approuvée : récupérer
Client IDetClient Secret. - Scope requis : lecture de tableur -
scope.sheet.readonly(lecture seule suffit ici).
2. Autorisation OAuth (à faire UNE fois, manuellement)
- Ouvrir l'URL d'autorisation dans un navigateur (connecté au compte Tencent qui a accès au doc) :
https://docs.qq.com/oauth/v2/authorize?client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&response_type=code&scope=scope.sheet.readonly&state=xyz - Scanner le QR / accepter. Tencent redirige vers
REDIRECT_URI?code=XXXX- lecodeest valable 5 min. - Échanger le code contre les tokens (depuis un backend, pas le navigateur) :
Réponse (à vérifier sur une vraie réponse) :POST https://docs.qq.com/oauth/v2/token Content-Type: application/x-www-form-urlencoded client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=XXXX&redirect_uri=REDIRECT_URIaccess_token(30 j),refresh_token(1 an),user_id(= Open-Id),expires_in. - Conserver précieusement le
refresh_tokenet leuser_id(Open-Id) → variables d'env n8n (§5).
3. Rafraîchir l'access_token (automatique, dans n8n)
POST https://docs.qq.com/oauth/v2/token
client_id=…&client_secret=…&grant_type=refresh_token&refresh_token=…
- Fait par le node « Rafraîchir le token » à chaque cycle (l'access_token dure 30 j mais on le régénère à chaque run, c'est le plus simple et sans état).
- ⚠️ Si Tencent renvoie un nouveau
refresh_tokenà chaque rafraîchissement (rotation), il faut persister la nouvelle valeur (sinon expiration au bout de la durée du premier). Option : une tableoauth_tokenen base, ou une écriture de variable. À valider au 1er test.
4. Lire le contenu du tableur (dans n8n)
a) Obtenir le sheetId de chaque onglet (une fois)
Le tableur a plusieurs onglets (« Commandes pour 2026 », « Retours 2026 »…). Chaque onglet a un sheetId distinct. Les lister via l'API « query sheets » :
GET https://docs.qq.com/openapi/spreadsheet/v3/files/{fileId}/sheets
En-têtes : Access-Token, Client-Id, Open-Id
fileId=DQ1lxSE5hQ1V3WlJh(l'ID dans l'URLdocs.qq.com/sheet/DQ1lxSE5hQ1V3WlJh).- Noter le
sheetIdde l'onglet à surveiller (au départ : « Commandes pour 2026 »).
b) Lire une plage de cellules
GET https://docs.qq.com/openapi/spreadsheet/v3/files/{fileId}/{sheetId}/{range}
En-têtes : Access-Token, Client-Id, Open-Id
range= notation A1, ex.A1:AZ1000.- Limites par appel : ≤ 1000 lignes, ≤ 200 colonnes, ≤ 10 000 cellules → paginer :
A1:AZ1000,A1001:AZ2000, … (le node « Préparer les plages » le fait automatiquement). - Réponse :
gridData.rows[].values[].cellValue(structure exacte à vérifier sur une vraie réponse et à ajuster dans le node « Normaliser »).
c) Mapping des colonnes (⚠️ à confirmer avec l'en-tête réel, ligne 1)
D'après la capture (colonnes visibles F→P) :
| Col | En-tête | Champ |
|---|---|---|
| F | Platform order number | numero_commande |
| G | Name | nom |
| H | Telephone | telephone |
| I | country | pays |
| J | State/Province | region |
| K | city | ville |
| L | Adress | adresse |
| M | Postal code | code_postal |
| N | 产品 (produit) | produit |
| O | quantity | quantite |
| P | date of issuance | date_expedition |
| ? | Logistics tracking number | tracking_number ← À TROUVER (colonnes à droite) |
| ? | Customer email | email ← À TROUVER |
→ Compléter l'objet COL du node « Normaliser » (index de colonne : A=0, B=1, … F=5).
5. Variables d'environnement n8n (Coolify → n8n → Environment)
| Variable | Valeur |
|---|---|
TENCENT_CLIENT_ID |
Client ID de l'app (§1) |
TENCENT_CLIENT_SECRET |
Client Secret |
TENCENT_REFRESH_TOKEN |
refresh_token obtenu au §2 |
TENCENT_OPEN_ID |
user_id obtenu au §2 |
TENCENT_SHEET_ID |
sheetId de l'onglet (§4a) |
Ne jamais coder ces valeurs en dur dans les nodes. Voir guide 06 §6–7.
6. Multi-onglets (feuilles par période)
Le déclencheur/lecture est par onglet. Pour couvrir « Retours 2026 », « 2026 - Saint SAV », etc. (ADR 0004) : dupliquer le node « Préparer les plages » par sheetId, ou boucler sur une liste de sheetIds. Démarrer avec un seul onglet, généraliser ensuite.
7. Tester
- Appliquer d'abord
db/schema.sql. - Renseigner les 5 variables d'env + les credentials Postgres/SMTP (guide 06).
- Compléter le mapping
COL(tracking_number, email…) dans « Normaliser ». - Exécuter le workflow manuellement une fois → vérifier la réponse de « Lire la plage » (structure
gridData) et les items produits par « Normaliser ». - Activer le Schedule une fois le mapping validé.
Checklist
- App développeur créée + approuvée ;
Client ID/Client Secretrécupérés. - OAuth fait une fois →
refresh_token+user_idconservés. -
sheetIdde l'onglet récupéré. - 5 variables d'env n8n renseignées.
- Structure
gridDatavérifiée + node « Normaliser » ajusté. - Mapping colonnes
tracking_number/emailcomplété. - Test manuel OK, puis Schedule activé.
