Tutoriel du schéma
Tutoriel du schémaLeçon 16 : Envoyer une notification quand il y a une nouvelle publication

Leçon 16 : Envoyer une notification quand il y a une nouvelle publication

Gato GraphQL peut nous aider à automatiser des tâches dans l'application, comme l'envoi d'un e-mail de notification à l'administrateur lorsqu'il y a une nouvelle publication.

Dans cette leçon du tutoriel, nous allons explorer deux façons d'y parvenir.

Requête GraphQL pour envoyer un e-mail de notification à l'administrateur

Cette requête GraphQL envoie un e-mail à l'utilisateur administrateur, le notifiant de la création d'une nouvelle publication sur le site :

query GetEmailData(
  $postTitle: String!,
  $postContent: String!
  $postURL: URL!
) {
  adminEmail: optionValue(name: "admin_email")
    @export(as: "adminEmail")
 
  emailMessageTemplate: _strConvertMarkdownToHTML(
    text: """
 
There is a [new post on the site]({$postURL}):
 
**{$postTitle}**:
 
{$postContent}
 
    """
  )
  emailMessage: _strReplaceMultiple(
    search: ["{$postTitle}", "{$postContent}", "{$postURL}"],
    replaceWith: [$postTitle, $postContent, $postURL],
    in: $__emailMessageTemplate
  )
    @export(as: "emailMessage")
 
  emailSubject: _sprintf(
    string: "New post: \"%s\"",
    values: [$postTitle]
  )
    @export(as: "emailSubject")
}
 
mutation SendEmail @depends(on: "GetEmailData") {
  _sendEmail(
    input: {
      to: $adminEmail
      subject: $emailSubject
      messageAs: {
        html: $emailMessage
      }
    }
  ) {
    status
  }
}

Pour envoyer l'e-mail en texte brut :

  • Utilisez l'entrée messageAs: { text: ... } dans la mutation _sendEmail
  • Supprimez les balises HTML du contenu de la publication en utilisant le champ global _htmlStripTags (fourni par l'extension PHP Functions via Schema)

Voyons ensuite comment déclencher l'exécution de la requête GraphQL.

Option 1 : Déclencher toujours en réagissant aux hooks WordPress

Nous nous accrochons à l'action WordPress core new_to_publish, nous récupérons les données de la publication nouvellement créée, et nous exécutons la requête GraphQL définie ci-dessus contre le serveur GraphQL interne (fourni via l'extension Internal GraphQL Server) :

use GatoGraphQL\InternalGraphQLServer\GraphQLServer;
use WP_Post;
 
// The GraphQL query, under var `$query`, is the one defined above
// $query = '...';
add_action(
  'new_to_publish',
  function (WP_Post $post) use ($query) {
    $variables = [
      'postTitle' => $post->post_title,
      'postContent' => $post->post_content,
      'postURL' => get_permalink($post->ID),
    ]
    GraphQLServer::executeQuery($query, $variables, 'SendEmail');
  }
);

La classe GatoGraphQL\InternalGraphQLServer\GraphQLServer n'est pas accessible en tant qu'API externe. Elle est destinée à être utilisée par l'application via du code PHP, pour exécuter/automatiser des tâches d'administration via des requêtes GraphQL.

Cette classe fournit 3 méthodes statiques pour exécuter des requêtes :

  • executeQuery : Exécute une requête GraphQL
  • executeQueryInFile : Exécute une requête GraphQL contenue dans un fichier (.gql)
  • executePersistedQuery : Exécute une persisted GraphQL query (en fournissant son identifiant sous forme d'int, ou son slug sous forme de string)

Cette requête GraphQL sera exécutée chaque fois qu'une nouvelle publication est créée ou, pour être plus précis, chaque fois que la fonction WordPress wp_insert_post est invoquée (car cette fonction déclenche le hook new_to_publish) :

$postID = wp_insert_post([
  'post_title' => 'Hello world!'
]);

C'est également le cas lors de l'exécution d'une autre requête GraphQL qui exécute la mutation createPost (car son resolver, en code PHP, invoque la fonction wp_insert_post) :

mutation CreatePost {
  createPost(input: {
    title: "Hello world!"
  }) {
    status
    postID
  }
}

Le GraphQL Server (qui est « externe », accessible en tant qu'API via HTTP) et l'Internal GraphQL Server exécuteront leurs requêtes en appliquant leur propre Schema Configuration, même lorsque leur exécution s'entremêle.

Par exemple, supposons que nous exécutons une requête GraphQL contre l'endpoint unique, et qu'elle crée une publication en exécutant la mutation createPost. La séquence d'étapes suivante se déroule alors :

(Externe) GraphQL ServerInternal GraphQL Server
Exécute la requête GraphQL contre l'endpoint unique, en utilisant sa propre Schema Configuration(non actif)
Crée une publication ; cela déclenche new_to_publish(non actif)
(en attente...)Réagit au hook new_to_publish : Démarre l'Internal GraphQL server, en utilisant sa propre Schema Configuration
(en attente...)Exécute la requête pour envoyer un e-mail
(en attente...)Envoie l'e-mail, fin de cette requête
(en attente...)Arrête le serveur
Continue l'exécution de la requête, fin de cette requête(non actif)
Arrête le serveur(non actif)

Option 2 : Déclencher en enchaînant des requêtes GraphQL

L'extension Automatisation fait en sorte que le GraphQL Server déclenche un hook après avoir terminé l'exécution d'une requête GraphQL. Cela nous permet d'enchaîner des requêtes GraphQL.

Ce code PHP exécute l'opération SendEmail (requête GraphQL définie ci-dessus), après que le serveur GraphQL a exécuté une autre requête avec l'opération CreatePost (requête GraphQL définie ci-dessus) :

// The GraphQL query, under var `$query`, is the one defined above
// $query = '...';
add_action(
  "gatographql__executed_query:CreatePost",
  function (Response $response) use ($query) {
    // @var string
    $responseContent = $response->getContent();
    // @var array<string,mixed>
    $responseJSON = json_decode($responseContent, true);
    $postID = $responseJSON['data']['createPost']['postID'] ?? null;
    if ($postID === null) {
      // Do nothing
      return;
    }
 
    $post = get_post($postID);
    $variables = [
      'postTitle' => $post->post_title,
      'postContent' => $post->post_content,
      'postURL' => get_permalink($post->ID),
    ]
    GraphQLServer::executeQuery($query, $variables, 'SendEmail');
  }
);

L'enchaînement de requêtes GraphQL nous permet d'exécuter une seule requête, même lorsque de nombreuses ressources ont été mutées.

Par exemple, cette requête GraphQL met à jour de nombreuses publications :

mutation ReplaceDomains {
  posts {
    id
    rawContent
    adaptedRawContent: _strReplace(
      search: "https://my-old-domain.com"
      replaceWith: "https://my-new-domain.com"
      in: $__rawContent
    )
    update(input: {
      contentAs: { html: $__adaptedRawContent }
    }) {
      status
      postID
    }
  }
}

Selon notre stratégie, nous pouvons déclencher l'exécution d'une ou de plusieurs requêtes GraphQL supplémentaires :

En s'accrochant à...Déclenche le nombre de requêtes GraphQL...
post_updated (par WordPress core)Une pour chaque publication mise à jour
gatographql__executed_query:ReplaceDomains (par l'extension Automatisation)Une au total (elle recevra les données de toutes les publications mises à jour)