Schema-tutorial
Schema-tutorialLes 16: Een melding sturen bij een nieuw bericht

Les 16: Een melding sturen bij een nieuw bericht

Gato GraphQL kan ons helpen taken in de applicatie te automatiseren, zoals het sturen van een e-mailmelding aan de beheerder wanneer er een nieuw bericht is.

In deze tutorielles verkennen we twee manieren om dit te bereiken.

GraphQL query om een e-mailmelding naar de beheerder te sturen

Deze GraphQL query stuurt een e-mail naar de beheerder om te melden dat er een nieuw bericht op de site is aangemaakt:

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
  }
}

Om de e-mail als platte tekst te versturen:

  • Gebruik invoer messageAs: { text: ... } in de _sendEmail mutatie
  • Verwijder de HTML-tags uit de berichtinhoud met het globale veld _htmlStripTags (geleverd door de PHP Functions via Schema extensie)

Laten we nu bekijken hoe we de uitvoering van de GraphQL query kunnen activeren.

Optie 1: Altijd activeren door te reageren op WordPress hooks

We koppelen aan de WordPress core actie new_to_publish, halen de gegevens op van het nieuw aangemaakte bericht en voeren de hierboven gedefinieerde GraphQL query uit tegen de interne GraphQL server (geleverd via de Internal GraphQL Server extensie):

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');
  }
);

De klasse GatoGraphQL\InternalGraphQLServer\GraphQLServer is niet toegankelijk als externe API. In plaats daarvan dient deze door de applicatie via PHP-code te worden gebruikt voor het uitvoeren/automatiseren van beheertaken via GraphQL queries.

Deze klasse biedt 3 statische methoden om queries uit te voeren:

  • executeQuery: Voer een GraphQL query uit
  • executeQueryInFile: Voer een GraphQL query uit die is opgeslagen in een (.gql) bestand
  • executePersistedQuery: Voer een persisted GraphQL query uit (geef het ID op als int, of de slug als string)

Deze GraphQL query wordt uitgevoerd telkens wanneer er een nieuw bericht wordt aangemaakt of, preciezer gezegd, telkens wanneer de WordPress-functie wp_insert_post wordt aangeroepen (omdat deze functie de hook new_to_publish activeert):

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

Dit geldt ook wanneer een andere GraphQL query wordt uitgevoerd die de createPost mutatie uitvoert (omdat de resolver ervan, in PHP-code, de functie wp_insert_post aanroept):

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

De GraphQL Server (die "extern" is en als API via HTTP toegankelijk is) en de Internal GraphQL Server voeren hun queries uit met hun eigen Schema Configuration, zelfs wanneer hun uitvoering verweven is.

Stel bijvoorbeeld dat we een GraphQL query uitvoeren tegen het single endpoint, en die maakt een bericht aan door de createPost mutatie uit te voeren. Dan volgt de volgende reeks stappen:

(Externe) GraphQL ServerInternal GraphQL Server
Voert GraphQL query uit tegen het single endpoint, met eigen Schema Configuration(niet actief)
Maakt een bericht aan; dit activeert new_to_publish(niet actief)
(wachten...)Reageert op hook new_to_publish: Start de Internal GraphQL server op, met eigen Schema Configuration
(wachten...)Voert de query uit om een e-mail te versturen
(wachten...)Verstuurt e-mail, einde van die query
(wachten...)Sluit server af
Gaat verder met de uitvoering van de query, einde van die query(niet actief)
Sluit server af(niet actief)

Optie 2: Activeren door GraphQL queries te ketenen

De Automation extensie zorgt ervoor dat de GraphQL Server een hook activeert na het voltooien van de uitvoering van een GraphQL query. Hierdoor kunnen we GraphQL queries aan elkaar koppelen.

Deze PHP-code voert de SendEmail operatie uit (hierboven gedefinieerde GraphQL query), nadat de GraphQL server een andere query heeft uitgevoerd met de operatie CreatePost (hierboven gedefinieerde GraphQL query):

// 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');
  }
);

Het ketenen van GraphQL queries stelt ons in staat slechts één query uit te voeren, zelfs wanneer er veel resources zijn gemuteerd.

Zo werkt deze GraphQL query bijvoorbeeld veel berichten bij:

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
    }
  }
}

Afhankelijk van onze strategie kunnen we de uitvoering van één of meerdere aanvullende GraphQL queries activeren:

Koppelen aan...Activeert aantal GraphQL queries...
post_updated (door WordPress core)Eén voor elk bijgewerkt bericht
gatographql__executed_query:ReplaceDomains (door de Automation extensie)Eén in totaal (ontvangt de gegevens voor alle bijgewerkte berichten)