스키마 튜토리얼
스키마 튜토리얼레슨 16: 새 게시물이 있을 때 알림 보내기

레슨 16: 새 게시물이 있을 때 알림 보내기

Gato GraphQL은 새 게시물이 있을 때 관리자에게 알림 이메일을 보내는 등 애플리케이션의 작업을 자동화하는 데 도움이 됩니다.

이 튜토리얼 레슨에서는 이를 달성하는 두 가지 방법을 살펴보겠습니다.

관리자에게 알림 이메일을 보내는 GraphQL 쿼리

이 GraphQL 쿼리는 관리자 사용자에게 이메일을 보내어 사이트에 새 게시물이 생성되었음을 알립니다.

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

이메일을 일반 텍스트로 보내려면:

  • _sendEmail 뮤테이션에서 입력 messageAs: { text: ... } 를 사용하세요
  • PHP Functions via Schema 확장 기능이 제공하는 글로벌 필드 _htmlStripTags 를 사용하여 게시물 콘텐츠에서 HTML 태그를 제거하세요

다음으로 GraphQL 쿼리의 실행을 트리거하는 방법을 살펴보겠습니다.

옵션 1: WordPress 훅에 반응하여 항상 트리거하기

WordPress 코어 액션 new_to_publish 에 훅하여 새로 생성된 게시물의 데이터를 가져오고, Internal GraphQL Server 확장 기능이 제공하는 내부 GraphQL 서버에 대해 위에서 정의한 GraphQL 쿼리를 실행합니다.

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

클래스 GatoGraphQL\InternalGraphQLServer\GraphQLServer 는 외부 API로 접근할 수 없습니다. 대신, PHP 코드를 통해 애플리케이션이 사용하며, GraphQL 쿼리를 통해 관리 작업을 실행하고 자동화하기 위한 것입니다.

이 클래스는 쿼리를 실행하기 위한 3가지 정적 메서드를 제공합니다.

  • executeQuery: GraphQL 쿼리를 실행합니다
  • executeQueryInFile: (.gql) 파일에 포함된 GraphQL 쿼리를 실행합니다
  • executePersistedQuery: 퍼시스티드 GraphQL 쿼리를 실행합니다 (ID를 int로, 또는 슬러그를 string으로 제공)

이 GraphQL 쿼리는 새 게시물이 생성될 때마다 실행됩니다. 더 정확하게는, WordPress 함수 wp_insert_post 가 호출될 때마다 실행됩니다 (이 함수가 훅 new_to_publish 를 트리거하기 때문입니다):

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

이는 createPost 뮤테이션을 실행하는 다른 GraphQL 쿼리를 실행하는 경우에도 마찬가지입니다 (그 리졸버가 PHP 코드에서 함수 wp_insert_post 를 호출하기 때문입니다):

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

GraphQL 서버 (HTTP를 통해 API로 접근하는 "외부" 서버)와 Internal GraphQL 서버는 실행이 서로 얽혀 있는 경우에도 각자의 Schema Configuration을 적용하여 쿼리를 실행합니다.

예를 들어, 단일 엔드포인트에 대해 GraphQL 쿼리를 실행하고 있으며, 그것이 createPost 뮤테이션을 실행하여 게시물을 생성한다고 가정해 보겠습니다. 이때 다음과 같은 일련의 단계가 발생합니다.

(외부) GraphQL ServerInternal GraphQL Server
단일 엔드포인트에 대해 GraphQL 쿼리를 실행하고 자체 Schema Configuration을 사용(비활성)
게시물을 생성하고 new_to_publish 를 트리거(비활성)
(대기 중...)new_to_publish 훅에 반응: Internal GraphQL 서버를 시작하고 자체 Schema Configuration을 사용
(대기 중...)이메일 발송 쿼리를 실행
(대기 중...)이메일을 발송하고 해당 쿼리 종료
(대기 중...)서버 종료
쿼리 실행을 계속하고 해당 쿼리 종료(비활성)
서버 종료(비활성)

옵션 2: GraphQL 쿼리를 체이닝하여 트리거하기

Automation 확장 기능은 GraphQL 서버가 GraphQL 쿼리의 실행을 완료한 후 훅을 트리거하도록 합니다. 이를 통해 GraphQL 쿼리를 체이닝할 수 있습니다.

이 PHP 코드는 GraphQL 서버가 CreatePost 오퍼레이션을 가진 다른 쿼리 (위에서 정의한 GraphQL 쿼리)를 실행한 후, SendEmail 오퍼레이션 (위에서 정의한 GraphQL 쿼리)을 실행합니다.

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

GraphQL 쿼리를 체이닝하면 많은 리소스가 뮤테이션된 경우에도 단 하나의 쿼리만 실행할 수 있습니다.

예를 들어, 이 GraphQL 쿼리는 많은 게시물을 업데이트합니다.

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

전략에 따라 하나 또는 여러 개의 추가 GraphQL 쿼리 실행을 트리거할 수 있습니다.

훅하는 대상...트리거되는 GraphQL 쿼리의 수...
post_updated (WordPress 코어에 의해)업데이트된 게시물마다 하나씩
gatographql__executed_query:ReplaceDomains (Automation 확장 기능에 의해)총 하나 (업데이트된 모든 게시물의 데이터를 받음)