# Appeler une API de LLM depuis une extension WordPress avec wp_remote_post

> Tutoriel pas à pas pour brancher une extension WordPress sur une API de modèle de langage, avec wp_remote_post, gestion des erreurs et bonnes pratiques de sécurité.

- Auteur : Clément Hadrot
- Publié le : 2023-05-16
- Mis à jour le : 2023-05-16
- Catégorie : IA &amp; MCP
- URL : https://wpmoderne.dev.wordpress-developpement.fr/ia-mcp/appeler-api-llm-wp-remote-post/

## L’essentiel

- wp_remote_post gère l'appel HTTP sortant côté serveur
- Toujours vérifier is_wp_error avant de lire la réponse
- Ne jamais exposer la clé API côté client

Brancher une extension WordPress sur une API de modèle de langage est devenu, en quelques mois, une demande récurrente côté clients : générer une méta-description, résumer un article, suggérer des titres. Techniquement, cela revient à effectuer un appel HTTP sortant depuis le serveur WordPress vers l'API du fournisseur choisi, puis à traiter la réponse JSON renvoyée. WordPress fournit pour cela une fonction dédiée, `wp_remote_post()`, qui évite de manipuler directement cURL et gère les particularités d'hébergement de façon plus portable.

Cet article détaille la structure d'un appel correct, les pièges classiques à éviter, et la façon de renvoyer proprement le résultat côté administration.

## Structure de base d'un appel

La fonction `wp_remote_post()` attend une URL et un tableau d'arguments contenant les en-têtes, le corps de la requête et un délai d'expiration. Voici un exemple minimal d'appel vers une API de complétion de texte :

```
$response = wp_remote_post(
    'https://api.exemple-llm.com/v1/completions',
    array(
        'headers' => array(
            'Authorization' => 'Bearer ' . $api_key,
            'Content-Type'  => 'application/json',
        ),
        'body'    => wp_json_encode( array(
            'model'      => 'modele-exemple',
            'prompt'     => $prompt,
            'max_tokens' => 300,
        ) ),
        'timeout' => 30,
    )
);
```

Le point important ici est le `timeout`. Par défaut, WordPress fixe un délai de cinq secondes pour les requêtes distantes, largement insuffisant pour une génération de texte qui peut prendre quinze à trente secondes selon la longueur demandée. Oublier d'augmenter ce délai est l'erreur la plus fréquente sur ce type d'intégration : l'appel échoue silencieusement avant même que le modèle ait fini de répondre.

## Traiter la réponse sans planter l'admin

Contrairement à cURL utilisé directement, `wp_remote_post()` ne lève jamais d'exception : en cas d'échec réseau, elle renvoie un objet `WP_Error`. Il faut donc systématiquement vérifier ce cas avant de tenter de lire le corps de la réponse, sous peine de fatal error sur une fonction appelée sur un objet inexistant.

> L'essentiel à retenir : wp_remote_post gère l'appel HTTP sortant côté serveur ; Toujours vérifier is_wp_error avant de lire la réponse ; Ne jamais exposer la clé API côté client

```
if ( is_wp_error( $response ) ) {
    error_log( 'Erreur appel LLM : ' . $response->get_error_message() );
    return new WP_Error( 'llm_request_failed', __( 'Le service IA est indisponible.', 'mon-extension' ) );
}

$code = wp_remote_retrieve_response_code( $response );
$body = json_decode( wp_remote_retrieve_body( $response ), true );

if ( 200 !== $code || empty( $body['choices'][0]['text'] ) ) {
    return new WP_Error( 'llm_bad_response', __( 'Réponse inattendue du service IA.', 'mon-extension' ) );
}

$texte_genere = sanitize_textarea_field( $body['choices'][0]['text'] );
```

Notez l'usage de `sanitize_textarea_field()` sur le texte renvoyé : même si la source est un service tiers de confiance, tout contenu externe qui finira par être affiché ou stocké doit être traité comme non fiable par défaut.

## Où placer cet appel dans le cycle WordPress

Un appel LLM synchrone, exécuté directement dans le rendu d'une page publique, bloque le chargement pour le visiteur pendant plusieurs secondes : c'est à proscrire. Les intégrations sérieuses passent par l'un de ces deux mécanismes :

- Une action déclenchée depuis l'administration via `admin-ajax.php` ou l'API REST de WordPress, appelée en arrière-plan depuis l'éditeur
- Une tâche planifiée avec `wp_schedule_single_event()`, pour un traitement différé qui ne bloque aucune requête utilisateur

Pour une génération déclenchée depuis l'écran d'édition d'un article, la première approche est la plus courante : un bouton dans l'éditeur envoie une requête vers un point de terminaison REST personnalisé, enregistré avec `register_rest_route()`, qui exécute l'appel `wp_remote_post()` côté serveur et renvoie le résultat en JSON au client.

## Sécuriser l'intégration

La clé API du fournisseur ne doit jamais transiter côté navigateur : tout appel direct depuis JavaScript exposerait la clé dans le code source de la page, accessible à n'importe quel visiteur. L'appel doit systématiquement passer par le serveur WordPress, qui seul connaît la clé stockée dans les réglages de l'extension. Sur le point de terminaison REST, il est indispensable de vérifier les permissions avec un `permission_callback` restrictif (par exemple `current_user_can( 'edit_posts' )`) et de vérifier le nonce transmis depuis l'éditeur, faute de quoi n'importe quel utilisateur connecté pourrait déclencher des appels facturés à votre compte.

> Un appel IA mal protégé côté serveur coûte de l'argent à chaque clic, pas seulement en cas d'attaque.

## En résumé

`wp_remote_post()` reste l'outil natif le plus adapté pour brancher une extension WordPress sur une API de modèle de langage : il gère proprement les erreurs réseau, s'intègre au système de filtres WordPress et évite de réinventer une couche HTTP maison. Les points de vigilance restent constants d'un projet à l'autre : un délai d'expiration réaliste, une vérification systématique des erreurs, un traitement asynchrone côté administration, et une clé API qui ne quitte jamais le serveur.
