Hướng dẫn schema
Hướng dẫn schemaBài 14: Gửi email một cách thích thú

Bài 14: Gửi email một cách thích thú

Bài học hướng dẫn này trình bày nhiều khả năng của Gato GraphQL để gửi email.

Gửi email

Chúng ta gửi email thông qua mutation _sendEmail được cung cấp bởi tiện ích Email Sender.

  • Email được gửi với loại nội dung "text" hoặc "HTML" tùy thuộc vào thuộc tính nào của input messageAs được sử dụng
  • Input from là tùy chọn; nếu không được cung cấp, các cài đặt được lưu trong WordPress sẽ được sử dụng
  • _sendEmail thực thi hàm WordPress wp_mail, vì vậy nó sẽ sử dụng cấu hình được định nghĩa để gửi email trong WordPress (chẳng hạn như nhà cung cấp SMTP được sử dụng)
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
      }
    }
  }
}

Soạn email bằng Markdown

Trường _strConvertMarkdownToHTML từ tiện ích Helper Function Collection chuyển đổi Markdown sang HTML.

Chúng ta có thể sử dụng trường này để soạn email bằng 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
      }
    }
  }
}

Chèn dữ liệu động vào email

Sử dụng các trường hàm được cung cấp bởi PHP Functions via Schema, chúng ta có thể tạo một mẫu tin nhắn chứa các placeholder và thay thế chúng bằng dữ liệu động:

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
  }
}

Gửi email thông báo cho quản trị viên

Chúng ta có thể lấy email của người dùng quản trị viên từ bảng wp_options của WordPress và chèn giá trị này vào trường 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
  }
}

Ngoài ra, nếu Nested Mutations được bật trong Schema Configuration, chúng ta có thể lấy email quản trị viên ngay trong thao tác mutation (và chèn nó vào mutation thông qua 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
  }
}

Gửi email cá nhân hóa cho người dùng

Để queries GraphQL này hoạt động, Schema Configuration được áp dụng cho endpoint cần có Nested Mutations được bật

_sendEmail là một trường toàn cục (hay chính xác hơn là một mutation toàn cục), nó có thể được thực thi trên bất kỳ kiểu nào từ schema GraphQL, bao gồm cả User.

Queries này lấy danh sách người dùng, thu thập dữ liệu của họ (tên, email và số tín dụng còn lại được lưu trữ dưới dạng meta), và gửi email cá nhân hóa cho từng người:

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
        }
      }
    }
  }
}