บล็อก

👨🏻‍🏫 GraphQL query สำหรับส่งผู้สมัครรับจดหมายข่าวจาก InstaWP ไปยัง Mailchimp โดยอัตโนมัติ

Leonardo Losoviz
โดย Leonardo Losoviz ·

(อ่านบทความบล็อก 🚀 การส่งผู้สมัครรับจดหมายข่าวจาก InstaWP ไปยัง Mailchimp โดยอัตโนมัติ เพื่อดูบริบทของ query นี้)

GraphQL query นี้จะดักจับอีเมลของผู้เยี่ยมชมที่ติ๊กช่องทำเครื่องหมาย "Subscribe to mailing list" บน InstaWP (เมื่อสร้างไซต์แซนด์บ็อกซ์ใหม่) และสมัครอีเมลนั้นเข้าสู่รายชื่อ Mailchimp:

query HasSubscribedToNewsletter {
  hasSubscriberOptIn: _httpRequestHasParam(name: "marketing_optin")
  subscriberOptIn: _httpRequestStringParam(name: "marketing_optin")
  isNotSubscriberOptInNAValue: _notEquals(value1: $__subscriberOptIn, value2: "NA")
  subscribedToNewsletter: _and(values: [$__hasSubscriberOptIn, $__isNotSubscriberOptInNAValue])
    @export(as: "subscribedToNewsletter")
}
 
query MaybeCreateContactOnMailchimp
   @depends(on: "HasSubscribedToNewsletter")
   @include(if: $subscribedToNewsletter)
{
  subscriberEmail: _httpRequestStringParam(name: "email")
  
  mailchimpUsername: _env(name: "MAILCHIMP_API_CREDENTIALS_USERNAME")
    @remove
  mailchimpPassword: _env(name: "MAILCHIMP_API_CREDENTIALS_PASSWORD")
    @remove
  
  mailchimpListMembersJSONObject: _sendJSONObjectItemHTTPRequest(input: {
    url: "https://us7.api.mailchimp.com/3.0/lists/{listCode}/members",
    method: POST,
    options: {
      auth: {
        username: $__mailchimpUsername,
        password: $__mailchimpPassword
      },
      json: {
        email_address: $__subscriberEmail,
        status: "subscribed"
      }
    }
  })
}

หรืออีกทางเลือกหนึ่ง คุณสามารถลงทะเบียนผู้สมัครในปลั๊กอิน WordPress newsletter plugin ของคุณได้เช่นกัน (เช่น Noptin หรือปลั๊กอินอื่นๆ)

มาดูกันว่า GraphQL query นี้ทำงานอย่างไร

การแบ่ง GraphQL query ออกเป็นหน่วยอิสระ

เอกสาร GraphQL สามารถมีหลาย operation (queries และ mutations) ได้ แต่จะมีเพียงหนึ่งรายการเท่านั้นที่จะถูกเรียกใช้งาน เราระบุรายการที่ต้องการผ่านพารามิเตอร์ ?operationName=... บน GraphQL endpoint หากไม่ระบุ operation สุดท้ายจะถูกเรียกใช้งาน

สังเกตว่าในเอกสารข้างต้นมี query operation อยู่ 2 รายการ:

  1. HasSubscribedToNewsletter
  2. MaybeCreateContactOnMailchimp

URL ของ webhook มี ?operationName=MaybeCreateContactOnMailchimp ดังนั้น operation นั้นจะถูกเรียกใช้งาน

ด้วยความช่วยเหลือของ extension Multiple Query Execution MaybeCreateContactOnMailchimp จะเรียกใช้ HasSubscribedToNewsletter ก่อน ตามที่ระบุผ่าน directive @depends:

query MaybeCreateContactOnMailchimp
   @depends(on: "HasSubscribedToNewsletter")
   # ...
{
  #
}

นอกจากนี้ MaybeCreateContactOnMailchimp จะถูกเรียกใช้งานแบบมีเงื่อนไข เฉพาะเมื่อค่าของตัวแปร $subscribedToNewsletter เป็น true เท่านั้น:

query MaybeCreateContactOnMailchimp
   @depends(on: "HasSubscribedToNewsletter")
   @include(if: $subscribedToNewsletter)
{
  #
}

$subscribedToNewsletter คือ dynamic variable ที่ถูก export ภายใน operation HasSubscribedToNewsletter:

