Samouczek schematu
Samouczek schematuLekcja 16: Wysyłanie powiadomienia gdy pojawi się nowy post

Lekcja 16: Wysyłanie powiadomienia gdy pojawi się nowy post

Gato GraphQL może pomóc nam automatyzować zadania w aplikacji, takie jak wysyłanie e-maila z powiadomieniem do administratora gdy pojawi się nowy post.

W tej lekcji tutorialu omówimy dwa sposoby osiągnięcia tego rezultatu.

Query GraphQL do wysyłania e-maila z powiadomieniem do administratora

Ta query GraphQL wysyła e-mail do użytkownika administratora, informując o utworzeniu nowego posta na stronie:

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

Aby wysłać e-mail w zwykłym tekście:

  • Użyj wejścia messageAs: { text: ... } w mutacji _sendEmail
  • Usuń tagi HTML z treści posta używając globalnego pola _htmlStripTags (dostarczonego przez rozszerzenie PHP Functions via Schema)

Zobaczmy teraz, jak wyzwolić wykonanie query GraphQL.

Opcja 1: Wyzwalanie zawsze przez reagowanie na hooki WordPress

Podpinamy się pod akcję WordPress core new_to_publish, pobieramy dane z nowo utworzonego posta i wykonujemy query GraphQL zdefiniowaną powyżej przeciwko wewnętrznemu serwerowi GraphQL (dostarczonemu przez rozszerzenie 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');
  }
);

Klasa GatoGraphQL\InternalGraphQLServer\GraphQLServer nie jest dostępna jako zewnętrzne API. Zamiast tego powinna być używana przez aplikację poprzez kod PHP, do wykonywania/automatyzowania zadań administracyjnych za pomocą queries GraphQL.

Ta klasa udostępnia 3 metody statyczne do wykonywania queries:

  • executeQuery: Wykonuje query GraphQL
  • executeQueryInFile: Wykonuje query GraphQL zawartą w pliku (.gql)
  • executePersistedQuery: Wykonuje persisted GraphQL query (podając jej ID jako int lub slug jako string)

Ta query GraphQL będzie wykonywana za każdym razem, gdy zostanie utworzony nowy post lub, mówiąc dokładniej, za każdym razem, gdy zostanie wywołana funkcja WordPress wp_insert_post (ponieważ ta funkcja wyzwala hook new_to_publish):

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

Dotyczy to również sytuacji, gdy wykonywana jest inna query GraphQL wykonująca mutację createPost (ponieważ jej resolver, w kodzie PHP, wywołuje funkcję wp_insert_post):

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

GraphQL Server (który jest "zewnętrzny", dostępny jako API przez HTTP) oraz Internal GraphQL Server będą wykonywać swoje queries stosując własną Schema Configuration, nawet gdy ich wykonanie jest przeplatane.

Na przykład, powiedzmy, że wykonujemy query GraphQL przeciwko single endpoint i tworzy ona post wykonując mutację createPost. Wtedy następuje poniższa sekwencja kroków:

(Zewnętrzny) GraphQL ServerInternal GraphQL Server
Wykonuje query GraphQL przeciwko single endpoint, używając własnej Schema Configuration(nieaktywny)
Tworzy post; to wyzwala new_to_publish(nieaktywny)
(oczekiwanie...)Reaguje na hook new_to_publish: Uruchamia Internal GraphQL server, używając własnej Schema Configuration
(oczekiwanie...)Wykonuje query w celu wysłania e-maila
(oczekiwanie...)Wysyła e-mail, koniec tej query
(oczekiwanie...)Zamyka serwer
Kontynuuje wykonanie query, koniec tej query(nieaktywny)
Zamyka serwer(nieaktywny)

Opcja 2: Wyzwalanie przez łańcuchowanie queries GraphQL

Rozszerzenie Automation sprawia, że GraphQL Server wyzwala hook po zakończeniu wykonywania query GraphQL. Pozwala nam to łączyć queries GraphQL w łańcuchy.

Ten kod PHP wykonuje operację SendEmail (query GraphQL zdefiniowana powyżej), po tym jak serwer GraphQL wykonał inną query z operacją CreatePost (query GraphQL zdefiniowana powyżej):

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

Łańcuchowanie queries GraphQL pozwala nam wykonać jedną query, nawet gdy wiele zasobów zostało zmodyfikowanych.

Na przykład, ta query GraphQL aktualizuje wiele postów:

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

W zależności od naszej strategii, możemy wyzwolić wykonanie jednej lub wielu dodatkowych queries GraphQL:

Podpinając się pod...Wyzwala liczbę queries GraphQL...
post_updated (przez WordPress core)Jedną dla każdego zaktualizowanego posta
gatographql__executed_query:ReplaceDomains (przez rozszerzenie Automation)Jedną łącznie (otrzyma dane dla wszystkich zaktualizowanych postów)