Tutorial skema
Tutorial skemaPelajaran 16: Mengirim notifikasi saat ada postingan baru

Pelajaran 16: Mengirim notifikasi saat ada postingan baru

Gato GraphQL dapat membantu kita mengotomatiskan tugas dalam aplikasi, seperti mengirim email notifikasi kepada admin saat ada postingan baru.

Dalam pelajaran tutorial ini kita akan menjelajahi dua cara untuk mencapai hal ini.

Query GraphQL untuk mengirim email notifikasi kepada admin

Query GraphQL ini mengirim email kepada pengguna admin, memberitahukan pembuatan postingan baru di situs:

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

Untuk mengirim email dalam teks biasa:

  • Gunakan input messageAs: { text: ... } pada mutasi _sendEmail
  • Hapus tag HTML dari konten postingan menggunakan field global _htmlStripTags (disediakan oleh ekstensi PHP Functions via Schema)

Mari kita lihat selanjutnya cara memicu eksekusi query GraphQL.

Opsi 1: Memicu selalu dengan bereaksi terhadap hooks WordPress

Kita mengaitkan diri ke action WordPress core new_to_publish, mengambil data dari postingan yang baru dibuat, dan mengeksekusi query GraphQL yang didefinisikan di atas terhadap internal GraphQL server (disediakan melalui ekstensi 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');
  }
);

Class GatoGraphQL\InternalGraphQLServer\GraphQLServer tidak dapat diakses sebagai API eksternal. Sebaliknya, class ini dimaksudkan untuk digunakan oleh aplikasi melalui kode PHP, untuk mengeksekusi/mengotomatiskan tugas admin melalui query GraphQL.

Class ini menyediakan 3 metode statis untuk mengeksekusi query:

  • executeQuery: Mengeksekusi sebuah query GraphQL
  • executeQueryInFile: Mengeksekusi sebuah query GraphQL yang tersimpan dalam file (.gql)
  • executePersistedQuery: Mengeksekusi sebuah persisted GraphQL query (dengan memberikan ID-nya sebagai int, atau slug sebagai string)

Query GraphQL ini akan dieksekusi setiap kali postingan baru dibuat atau, lebih tepatnya, setiap kali fungsi WordPress wp_insert_post dipanggil (karena fungsi ini memicu hook new_to_publish):

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

Hal ini juga berlaku saat mengeksekusi query GraphQL lain yang mengeksekusi mutasi createPost (karena resolver-nya, dalam kode PHP, memanggil fungsi wp_insert_post):

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

GraphQL Server (yang bersifat "eksternal", diakses sebagai API melalui HTTP) dan Internal GraphQL Server akan mengeksekusi query mereka dengan menerapkan Schema Configuration masing-masing, bahkan ketika eksekusi mereka saling terkait.

Misalnya, katakanlah kita sedang mengeksekusi sebuah query GraphQL terhadap single endpoint, dan ia membuat sebuah postingan dengan mengeksekusi mutasi createPost. Maka urutan langkah berikut terjadi:

(Eksternal) GraphQL ServerInternal GraphQL Server
Mengeksekusi query GraphQL terhadap single endpoint, menggunakan Schema Configuration-nya sendiri(tidak aktif)
Membuat postingan; ini memicu new_to_publish(tidak aktif)
(menunggu...)Bereaksi terhadap hook new_to_publish: Menjalankan Internal GraphQL server, menggunakan Schema Configuration-nya sendiri
(menunggu...)Mengeksekusi query untuk mengirim email
(menunggu...)Mengirim email, akhir dari query tersebut
(menunggu...)Mematikan server
Melanjutkan eksekusi query, akhir dari query tersebut(tidak aktif)
Mematikan server(tidak aktif)

Opsi 2: Memicu dengan merantai query GraphQL

Ekstensi Automation membuat GraphQL Server memicu sebuah hook setelah menyelesaikan eksekusi sebuah query GraphQL. Ini memungkinkan kita untuk merantai query GraphQL.

Kode PHP ini mengeksekusi operasi SendEmail (query GraphQL yang didefinisikan di atas), setelah GraphQL server telah mengeksekusi query lain dengan operasi CreatePost (query GraphQL yang didefinisikan di atas):

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

Merantai query GraphQL memungkinkan kita mengeksekusi hanya satu query, bahkan ketika banyak resource telah dimutasi.

Misalnya, query GraphQL ini memperbarui banyak postingan:

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

Bergantung pada strategi kita, kita dapat memicu eksekusi satu atau beberapa query GraphQL tambahan:

Mengaitkan ke...Memicu jumlah query GraphQL...
post_updated (oleh WordPress core)Satu untuk setiap postingan yang diperbarui
gatographql__executed_query:ReplaceDomains (oleh ekstensi Automation)Satu secara total (akan menerima data untuk semua postingan yang diperbarui)