Queries Library
Queries LibraryGenerate Yoast SEO metadata with ChatGPT

Generate Yoast SEO metadata with ChatGPT

This query is demonstrated in the Creating Yoast SEO metadata for MasterStudy LMS courses and lessons using ChatGPT demo.

This query generates and updates SEO metadata in Yoast for a post using ChatGPT.

The required variables are:

  • postId: The ID of the post (or custom post, for any of the accessible custom post types) to update
  • openAIAPIKey: The API key for the OpenAI API
query GetPostData($postId: ID!) {
  customPost(by: { id: $postId }) {
    id
    ...on CustomPost {
      title
        @export(as: "title")
      content
        @export(as: "content")
    }
    ...WithMetaData
  }
}
 
query GenerateSeoMetadataWithChatGPT(
  $openAIAPIKey: String!
  $systemMessage: String! = "You are an SEO specialist"
  $promptTemplate: String! = """
I'm working on creating the SEO metadata for courses and lessons in my Learning Management System.
 
Please evaluate the course or lesson data, and generate the following SEO metadata:
 
- Title
- Excerpt
- Focus Keyword
- Open Graph Title
- Open Graph Description
- Twitter Title
- Twitter Description
 
The data is:
 
- Title: {$title}
- Content: {$content}
"""
  $model: String! = "gpt-4o-mini"
)
  @depends(on: "GetPostData")
{
  prompt: _strReplaceMultiple(
    search: ["{$title}", "{$content}"],
    replaceWith: [$title, $content],
    in: $promptTemplate
  )
  openAIResponse: _sendJSONObjectItemHTTPRequest(input: {
    url: "https://api.openai.com/v1/chat/completions",
    method: POST,
    options: {
      auth: {
        password: $openAIAPIKey
      },
      json: {
        model: $model,
        messages: [
          {
            role: "system",
            content: $systemMessage
          },
          {
            role: "user",
            content: $__prompt
          },
        ],
        response_format: {
          type: "json_schema",
          json_schema: {
            name: "seo_metadata_response",
            strict: true,
            schema: {
              type: "object",
              properties: {
                seoMetadata: {
                  type: "object",
                  properties: {
                    title: {
                      type: "string"
                    },
                    excerpt: {
                      type: "string"
                    },
                    focusKeyword: {
                      type: "string"
                    },
                    openGraphTitle: {
                      type: "string"
                    },
                    openGraphDescription: {
                      type: "string"
                    },
                    twitterTitle: {
                      type: "string"
                    },
                    twitterDescription: {
                      type: "string"
                    }
                  },
                  required: ["title", "excerpt", "focusKeyword", "openGraphTitle", "openGraphDescription", "twitterTitle", "twitterDescription"],
                  additionalProperties: false
                }
              },
              required: ["seoMetadata"],
              additionalProperties: false
            }
          }
        }
      }
    }
  })
    @underJSONObjectProperty(by: { key: "choices" })
      @underArrayItem(index: 0)
        @underJSONObjectProperty(by: { path: "message.content" })
          @export(as: "jsonEncodedSeoMetadataResponse")
}
 
query ExtractSeoMetadata
  @depends(on: "GenerateSeoMetadataWithChatGPT")
{
  decodedSeoMetadataResponse: _strDecodeJSONObject(string: $jsonEncodedSeoMetadataResponse)
    @underJSONObjectProperty(by: { path: "seoMetadata" })
      @export(as: "seoMetadata")
}
 
mutation GenerateSeoMetadataAndUpdateYoast(
  $postId: ID!
)
  @depends(on: "ExtractSeoMetadata")
{
  seoMetadataTitle: _objectProperty(
    object: $seoMetadata,
    by: { key: "title" }
  )
  seoMetadataExcerpt: _objectProperty(
    object: $seoMetadata,
    by: { key: "excerpt" }
  )
  seoMetadataFocusKeyword: _objectProperty(
    object: $seoMetadata,
    by: { key: "focusKeyword" }
  )
  seoMetadataOpenGraphTitle: _objectProperty(
    object: $seoMetadata,
    by: { key: "openGraphTitle" }
  )
  seoMetadataOpenGraphDescription: _objectProperty(
    object: $seoMetadata,
    by: { key: "openGraphDescription" }
  )
  seoMetadataTwitterTitle: _objectProperty(
    object: $seoMetadata,
    by: { key: "twitterTitle" }
  )
  seoMetadataTwitterDescription: _objectProperty(
    object: $seoMetadata,
    by: { key: "twitterDescription" }
  )
 
  updateCustomPostMetas(inputs: [
    { id: $postId, key: "_yoast_wpseo_title", value: $__seoMetadataTitle },
    { id: $postId, key: "_yoast_wpseo_metadesc", value: $__seoMetadataExcerpt },
    { id: $postId, key: "_yoast_wpseo_focuskw", value: $__seoMetadataFocusKeyword },
    { id: $postId, key: "_yoast_wpseo_opengraph-title", value: $__seoMetadataOpenGraphTitle },
    { id: $postId, key: "_yoast_wpseo_opengraph-description", value: $__seoMetadataOpenGraphDescription },
    { id: $postId, key: "_yoast_wpseo_twitter-title", value: $__seoMetadataTwitterTitle },
    { id: $postId, key: "_yoast_wpseo_twitter-description", value: $__seoMetadataTwitterDescription }
  ]) {
    status
    errors {
      __typename
      ...on ErrorPayload {
        message
      }
    }
  }
}
 
query GenerateAndUpdatePostSeoMetadataAndCheckResults($postId: ID!)
  @depends(on: "GenerateSeoMetadataAndUpdateYoast")
{
  postResults: customPost(by: { id: $postId }) {
    id
    ...WithMetaData
  }
}
 
fragment WithMetaData on WithMeta {
  metaTitle: metaValue(key: "_yoast_wpseo_title")
  metaDesc: metaValue(key: "_yoast_wpseo_metadesc")
  focusKeyword: metaValue(key: "_yoast_wpseo_focuskw")
  socialFBTitle: metaValue(key: "_yoast_wpseo_opengraph-title")
  socialFBDesc: metaValue(key: "_yoast_wpseo_opengraph-description")
  socialTwitterTitle: metaValue(key: "_yoast_wpseo_twitter-title")
  socialTwitterDesc: metaValue(key: "_yoast_wpseo_twitter-description")
}

The variables would look like this:

{
  "postId": "123",
  "openAIAPIKey": "sk-..."
}