Ders 16: Yeni bir gönderi olduğunda bildirim gönderme
Gato GraphQL, uygulamada görevleri otomatikleştirmemize yardımcı olabilir; örneğin yeni bir gönderi olduğunda yöneticiye bildirim e-postası göndermek gibi.
Bu eğitim dersinde bunu başarmanın iki yolunu keşfedeceğiz.
Yöneticiye bildirim e-postası göndermek için GraphQL query
Bu GraphQL query, sitede yeni bir gönderi oluşturulduğunu yönetici kullanıcıya bildiren bir e-posta gönderir:
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
}
}E-postayı düz metin olarak göndermek için:
_sendEmailmutation'ındamessageAs: { text: ... }girdisini kullanın- PHP Functions via Schema eklentisinin sağladığı
_htmlStripTagsglobal alanını kullanarak gönderinin içeriğinden HTML etiketlerini kaldırın
Şimdi GraphQL query çalıştırmasının nasıl tetikleneceğini görelim.
Seçenek 1: WordPress hook'larına tepki vererek her zaman tetikleme
WordPress core new_to_publish eylemine bağlanır, yeni oluşturulan gönderinin verilerini alır ve yukarıda tanımlanan GraphQL query'yi dahili GraphQL sunucusuna karşı çalıştırırız (Internal GraphQL Server eklentisi aracılığıyla sağlanır):
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 sınıfı harici bir API olarak erişilebilir değildir. Bunun yerine, GraphQL queries aracılığıyla yönetici görevlerini yürütmek/otomatikleştirmek için uygulama tarafından PHP kodu üzerinden kullanılması amaçlanmıştır.
Bu sınıf, queries çalıştırmak için 3 statik yöntem sağlar:
executeQuery: Bir GraphQL query çalıştırırexecuteQueryInFile: Bir (.gql) dosyasında bulunan GraphQL query'yi çalıştırırexecutePersistedQuery: Kalıcı bir GraphQL query çalıştırır (ID'sini int olarak veya slug'ını string olarak sağlayarak)
Bu GraphQL query, yeni bir gönderi oluşturulduğunda veya daha doğrusu WordPress wp_insert_post fonksiyonu çağrıldığında her seferinde çalıştırılacaktır (bu fonksiyon new_to_publish hook'unu tetikler):
$postID = wp_insert_post([
'post_title' => 'Hello world!'
]);Bu durum, createPost mutation'ını çalıştıran başka bir GraphQL query çalıştırıldığında da geçerlidir (çünkü PHP kodundaki çözümleyici wp_insert_post fonksiyonunu çağırır):
mutation CreatePost {
createPost(input: {
title: "Hello world!"
}) {
status
postID
}
}GraphQL Server ("harici", HTTP üzerinden API olarak erişilen) ve Internal GraphQL Server, yürütmeleri iç içe geçmiş olsa bile kendi Schema Configuration'larını uygulayarak queries'lerini çalıştırır.
Örneğin, tek endpoint'e karşı bir GraphQL query çalıştırdığımızı ve bunun createPost mutation'ını çalıştırarak bir gönderi oluşturduğunu varsayalım. Ardından şu adım dizisi gerçekleşir:
| (Harici) GraphQL Server | Internal GraphQL Server |
|---|---|
| GraphQL query'yi tek endpoint'e karşı kendi Schema Configuration'ını kullanarak çalıştırır | (etkin değil) |
Bir gönderi oluşturur; bu new_to_publish hook'unu tetikler | (etkin değil) |
| (bekliyor...) | new_to_publish hook'una tepki verir: Internal GraphQL sunucusunu kendi Schema Configuration'ı ile başlatır |
| (bekliyor...) | E-posta göndermek için query'yi çalıştırır |
| (bekliyor...) | E-postayı gönderir, o query sona erer |
| (bekliyor...) | Sunucuyu kapatır |
| Query çalıştırmaya devam eder, o query sona erer | (etkin değil) |
| Sunucuyu kapatır | (etkin değil) |
Seçenek 2: GraphQL queries zincirleyerek tetikleme
Automation eklentisi, GraphQL Server'ın bir GraphQL query çalıştırmasını tamamladıktan sonra bir hook tetiklemesini sağlar. Bu, GraphQL queries'leri zincirleştirmemize olanak tanır.
Bu PHP kodu, GraphQL sunucusu CreatePost operasyonuyla başka bir query çalıştırdıktan sonra SendEmail operasyonunu (yukarıda tanımlanan GraphQL query) çalıştırır:
// 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 queries zincirlemek, birçok kaynak mutasyona uğramış olsa bile tek bir query çalıştırmamıza olanak tanır.
Örneğin, bu GraphQL query birçok gönderiyi günceller:
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
}
}
}Stratejimize bağlı olarak, bir veya birden fazla ek GraphQL query çalıştırmasını tetikleyebiliriz:
| Bağlandığımız yer... | Tetiklenen GraphQL query sayısı... |
|---|---|
post_updated (WordPress core tarafından) | Güncellenen her gönderi için bir tane |
gatographql__executed_query:ReplaceDomains (Automation eklentisi tarafından) | Toplamda bir tane (tüm güncellenmiş gönderilerin verilerini alır) |