Schema-Tutorial
Schema-TutorialLektion 16: Eine Benachrichtigung senden, wenn es einen neuen Beitrag gibt

Lektion 16: Eine Benachrichtigung senden, wenn es einen neuen Beitrag gibt

Gato GraphQL kann uns helfen, Aufgaben in der Anwendung zu automatisieren, wie das Senden einer Benachrichtigungs-E-Mail an den Administrator, wenn es einen neuen Beitrag gibt.

In dieser Tutorial-Lektion werden wir zwei Möglichkeiten erkunden, dies zu erreichen.

GraphQL-Query zum Senden einer Benachrichtigungs-E-Mail an den Administrator

Diese GraphQL-Query sendet eine E-Mail an den Administrator-Benutzer und benachrichtigt ihn ĂĽber die Erstellung eines neuen Beitrags auf der Website:

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

Um die E-Mail als Klartext zu senden:

  • Verwende den Input messageAs: { text: ... } in der _sendEmail-Mutation
  • Entferne die HTML-Tags aus dem Beitragsinhalt mit dem globalen Feld _htmlStripTags (bereitgestellt von der Erweiterung PHP Functions via Schema)

Schauen wir uns nun an, wie die Ausführung der GraphQL-Query ausgelöst werden kann.

Option 1: Immer durch Reagieren auf WordPress-Hooks auslösen

Wir hängen uns in die WordPress-Core-Aktion new_to_publish ein, rufen die Daten des neu erstellten Beitrags ab und führen die oben definierte GraphQL-Query gegen den internen GraphQL-Server aus (bereitgestellt über die Erweiterung 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');
  }
);

Die Klasse GatoGraphQL\InternalGraphQLServer\GraphQLServer ist nicht als externe API zugänglich. Sie ist stattdessen dafür gedacht, von der Anwendung über PHP-Code verwendet zu werden, um Admin-Aufgaben über GraphQL-queries auszuführen/automatisieren.

Diese Klasse stellt 3 statische Methoden zur AusfĂĽhrung von queries bereit:

  • executeQuery: FĂĽhrt eine GraphQL-Query aus
  • executeQueryInFile: FĂĽhrt eine GraphQL-Query aus, die in einer (.gql)-Datei enthalten ist
  • executePersistedQuery: FĂĽhrt eine persistierte GraphQL-Query aus (mit ihrer ID als int oder ihrem Slug als String)

Diese GraphQL-Query wird jedes Mal ausgeführt, wenn ein neuer Beitrag erstellt wird, oder genauer gesagt, jedes Mal, wenn die WordPress-Funktion wp_insert_post aufgerufen wird (da diese Funktion den Hook new_to_publish auslöst):

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

Dies gilt auch beim AusfĂĽhren einer anderen GraphQL-Query, die die createPost-Mutation ausfĂĽhrt (da deren Resolver im PHP-Code die Funktion wp_insert_post aufruft):

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

Der GraphQL-Server (der „extern" ist und als API über HTTP zugänglich ist) und der Internal GraphQL Server führen ihre queries unter Anwendung ihrer eigenen Schema-Konfiguration aus, auch wenn ihre Ausführung verschränkt ist.

Angenommen, wir führen eine GraphQL-Query gegen den Single-Endpoint aus, und diese erstellt einen Beitrag durch Ausführung der createPost-Mutation. Dann läuft folgende Schrittsequenz ab:

(Externer) GraphQL-ServerInternal GraphQL Server
FĂĽhrt die GraphQL-Query gegen den Single-Endpoint aus, unter Verwendung der eigenen Schema-Konfiguration(nicht aktiv)
Erstellt einen Beitrag; dies löst new_to_publish aus(nicht aktiv)
(wartend...)Reagiert auf den new_to_publish-Hook: Startet den Internal GraphQL-Server mit seiner eigenen Schema-Konfiguration
(wartend...)FĂĽhrt die Query zum Senden einer E-Mail aus
(wartend...)Sendet die E-Mail, Ende dieser Query
(wartend...)Fährt den Server herunter
Setzt die AusfĂĽhrung der Query fort, Ende dieser Query(nicht aktiv)
Fährt den Server herunter(nicht aktiv)

Option 2: Durch Verkettung von GraphQL-Queries auslösen

Die Erweiterung Automation lässt den GraphQL-Server nach Abschluss der Ausführung einer GraphQL-Query einen Hook auslösen. Dies erlaubt uns, GraphQL-queries zu verketten.

Dieser PHP-Code fĂĽhrt die SendEmail-Operation (oben definierte GraphQL-Query) aus, nachdem der GraphQL-Server eine andere Query mit der Operation CreatePost (oben definierte GraphQL-Query) ausgefĂĽhrt hat:

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

Die Verkettung von GraphQL-queries ermöglicht es uns, eine einzige Query auszuführen, auch wenn viele Ressourcen mutiert wurden.

Zum Beispiel aktualisiert diese GraphQL-Query viele Beiträge:

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

Je nach unserer Strategie können wir die Ausführung einer oder mehrerer zusätzlicher GraphQL-queries auslösen:

Einhängen in...Löst Anzahl von GraphQL-queries aus...
post_updated (durch WordPress Core)Eine pro aktualisiertem Beitrag
gatographql__executed_query:ReplaceDomains (durch die Erweiterung Automation)Eine insgesamt (sie erhält die Daten für alle aktualisierten Beiträge)