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 GraphQLexecuteQueryInFile: 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 Server | Internal 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) |