บทช่วยสอน Schema
บทช่วยสอน Schemaบทเรียนที่ 14: ส่งอีเมลอย่างมีความสุข

บทเรียนที่ 14: ส่งอีเมลอย่างมีความสุข

บทเรียนนี้สาธิตความสามารถหลายอย่างของ Gato GraphQL ในการส่งอีเมล

การส่งอีเมล

เราส่งอีเมลผ่าน mutation _sendEmail ที่จัดเตรียมโดยเอกซ์เทนชัน Email Sender

  • อีเมลจะถูกส่งด้วยประเภทเนื้อหา "text" หรือ "HTML" ขึ้นอยู่กับว่าใช้พร็อพเพอร์ตีใดจากอินพุต messageAs
  • อินพุต from เป็นทางเลือก หากไม่ได้ระบุไว้ จะใช้การตั้งค่าที่จัดเก็บไว้ใน WordPress
  • _sendEmail เรียกใช้ฟังก์ชัน wp_mail ของ WordPress ดังนั้นจึงใช้การกำหนดค่าที่ตั้งไว้สำหรับการส่งอีเมลใน WordPress (เช่น ผู้ให้บริการ SMTP ที่จะใช้)
mutation {
  sendTextEmail: _sendEmail(
    input: {
      from: {
        email: "from@email.com"
        name: "Me myself"
      }
      replyTo: "replyTo@email.com"
 
      to: "target@email.com"
      cc: ["cc1@email.com", "cc2@email.com"]
      bcc: ["bcc1@email.com", "bcc2@email.com", "bcc3@email.com"]
      
      subject: "Email with text content"
      messageAs: {
        text: "Hello world!"
      }
    }
  ) {
    status
    errors {
      __typename
      ...on ErrorPayload {
        message
      }
    }
  }
  
  sendHTMLEmail: _sendEmail(
    input: {
      to: "target@email.com"
      subject: "Email with HTML content"
      messageAs: {
        html: "<p>Hello world!</p>"
      }
    }
  ) {
    status
    errors {
      __typename
      ...on ErrorPayload {
        message
      }
    }
  }
}

การเขียนอีเมลด้วย Markdown

ฟิลด์ _strConvertMarkdownToHTML จากเอกซ์เทนชัน Helper Function Collection แปลง Markdown เป็น HTML

เราสามารถใช้ฟิลด์นี้เพื่อเขียนอีเมลด้วย Markdown ได้:

query GetEmailData {
  emailMessage: _strConvertMarkdownToHTML(
    text: """
 
We have great news: **Version 1.0 of our plugin will be released soon!**
 
If you'd like to help us beta test it, please complete [this form](https://forms.gle/FpXNromWAsZYC1zB8).
 
_Please reply by 30th June 🙏_
 
Thanks!
 
    """
  )
    @export(as: "emailMessage")
}
 
mutation SendEmail @depends(on: "GetEmailData") {
  _sendEmail(
    input: {
      to: "target@email.com"
      subject: "Great news!"
      messageAs: {
        html: $emailMessage
      }
    }
  ) {
    status
    errors {
      __typename
      ...on ErrorPayload {
        message
      }
    }
  }
}

การฉีดข้อมูลแบบไดนามิกเข้าไปในอีเมล

ด้วยฟิลด์ฟังก์ชันที่จัดเตรียมโดย PHP Functions via Schema เราสามารถสร้างเทมเพลตข้อความที่มีพเลซโฮลเดอร์ และแทนที่ด้วยข้อมูลแบบไดนามิกได้:

query GetPostData($postID: ID!) {
  post(by: {id: $postID}) {
    title @export(as: "postTitle")
    excerpt @export(as: "postExcerpt")
    url @export(as: "postLink")
    author {
      name @export(as: "postAuthorName")
      url @export(as: "postAuthorLink")
    }
  }
}
 