query HasSubscribedToNewsletter {
  # ...
  subscribedToNewsletter: _and(values: [$__hasSubscriberOptIn, $__isNotSubscriberOptInNAValue])
    @export(as: "subscribedToNewsletter")
}

ดังนั้น operation MaybeCreateContactOnMailchimp จะถูกเรียกใช้งานก็ต่อเมื่อผู้ใช้ติ๊กช่องทำเครื่องหมาย "Subscribe to mailing list" เท่านั้น

การคำนวณว่าผู้ใช้ติ๊กช่องทำเครื่องหมายหรือไม่

เอกสาร webhook ของ InstaWP ระบุว่าข้อมูล payload มีฟิลด์ต่อไปนี้ (รวมถึงฟิลด์อื่นๆ):

  • marketing_optin: ระบุว่าผู้ใช้ติ๊กช่องทำเครื่องหมายหรือไม่
  • email: อีเมลของผู้เยี่ยมชม

เอกสารอธิบายเพียงว่าฟิลด์ marketing_optin มีค่า NA เมื่อไม่ได้ติ๊กช่องทำเครื่องหมาย ดังนั้นเราต้องทำงานกับเงื่อนไขนั้น

ในการตรวจสอบว่าผู้ใช้ติ๊กช่องทำเครื่องหมายหรือไม่ ตรรกะคือ:

  • ตรวจสอบว่าฟิลด์ marketing_optin มีอยู่ และ
  • ตรวจสอบว่าค่าของฟิลด์ไม่ใช่ NA

สิ่งนี้ถูกคำนวณใน operation HasSubscribedToNewsletter นี่คือ operation พร้อม comment อธิบายว่าแต่ละบรรทัดใน query ทำอะไร:

query HasSubscribedToNewsletter {
 
  # Check if field `marketing_optin` is present
  hasSubscriberOptIn: _httpRequestHasParam(name: "marketing_optin")
 
  # Get the value of field `marketing_optin`
  subscriberOptIn: _httpRequestStringParam(name: "marketing_optin")
 
  # Check if the value of the field is not "NA"
  isNotSubscriberOptInNAValue: _notEquals(value1: $__subscriberOptIn, value2: "NA")
 
  # Perform an AND operation: field present && value != "NA"
  subscribedToNewsletter: _and(values: [$__hasSubscriberOptIn, $__isNotSubscriberOptInNAValue])
    
    # Export the result under dynamic variable $subscribedToNewsletter
    @export(as: "subscribedToNewsletter")
}

มีสิ่งที่น่าสนใจหลายอย่างใน query นี้

Global Fields

คุณสังเกตเห็นฟิลด์ที่ขึ้นต้นด้วย _ หรือไม่? ได้แก่:

  • _httpRequestHasParam
  • _httpRequestStringParam
  • _notEquals
  • _and

สิ่งเหล่านี้คือ global fields ซึ่งเป็นฟิลด์ที่พร้อมใช้งานภายใต้ทุก type ใน GraphQL schema global fields นำเสนอฟังก์ชันการทำงานแทนข้อมูล และตามแบบแผน จะขึ้นต้นด้วย _

Field to Input

คุณสังเกตเห็นตัวแปรที่ขึ้นต้นด้วย $__ หรือไม่? ได้แก่:

  • $__subscriberOptIn
  • $__hasSubscriberOptIn
  • $__isNotSubscriberOptInNAValue

สิ่งเหล่านี้คือ dynamic variables ที่เก็บค่าของฟิลด์ที่กำหนดไว้ก่อนหน้าในขอบเขตของ operation เดียวกัน ตัวอย่างเช่น ตัวแปร $__subscriberOptIn มีค่าของฟิลด์ subscriberOptIn ที่ประกาศไว้ก่อนหน้า

นี่คือฟีเจอร์ที่ extension Field to Input มอบให้ ซึ่งช่วยให้สามารถใช้ output ของฟิลด์เป็น input ของฟิลด์อื่นได้ นี่คือวิธีที่เราสามารถสร้างฟังก์ชันการทำงานภายใน GraphQL query ได้

ใน query นี้ ฟิลด์ isNotSubscriberOptInNAValue ตรวจสอบว่าค่าของฟิลด์ subscriberOptIn ที่ query ไว้ก่อนหน้าไม่เท่ากับ "NA" และ subscribedToNewsletter คำนวณ AND operation โดยใช้ค่าของฟิลด์ hasSubscriberOptIn และ isNotSubscriberOptInNAValue

