レッスン16:新しい投稿があった際に通知を送信する
Gato GraphQL は、新しい投稿があった際に管理者へ通知メールを送信するなど、アプリケーションのタスクを自動化するのに役立ちます。
このチュートリアルレッスンでは、これを実現する2つの方法を探ります。
管理者に通知メールを送信する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 coreのアクション 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 Server | Internal 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クエリをチェーンすることで、多くのリソースがミューテーションされた場合でも、実行するクエリを1つだけにすることができます。
例えば、この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
}
}
}戦略に応じて、1つまたは複数の追加GraphQLクエリの実行をトリガーできます。
| フックする対象... | トリガーされるGraphQLクエリの数... |
|---|---|
post_updated(WordPress coreによる) | 更新された投稿ごとに1つ |
gatographql__executed_query:ReplaceDomains(Automation 拡張機能による) | 合計1つ(更新されたすべての投稿のデータを受け取る) |