Hướng dẫn schema
Hướng dẫn schemaBài học 16: Gửi thông báo khi có bài viết mới

Bài học 16: Gửi thông báo khi có bài viết mới

Gato GraphQL có thể giúp chúng ta tự động hóa các tác vụ trong ứng dụng, chẳng hạn như gửi email thông báo cho quản trị viên khi có bài viết mới.

Trong bài học hướng dẫn này, chúng ta sẽ khám phá hai cách để đạt được điều này.

GraphQL query để gửi email thông báo cho quản trị viên

GraphQL query này gửi một email đến người dùng quản trị viên, thông báo về việc tạo một bài viết mới trên trang:

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

Để gửi email dưới dạng văn bản thuần túy:

  • Sử dụng input messageAs: { text: ... } trong mutation _sendEmail
  • Xóa các thẻ HTML khỏi nội dung bài viết bằng cách sử dụng global field _htmlStripTags (được cung cấp bởi extension PHP Functions via Schema)

Tiếp theo, hãy xem cách kích hoạt việc thực thi GraphQL query.

Tùy chọn 1: Kích hoạt luôn luôn bằng cách phản ứng với các hook của WordPress

Chúng ta móc vào action WordPress core new_to_publish, lấy dữ liệu từ bài viết vừa được tạo, và thực thi GraphQL query đã định nghĩa ở trên đối với internal GraphQL server (được cung cấp thông qua extension 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 không thể truy cập như một API bên ngoài. Thay vào đó, nó được sử dụng bởi ứng dụng thông qua mã PHP, để thực thi/tự động hóa các tác vụ quản trị thông qua GraphQL queries.

Class này cung cấp 3 phương thức tĩnh để thực thi queries:

  • executeQuery: Thực thi một GraphQL query
  • executeQueryInFile: Thực thi một GraphQL query chứa trong một file (.gql)
  • executePersistedQuery: Thực thi một persisted GraphQL query (cung cấp ID của nó dưới dạng int, hoặc slug dưới dạng string)

GraphQL query này sẽ được thực thi mỗi khi một bài viết mới được tạo, hay nói chính xác hơn, mỗi khi hàm WordPress wp_insert_post được gọi (vì hàm này kích hoạt hook new_to_publish):

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

Điều này cũng xảy ra khi thực thi một GraphQL query khác thực thi mutation createPost (vì resolver của nó, trong mã PHP, gọi hàm wp_insert_post):

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

GraphQL Server (là server "bên ngoài", được truy cập như một API qua HTTP) và Internal GraphQL Server sẽ thực thi các queries của mình áp dụng Schema Configuration riêng của từng server, ngay cả khi việc thực thi của chúng đan xen nhau.

Ví dụ, giả sử chúng ta đang thực thi một GraphQL query đối với single endpoint, và nó tạo một bài viết bằng cách thực thi mutation createPost. Khi đó, trình tự các bước sau sẽ diễn ra:

(Bên ngoài) GraphQL ServerInternal GraphQL Server
Thực thi GraphQL query đối với single endpoint, sử dụng Schema Configuration của riêng nó(không hoạt động)
Tạo một bài viết; điều này kích hoạt new_to_publish(không hoạt động)
(đang chờ...)Phản ứng với hook new_to_publish: Khởi động Internal GraphQL server, sử dụng Schema Configuration của riêng nó
(đang chờ...)Thực thi query để gửi email
(đang chờ...)Gửi email, kết thúc query đó
(đang chờ...)Tắt server
Tiếp tục thực thi query, kết thúc query đó(không hoạt động)
Tắt server(không hoạt động)

Tùy chọn 2: Kích hoạt bằng cách xâu chuỗi các GraphQL queries

Extension Automation khiến GraphQL Server kích hoạt một hook sau khi hoàn thành việc thực thi một GraphQL query. Điều này cho phép chúng ta xâu chuỗi các GraphQL queries.

Mã PHP này thực thi operation SendEmail (GraphQL query đã định nghĩa ở trên), sau khi GraphQL server đã thực thi một query khác với operation CreatePost (GraphQL query đã định nghĩa ở trên):

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

Xâu chuỗi các GraphQL queries cho phép chúng ta chỉ thực thi một query duy nhất, ngay cả khi nhiều tài nguyên đã được thay đổi.

Ví dụ, GraphQL query này cập nhật nhiều bài viết:

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

Tùy thuộc vào chiến lược của chúng ta, chúng ta có thể kích hoạt việc thực thi một hoặc nhiều GraphQL queries bổ sung:

Móc vào...Số GraphQL queries được kích hoạt...
post_updated (bởi WordPress core)Một cho mỗi bài viết được cập nhật
gatographql__executed_query:ReplaceDomains (bởi extension Automation)Một tổng cộng (sẽ nhận dữ liệu của tất cả các bài viết được cập nhật)