การเชื่อมต่อกับ Mailchimp

Operation MaybeCreateContactOnMailchimp มีตรรกะสำหรับดึงข้อมูล payload และเรียก Mailchimp API เพื่อสมัครอีเมลเข้าสู่รายชื่อจดหมายข่าว

นี่คือ operation พร้อม comment อธิบายว่าแต่ละบรรทัดทำอะไร:

query MaybeCreateContactOnMailchimp
   @depends(on: "HasSubscribedToNewsletter")
   @include(if: $subscribedToNewsletter)
{
  # Extract form field `email` from the body of the request
  subscriberEmail: _httpRequestStringParam(name: "email")
  
  # Obtain Mailchimp credentials, defined in wp-config.php
  mailchimpUsername: _env(name: "MAILCHIMP_API_CREDENTIALS_USERNAME")
    # Do not print the credentials in the response
    @remove
  mailchimpPassword: _env(name: "MAILCHIMP_API_CREDENTIALS_PASSWORD")
    @remove
  
  # Connect to Mailchimp to add a new member to the list
  mailchimpListMembersJSONObject: _sendJSONObjectItemHTTPRequest(input: {
    url: "https://us7.api.mailchimp.com/3.0/lists/{listCode}/members",
    method: POST,
    options: {
      # Provide credentials to connect to the API
      auth: {
        username: $__mailchimpUsername,
        password: $__mailchimpPassword
      },
      # Provide form data
      json: {
        email_address: $__subscriberEmail,
        status: "subscribed"
      }
    }
  })
}

มาสำรวจฟีเจอร์ที่ใช้ใน query นี้กัน

Environment Variables

เราต้องระบุข้อมูลประจำตัวเมื่อเชื่อมต่อกับ Mailchimp API อย่างไรก็ตาม เราไม่ต้องการป้อนข้อมูลเหล่านี้โดยตรงใน GraphQL query เพราะอาจรั่วไหลไปที่ใดที่หนึ่ง (เช่น อาจถูกพิมพ์ในบางล็อก)

นั่นเป็นเหตุผลที่เราใช้ global field _env (ที่ extension PHP Constants and Environment via Schema มอบให้) เพื่ออ่าน environment variable หรือ PHP constant ร่วมกับ directive @remove (ที่ extension Field Response Removal มอบให้) เพื่อข้ามการพิมพ์ข้อมูลประจำตัวใน response

ตอนนี้ เราสามารถประกาศข้อมูลประจำตัวใน wp-config.php ได้:

define( 'MAILCHIMP_API_CREDENTIALS_USERNAME', '{ username }' );
define( 'MAILCHIMP_API_CREDENTIALS_PASSWORD', '{ password }' );

การส่ง HTTP request ไปยัง Mailchimp

ส่วนสุดท้ายของตรรกะคือฟิลด์ _sendJSONObjectItemHTTPRequest ซึ่งส่ง HTTP request ไปยังบริการใดๆ

เนื่องจากเราต้องการเชื่อมต่อกับ Mailchimp API ฟิลด์ mailchimpListMembersJSONObject จึงให้ข้อมูลที่ REST API endpoint ของ Mailchimp ต้องการ ตามที่ระบุไว้ในเอกสารเพื่อเพิ่มสมาชิกเข้าสู่รายชื่อ Mailchimp:

  • ส่ง POST request
  • Endpoint คือ https://{subdomain}.api.mailchimp.com/3.0/lists/{listCode}/members
  • Body ต้องมีฟิลด์ email_address และ status

การสร้าง webhook สำหรับโต้ตอบกับ API ใดๆ

GraphQL query ในบทความนี้ส่งต่อข้อมูลจาก InstaWP ไปยัง Mailchimp

คุณสามารถนำแนวคิดเดียวกันนี้ไปใช้กับการผสมผสานที่คุณต้องการ โดยดึงข้อมูลจากบริการต้นทาง (ไม่ว่าจะเป็นอะไร) ปรับแต่ง และส่งไปยังบริการปลายทาง (ไม่ว่าจะเป็นอะไร)

สนุกกับการใช้งาน!


สมัครรับจดหมายข่าวของเรา

ติดตามการอัปเดตทั้งหมดของ Gato GraphQL