query GetEmailData @depends(on: "GetPostData") {
  emailMessageTemplate: _strConvertMarkdownToHTML(
    text: """
 
There is a new post by [{$postAuthorName}]({$postAuthorLink}):
 
**{$postTitle}**: {$postExcerpt}
 
[Read online]({$postLink})
 
    """
  )
  emailMessage: _strReplaceMultiple(
    search: ["{$postAuthorName}", "{$postAuthorLink}", "{$postTitle}", "{$postExcerpt}", "{$postLink}"],
    replaceWith: [$postAuthorName, $postAuthorLink, $postTitle, $postExcerpt, $postLink],
    in: $__emailMessageTemplate
  )
    @export(as: "emailMessage")
  subject: _sprintf(string: "New post created by %s", values: [$postAuthorName])
    @export(as: "emailSubject")
}
 
mutation SendEmail @depends(on: "GetEmailData") {
  _sendEmail(
    input: {
      to: "target@email.com"
      subject: $emailSubject
      messageAs: {
        html: $emailMessage
      }
    }
  ) {
    status
  }
}

การส่งอีเมลแจ้งเตือนไปยังผู้ดูแลระบบ

เราสามารถดึงอีเมลของผู้ใช้ที่เป็นผู้ดูแลระบบจากตาราง wp_options ของ WordPress และฉีดค่านี้เข้าไปในฟิลด์ to ได้:

query ExportData {
  adminEmail: optionValue(name: "admin_email")
    @export(as: "adminEmail")
}
 
mutation SendEmail @depends(on: "ExportData") {
  _sendEmail(
    input: {
      to: $adminEmail
      subject: "Admin notification"
      messageAs: {
        html: "There is a new post on the site, go check!"
      }
    }
  ) {
    status
  }
}

อีกทางหนึ่ง หาก Nested Mutations ถูกเปิดใช้งานใน Schema Configuration เราสามารถดึงอีเมลของผู้ดูแลระบบภายในการดำเนินการ mutation ได้ทันที (และฉีดเข้าไปในมิวเทชันผ่าน Field to Input):

mutation SendEmail {
  adminEmail: optionValue(name: "admin_email")
  _sendEmail(
    input: {
      to: $__adminEmail
      subject: "Admin notification"
      messageAs: {
        html: "There is a new post on the site, go check!"
      }
    }
  ) {
    status
  }
}

การส่งอีเมลแบบเฉพาะบุคคลไปยังผู้ใช้

เพื่อให้ GraphQL query นี้ทำงานได้ Schema Configuration ที่นำไปใช้กับเอนด์พอยต์จำเป็นต้องเปิดใช้งาน Nested Mutations

เนื่องจาก _sendEmail เป็นฟิลด์ระดับโกลบอล (หรือพูดให้ชัดกว่านั้นคือมิวเทชันระดับโกลบอล) จึงสามารถเรียกใช้กับ type ใดก็ได้จาก GraphQL schema รวมถึง User

query นี้ดึงรายการผู้ใช้ ดึงข้อมูลของพวกเขา (ชื่อ อีเมล และจำนวนเครดิตที่เหลือ ซึ่งจัดเก็บไว้เป็น meta) และส่งอีเมลแบบเฉพาะบุคคลไปยังผู้ใช้แต่ละคน:

mutation {
  users {
    email
    displayName
    credits: metaValue(key: "credits")
    
    # If the user does not have meta entry "credits", use `0` credits
    hasNoCreditsEntry: _isNull(value: $__credits)
    remainingCredits: _if(condition: $__hasNoCreditsEntry, then: 0, else: $__credits)
 
    emailMessageTemplate: _strConvertMarkdownToHTML(
      text: """
 
Hello %s,
 
Your have **%s remaining credits** in your account.
 
Would you like to [buy more](%s)?
 
      """
    )
    emailMessage: _sprintf(
      string: $__emailMessageTemplate,
      values: [
        $__displayName,
        $__remainingCredits,
        "https://mysite.com/buy-credits"
      ]
    )
 
    _sendEmail(
      input: {
        to: $__email
        subject: "Remaining credits alert"
        messageAs: {
          html: $__emailMessage
        }
      }
    ) {
      status
      errors {
        __typename
        ...on ErrorPayload {
          message
        }
      }
    }
  }
}