Tutorial dello schema
Tutorial dello schemaLezione 16: Inviare una notifica quando c'è un nuovo post

Lezione 16: Inviare una notifica quando c'è un nuovo post

Gato GraphQL può aiutarci ad automatizzare attività nell'applicazione, come l'invio di un'e-mail di notifica all'amministratore quando c'è un nuovo post.

In questa lezione del tutorial esploreremo due modi per ottenere questo risultato.

Query GraphQL per inviare un'e-mail di notifica all'amministratore

Questa query GraphQL invia un'e-mail all'utente amministratore, notificandolo della creazione di un nuovo post sul sito:

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

Per inviare l'e-mail in testo semplice:

  • Utilizzare l'input messageAs: { text: ... } nella mutation _sendEmail
  • Rimuovere i tag HTML dal contenuto del post usando il campo globale _htmlStripTags (fornito dall'estensione PHP Functions via Schema)

Vediamo ora come attivare l'esecuzione della query GraphQL.

Opzione 1: Attivare sempre reagendo agli hook di WordPress

Ci agganceremo all'azione WordPress core new_to_publish, recupereremo i dati dal post appena creato ed eseguiremo la query GraphQL definita sopra contro il server GraphQL interno (fornito tramite l'estensione 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');
  }
);

La classe GatoGraphQL\InternalGraphQLServer\GraphQLServer non è accessibile come API esterna. È invece destinata ad essere utilizzata dall'applicazione tramite codice PHP, per eseguire/automatizzare attività di amministrazione tramite queries GraphQL.

Questa classe fornisce 3 metodi statici per eseguire queries:

  • executeQuery: Esegue una query GraphQL
  • executeQueryInFile: Esegue una query GraphQL contenuta in un file (.gql)
  • executePersistedQuery: Esegue una persisted GraphQL query (fornendo il suo ID come int, o lo slug come stringa)

Questa query GraphQL verrà eseguita ogni volta che viene creato un nuovo post o, più precisamente, ogni volta che la funzione WordPress wp_insert_post viene invocata (poiché questa funzione attiva l'hook new_to_publish):

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

Questo vale anche quando si esegue un'altra query GraphQL che esegue la mutation createPost (poiché il suo resolver, nel codice PHP, invoca la funzione wp_insert_post):

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

Il GraphQL Server (che è "esterno", accessibile come API tramite HTTP) e l'Internal GraphQL Server eseguiranno le loro queries applicando la propria Schema Configuration, anche quando la loro esecuzione si intreccia.

Ad esempio, supponiamo di eseguire una query GraphQL contro il single endpoint e che questa crei un post eseguendo la mutation createPost. Si svolge quindi la seguente sequenza di passaggi:

(Esterno) GraphQL ServerInternal GraphQL Server
Esegue la query GraphQL contro il single endpoint, utilizzando la propria Schema Configuration(non attivo)
Crea un post; questo attiva new_to_publish(non attivo)
(in attesa...)Reagisce all'hook new_to_publish: Avvia l'Internal GraphQL server, utilizzando la propria Schema Configuration
(in attesa...)Esegue la query per inviare un'e-mail
(in attesa...)Invia l'e-mail, fine di quella query
(in attesa...)Arresta il server
Continua l'esecuzione della query, fine di quella query(non attivo)
Arresta il server(non attivo)

Opzione 2: Attivare concatenando queries GraphQL

L'estensione Automation fa sì che il GraphQL Server attivi un hook dopo aver completato l'esecuzione di una query GraphQL. Questo ci consente di concatenare queries GraphQL.

Questo codice PHP esegue l'operazione SendEmail (query GraphQL definita sopra), dopo che il server GraphQL ha eseguito un'altra query con l'operazione CreatePost (query GraphQL definita sopra):

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

La concatenazione di queries GraphQL ci consente di eseguire una sola query, anche quando molte risorse sono state mutate.

Ad esempio, questa query GraphQL aggiorna molti post:

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

A seconda della nostra strategia, possiamo attivare l'esecuzione di una o più queries GraphQL aggiuntive:

Agganciandosi a...Attiva il numero di queries GraphQL...
post_updated (da WordPress core)Una per ogni post aggiornato
gatographql__executed_query:ReplaceDomains (dall'estensione Automation)Una in totale (riceverà i dati di tutti i post aggiornati)