Lição 16: Enviando uma notificação quando há um novo post
O Gato GraphQL pode nos ajudar a automatizar tarefas na aplicação, como o envio de um e-mail de notificação ao administrador quando há um novo post.
Nesta lição do tutorial, exploraremos duas maneiras de alcançar esse resultado.
Query GraphQL para enviar um e-mail de notificação ao administrador
Esta query GraphQL envia um e-mail ao usuário administrador, notificando-o da criação de um novo post no 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
}
}Para enviar o e-mail em texto simples:
- Use o input
messageAs: { text: ... }na mutation_sendEmail - Remova as tags HTML do conteúdo do post usando o campo global
_htmlStripTags(fornecido pela extensão PHP Functions via Schema)
Vejamos agora como acionar a execução da query GraphQL.
Opção 1: Acionar sempre reagindo aos hooks do WordPress
Nos conectamos à action do WordPress core new_to_publish, recuperamos os dados do post recém-criado e executamos a query GraphQL definida acima contra o servidor GraphQL interno (fornecido pela extensão 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');
}
);A classe GatoGraphQL\InternalGraphQLServer\GraphQLServer não é acessível como uma API externa. Em vez disso, ela deve ser usada pela aplicação via código PHP, para executar/automatizar tarefas administrativas por meio de queries GraphQL.
Esta classe fornece 3 métodos estáticos para executar queries:
executeQuery: Executa uma query GraphQLexecuteQueryInFile: Executa uma query GraphQL contida em um arquivo (.gql)executePersistedQuery: Executa uma persisted GraphQL query (fornecendo seu ID como int, ou o slug como string)
Esta query GraphQL será executada sempre que um novo post for criado ou, mais precisamente, sempre que a função WordPress wp_insert_post for invocada (pois essa função aciona o hook new_to_publish):
$postID = wp_insert_post([
'post_title' => 'Hello world!'
]);Este também é o caso ao executar outra query GraphQL que executa a mutation createPost (pois seu resolver, no código PHP, invoca a função wp_insert_post):
mutation CreatePost {
createPost(input: {
title: "Hello world!"
}) {
status
postID
}
}O GraphQL Server (que é "externo", acessado como uma API via HTTP) e o Internal GraphQL Server executarão suas queries aplicando sua própria Schema Configuration, mesmo quando suas execuções estiverem entrelaçadas.
Por exemplo, digamos que estamos executando uma query GraphQL contra o single endpoint e ela cria um post ao executar a mutation createPost. A seguinte sequência de etapas ocorre:
| (Externo) GraphQL Server | Internal GraphQL Server |
|---|---|
| Executa a query GraphQL contra o single endpoint, usando sua própria Schema Configuration | (não ativo) |
Cria um post; isso aciona new_to_publish | (não ativo) |
| (aguardando...) | Reage ao hook new_to_publish: Inicializa o Internal GraphQL server, usando sua própria Schema Configuration |
| (aguardando...) | Executa a query para enviar um e-mail |
| (aguardando...) | Envia o e-mail, fim dessa query |
| (aguardando...) | Encerra o servidor |
| Continua a execução da query, fim dessa query | (não ativo) |
| Encerra o servidor | (não ativo) |
Opção 2: Acionar encadeando queries GraphQL
A extensão Automation faz com que o GraphQL Server acione um hook após concluir a execução de uma query GraphQL. Isso nos permite encadear queries GraphQL.
Este código PHP executa a operação SendEmail (query GraphQL definida acima), após o servidor GraphQL ter executado outra query com a operação CreatePost (query GraphQL definida acima):
// 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');
}
);O encadeamento de queries GraphQL nos permite executar uma única query, mesmo quando muitos recursos foram mutados.
Por exemplo, esta query GraphQL atualiza muitos posts:
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
}
}
}Dependendo da nossa estratégia, podemos acionar a execução de uma ou mais queries GraphQL adicionais:
| Conectando-se a... | Aciona o número de queries GraphQL... |
|---|---|
post_updated (pelo WordPress core) | Uma para cada post atualizado |
gatographql__executed_query:ReplaceDomains (pela extensão Automation) | Uma no total (receberá os dados de todos os posts atualizados) |