๐ Hasilkan dan optimalkan gambar unggulan postingan menggunakan AI, dengan Gato GraphQL v2 yang baru
Kami dengan senang hati mengumumkan bahwa Gato GraphQL v2.0 kini telah dirilis!
Dengan versi baru ini, dan ekstensi PRO, Anda dapat menggunakan AI generatif untuk membuat gambar unggulan bagi postingan yang belum memiliki thumbnail.
Berikut adalah perubahan terpenting yang ditambahkan pada v2.0 (untuk melihat semua perubahan, kunjungi catatan rilis di GitHub).
Ditambahkan mutasi createMediaItem
Mutasi createMediaItem memungkinkan pengunggahan file ke Perpustakaan Media. Terdapat 2 cara untuk menyediakan file sumber:
- Melalui URL
- Langsung dengan kontennya
Menjalankan query ini:
mutation CreateMediaItems {
fromURL: createMediaItem(input: {
from: {
url: {
source: "https://gatographql.com/assets/GatoGraphQL-logo.png"
}
}
caption: "Gato GraphQL logo"
altText: "This is the Gato GraphQL logo"
}) {
mediaItemID
status
errors {
__typename
...on ErrorPayload {
message
}
}
mediaItem {
...MediaItemData
}
}
directlyByContents: createMediaItem(input: {
from: {
contents: {
body: """
<html>
<body>
Hello world!
</body>
</html>
"""
filename: "hello-world.html"
}
}
title: "Hello world!"
}) {
mediaItemID
status
errors {
__typename
...on ErrorPayload {
message
}
}
mediaItem {
...MediaItemData
}
}
}
fragment MediaItemData on Media {
altText
caption
mimeType
slug
src
title
}...akan menghasilkan:
{
"data": {
"fromURL": {
"mediaItemID": 1380,
"status": "SUCCESS",
"errors": null,
"mediaItem": {
"altText": "This is the Gato GraphQL logo",
"caption": "Gato GraphQL logo",
"mimeType": "image/png",
"slug": "gatographql-logo-png",
"src": "https://mysite.com/wp-content/uploads/GatoGraphQL-logo.png",
"title": "GatoGraphQL-logo.png"
}
},
"directlyByContents": {
"mediaItemID": 1381,
"status": "SUCCESS",
"errors": null,
"mediaItem": {
"altText": "",
"caption": "",
"mimeType": "text/html",
"slug": "hello-world-html",
"src": "https://mysite.com/wp-content/uploads/hello-world.html",
"title": "Hello world!"
}
}
}
}Ditambahkan field myMediaItemCount, myMediaItems dan myMediaItem
Pengguna yang sudah masuk kini dapat mengambil semua file media mereka.
Menjalankan query ini:
query GetMediaItems {
me {
slug
}
myMediaItemCount
myMediaItems(pagination: {
limit: 3
}) {
...MediaItemData
}
myMediaItem(by: { id: 1380 }) {
...MediaItemData
}
}
fragment MediaItemData on Media {
id
mimeType
src
author {
slug
}
}...akan menghasilkan:
{
"data": {
"me": {
"slug": "admin"
},
"myMediaItemCount": 2,
"myMediaItems": [
{
"id": 1380,
"mimeType": "image/png",
"src": "https://mysite.com/wp-content/uploads/GatoGraphQL-logo.png",
"author": {
"slug": "admin"
}
},
{
"id": 1365,
"mimeType": "image/png",
"src": "https://mysite.com/wp-content/uploads/browser.png",
"author": {
"slug": "admin"
}
}
],
"myMediaItem": {
"id": 1380,
"mimeType": "image/png",
"src": "https://mysite.com/wp-content/uploads/GatoGraphQL-logo.png",
"author": {
"slug": "admin"
}
}
}
}Ditambahkan persisted query bawaan "Generate a post's featured image using AI and optimize it"
(Fungsionalitas ini memerlukan ekstensi PRO.)
Persisted query bawaan baru, dengan judul "Generate a post's featured image using AI and optimize it", telah ditambahkan.
Fitur ini menggunakan AI generatif untuk membuat gambar bagi postingan yang belum memiliki gambar unggulan, menggunakan judul postingan sebagai prompt. Kita dapat memilih dari penyedia layanan berikut:
Query pertama-tama memeriksa apakah sebuah postingan memiliki gambar unggulan. Jika belum ada, query akan membuatnya dengan memanggil layanan AI generatif. Kita harus menyediakan API key yang sesuai untuk layanan yang dipilih.
Karena gambar AI generatif tidak dioptimalkan untuk web (gambar dari OpenAI bisa berbobot 3MB!), query juga mengirimkan gambar yang baru dihasilkan ke TinyPNG untuk dikompres. Kita harus menyediakan API key untuk menggunakan layanan ini.
Terakhir, query membuat item media baru dengan gambar tersebut (menggunakan judul postingan sebagai nama file untuk lampiran, dipotong hingga 20 karakter), dan menetapkannya sebagai gambar unggulan postingan.
Ini adalah query GraphQL-nya:
query InitializeVariables(
$openAIAPIKey: String
$stableDiffusionAPIKey: String
$tinyPngAPIKey: String
)
@configureWarningsOnExportingDuplicateVariable(enabled: false)
{
isFeaturedImageMissing: _echo(value: false)
@export(as: "isFeaturedImageMissing")
@remove
generatedImageURL: _echo(value: null)
@export(as: "generatedImageURL")
@remove
isImageGenerated: _echo(value: false)
@export(as: "isImageGenerated")
@remove
mimeType: _echo(value: null)
@export(as: "mimeType")
@remove
isMediaItemCreated: _echo(value: false)
@export(as: "isMediaItemCreated")
@remove
useOpenAI: _notEmpty(value: $openAIAPIKey)
@export(as: "useOpenAI")
@remove
useStableDiffusion: _notEmpty(value: $stableDiffusionAPIKey)
@export(as: "useStableDiffusion")
@remove
useTinyPng: _notEmpty(value: $tinyPngAPIKey)
@export(as: "useTinyPng")
@remove
}
query ExportPostData(
$postId: ID!
)
@depends(on: "InitializeVariables")
{
post(by: { id: $postId }) {
hasFeaturedImage
isFeaturedImageMissing: hasFeaturedImage
@boolOpposite
@export(as: "isFeaturedImageMissing")
title
@export(as: "postTitle")
mediaItemFilename: rawTitle
@default(value: "untitled", condition: IS_EMPTY)
@strLowerCase
@strSubstr(offset: 0, length: 20)
@export(as: "filename")
@remove
}
}
query MaybeGenerateImageUsingOpenAI(
$openAIAPIKey: String
$imageSize: String! = "1024x1024" # 256x256, 512x512, or 1024x1024 pixels
)
@depends(on: "ExportPostData")
@include(if: $isFeaturedImageMissing)
@include(if: $useOpenAI)
{
openAIResponse: _sendJSONObjectItemHTTPRequest(input: {
url: "https://api.openai.com/v1/images/generations",
method: POST,
options: {
auth: {
password: $openAIAPIKey
},
json: {
prompt: $postTitle,
size: $imageSize,
n: 1,
response_format: "url",
}
}
})
@underJSONObjectProperty(by: { key: "data" })
@underArrayItem(index: 0)
@underJSONObjectProperty(by: { key: "url" })
@export(as: "generatedImageURL")
openAPIImageCaption: _sprintf(
string: "Image created by DALL-E using prompt: '%s'",
values: [$postTitle]
)
@export(as: "imageCaption")
openAIMediaItemFilename: _sprintf(
string: "%s.png",
values: [$filename]
)
@export(as: "filename")
}
query MaybeGenerateImageUsingStableDiffusion(
$stableDiffusionAPIKey: String
$width: Int! = 1024
$height: Int! = 1024
)
@depends(on: "ExportPostData")
@include(if: $isFeaturedImageMissing)
@include(if: $useStableDiffusion)
{
stableDiffusionResponse: _sendJSONObjectItemHTTPRequest(input: {
url: "https://stablediffusionapi.com/api/v3/text2img",
method: POST,
options: {
json: {
key: $stableDiffusionAPIKey
prompt: $postTitle,
width: $width
height: $height
samples: 1
}
}
})
@underJSONObjectProperty(by: { key: "output" })
@underArrayItem(index: 0)
@export(as: "generatedImageURL")
stableDiffusionImageCaption: _sprintf(
string: "Image created by Stable Diffusion using prompt: '%s'",
values: [$postTitle]
)
@export(as: "imageCaption")
stableDiffusionMediaItemFilename: _sprintf(
string: "%s.png",
values: [$filename]
)
@export(as: "filename")
}
query CheckIsImageGenerated
@depends(on: [
"MaybeGenerateImageUsingOpenAI",
"MaybeGenerateImageUsingStableDiffusion"
])
@include(if: $isFeaturedImageMissing)
{
isImageGenerated: _notEmpty(value: $generatedImageURL)
@export(as: "isImageGenerated")
}
query MaybeCompressGeneratedImage(
$tinyPngAPIKey: String
)
@depends(on: "CheckIsImageGenerated")
@include(if: $isImageGenerated)
@include(if: $useTinyPng)
{
compressedImageResponse: _sendHTTPRequest(input: {
url: "https://api.tinify.com/shrink",
method: POST,
options: {
auth: {
password: $tinyPngAPIKey
},
headers: [
{
name: "Content-Type",
value: "application/json"
}
],
json: {
source: {
url: $generatedImageURL
}
}
}
}) {
body
@remove
bodyJSONObject: _strDecodeJSONObject(string: $__body)
mimeType: _objectProperty(
object: $__bodyJSONObject
by: { path: "output.type" }
)
@export(as: "mimeType")
generatedImageURL: header(name: "Location")
@export(as: "generatedImageURL")
}
}
mutation CreateMediaItemFromGeneratedImage
@depends(on: "MaybeCompressGeneratedImage")
@include(if: $isImageGenerated)
{
createMediaItem(input: {
from: {
url: {
source: $generatedImageURL
filename: $filename
}
}
title: $postTitle
caption: $imageCaption
altText: $postTitle
mimeType: $mimeType
}) {
mediaItemID
@export(as: "mediaItemID")
isMediaItemCreated: _notNull(value: $__mediaItemID)
@export(as: "isMediaItemCreated")
@remove
status
errors {
__typename
...on ErrorPayload {
message
}
}
mediaItem {
altText
caption
mimeType
slug
src
title
}
}
}
mutation SetMediaItemAsPostFeaturedImage(
$postId: ID!
)
@depends(on: "CreateMediaItemFromGeneratedImage")
@include(if: $isMediaItemCreated)
{
setFeaturedImageOnCustomPost(input: {
customPostID: $postId
mediaItemBy: { id: $mediaItemID }
}) {
status
errors {
__typename
...on ErrorPayload {
message
}
}
customPost {
__typename
...on CustomPost {
featuredImage {
id
altText
caption
mimeType
slug
src
title
}
}
}
}
}[PRO] Ditambahkan field _dataMatrixOutputAsCSV pada ekstensi Helper Function Collection
(Fungsionalitas ini ditambahkan ke ekstensi PRO.)
Field _dataMatrixOutputAsCSV telah ditambahkan ke ekstensi Helper Function Collection (dan semua bundle yang berisi ekstensi ini).
Field ini mengambil matriks data, dan menghasilkan string CSV. Misalnya, query ini:
csv: _dataMatrixOutputAsCSV(
fields:
["Name", "Surname", "Year"]
data: [
["John", "Smith", 2003],
["Pedro", "Gonzales", 2012],
["Manuel", "Perez", 2008],
["Jose", "Pereyra", 1999],
["Jacinto", "Bloomberg", 1998],
["Jun-E", "Song", 1983],
["Juan David", "Santamaria", 1943],
["Luis Miguel", null, 1966],
]
)...akan menghasilkan:
{
"data": {
"csv": "Name,Surname,Year\nJohn,Smith,2003\nPedro,Gonzales,2012\nManuel,Perez,2008\nJose,Pereyra,1999\nJacinto,Bloomberg,1998\nJun-E,Song,1983\nJuan David,Santamaria,1943\nLuis Miguel,,1966\n"
}
}Fungsionalitas ini memungkinkan kita untuk mengekspor data dari situs WordPress kita ke Google Sheets atau yang lainnya.
Misalnya, query ini akan mengambil data untuk 100 postingan, dan membuat file CSV yang diunggah ke Perpustakaan Media, dengan kolom ID, Title, Slug, Author name, Published date, URL, dan Content:
query ExportPostData(
$limit: Int! = 100,
$offset: Int! = 0
) {
posts(
pagination: { limit: $limit, offset: $offset },
sort: { by: ID, order: ASC }
) {
id @export(as: "postIds", type: LIST)
title @export(as: "postTitles", type: LIST)
slug @export(as: "postSlugs", type: LIST)
author {
name @export(as: "postAuthorNames", type: LIST)
}
dateStr(format: "d/m/Y") @export(as: "postPublishedDates", type: LIST)
url @export(as: "postUrls", type: LIST)
content @export(as: "postContents", type: LIST)
}
}
query CreateDataMatrix
@depends(on: "ExportPostData")
{
csvDataMatrix: _echo(value: $postIds)
@underEachArrayItem(
passIndexOnwardsAs: "key"
passValueOnwardsAs: "postId"
affectDirectivesUnderPos: [1, 2, 3, 4, 5, 6, 7]
)
@applyField(
name: "_arrayItem",
arguments: {
array: $postTitles,
position: $key,
},
passOnwardsAs: "postTitle"
)
@applyField(
name: "_arrayItem",
arguments: {
array: $postSlugs,
position: $key,
},
passOnwardsAs: "postSlug"
)
@applyField(
name: "_arrayItem",
arguments: {
array: $postAuthorNames,
position: $key,
},
passOnwardsAs: "postAuthorName"
)
@applyField(
name: "_arrayItem",
arguments: {
array: $postPublishedDates,
position: $key,
},
passOnwardsAs: "postPublishedDate"
)
@applyField(
name: "_arrayItem",
arguments: {
array: $postUrls,
position: $key,
},
passOnwardsAs: "postUrl"
)
@applyField(
name: "_arrayItem",
arguments: {
array: $postContents,
position: $key,
},
passOnwardsAs: "postContent"
)
@applyField(
name: "_echo",
arguments: {
value: [
$postId,
$postTitle,
$postSlug,
$postAuthorName,
$postPublishedDate,
$postUrl,
$postContent
]
},
setResultInResponse: true
)
@export(as: "csvDataMatrix")
}
query OutputCSV
@depends(on: "CreateDataMatrix")
{
csvString: _dataMatrixOutputAsCSV(
fields: [
"ID",
"Title",
"Slug",
"Author name",
"Published date",
"URL",
"Content",
]
data: $csvDataMatrix
)
@export(as: "csvString")
}
mutation CreateMediaItem
@depends(on: "OutputCSV")
{
createMediaItem(input: {
from: {
contents: {
body: $csvString
filename: "posts.csv"
}
}
title: "Post data as CSV"
}) {
mediaItemID
status
errors {
__typename
...on ErrorPayload {
message
}
}
mediaItem {
mimeType
slug
src
title
}
}
}Persiapan menuju v3.0
Kami berharap Anda menikmati fitur-fitur baru dalam rilis terbaru ini.
Apakah ada fitur baru yang ingin Anda lihat di Gato GraphQL berikutnya? Kirimkan pesan kepada kami dan beri tahu kami.
Selamat menikmati!