การผสานอีเมล

คู่มือนี้จะอธิบายวิธีใช้ Google Docs API เพื่อผสานอีเมล

เกริ่นนำ

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

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

ชื่อ ที่อยู่ โซน
1 UrbanPq 123 ถนนเฟิร์สต์ ตะวันตก
2 พาวาซานา 456 สตรีต 2 ใต้

แอปตัวอย่างในหน้านี้จะแสดงวิธีที่คุณสามารถใช้ API ของ Google เอกสาร, ชีต และไดรฟ์เพื่อตัดรายละเอียดเกี่ยวกับการทำงานของการผสานอีเมล ซึ่งช่วยป้องกันไม่ให้ผู้ใช้กังวลในเรื่องการใช้งาน ดูข้อมูลเพิ่มเติมเกี่ยวกับตัวอย่าง Python นี้ได้ที่ที่เก็บ GitHub ของตัวอย่าง

แอปพลิเคชันตัวอย่าง

แอปตัวอย่างนี้คัดลอกเทมเพลตหลักของคุณ จากนั้นผสานตัวแปรจากแหล่งข้อมูลที่กำหนดลงในสำเนาแต่ละสำเนา หากต้องการลองใช้แอปตัวอย่างนี้ ให้ตั้งค่าเทมเพลตก่อน

  1. สร้างไฟล์เอกสาร เลือก เทมเพลตที่ต้องการใช้
  2. จดรหัสเอกสารของไฟล์ใหม่ไว้ ดูข้อมูลเพิ่มเติมได้ที่รหัสเอกสาร
  3. ตั้งค่าตัวแปร DOCS_FILE_ID เป็นรหัสเอกสาร
  4. แทนที่ข้อมูลติดต่อด้วยตัวแปรตัวยึดตำแหน่งเทมเพลตที่แอปจะผสานกับข้อมูลที่เลือกไว้

ต่อไปนี้เป็นเทมเพลตตัวอย่างจดหมายที่มีตัวยึดตำแหน่งที่สามารถผสานรวมกับข้อมูลจริงจากแหล่งที่มา เช่น ข้อความธรรมดาหรือชีต เทมเพลตมีลักษณะดังนี้

ถัดไป ให้เลือกข้อความธรรมดาหรือชีตเป็นแหล่งข้อมูลโดยใช้ตัวแปร SOURCE ตัวอย่างจะมีค่าเริ่มต้นเป็นข้อความธรรมดา ซึ่งหมายความว่าข้อมูลตัวอย่างใช้ตัวแปร TEXT_SOURCE_DATA หากต้องการดึงข้อมูลจากชีต ให้อัปเดตตัวแปร SOURCE เป็น 'sheets' แล้วชี้ไปยังชีตตัวอย่าง (หรือของคุณเอง) โดยตั้งค่าตัวแปร SHEETS_FILE_ID

นี่คือลักษณะของแผ่นงานที่คุณจะเห็นรูปแบบ

ลองใช้แอปที่มีข้อมูลตัวอย่างของเรา แล้วปรับให้เข้ากับข้อมูลและกรณีการใช้งานของคุณ แอปพลิเคชันบรรทัดคำสั่งมีการทำงานดังนี้

  • ตั้งค่า
  • ดึงข้อมูลจากแหล่งข้อมูล
  • วนซ้ำข้อมูลแต่ละแถว
    • สร้างสำเนาของเทมเพลต
    • ผสานสำเนากับข้อมูล
    • ลิงก์เอาต์พุตไปยังเอกสารที่ผสานใหม่

ตัวอักษรที่ผสานใหม่ทั้งหมดจะปรากฏใน "ไดรฟ์ของฉัน" ของผู้ใช้ด้วย ตัวอย่างของตัวอักษรที่ผสานจะมีลักษณะดังนี้

ซอร์สโค้ด

Python

docs/mail-merge/docs_mail_merge.py
import time

import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

# Fill-in IDs of your Docs template & any Sheets data source
DOCS_FILE_ID = "195j9eDD3ccgjQRttHhJPymLJUCOUjs-jmwTrekvdjFE"
SHEETS_FILE_ID = "11pPEzi1vCMNbdpqaQx4N43rKmxvZlgEHE9GqpYoEsWw"

# authorization constants

SCOPES = (  # iterable or space-delimited string
    "https://www.googleapis.com/auth/drive",
    "https://www.googleapis.com/auth/documents",
    "https://www.googleapis.com/auth/spreadsheets.readonly",
)

# application constants
SOURCES = ("text", "sheets")
SOURCE = "text"  # Choose one of the data SOURCES
COLUMNS = ["to_name", "to_title", "to_company", "to_address"]
TEXT_SOURCE_DATA = (
    (
        "Ms. Lara Brown",
        "Googler",
        "Google NYC",
        "111 8th Ave\nNew York, NY  10011-5201",
    ),
    (
        "Mr. Jeff Erson",
        "Googler",
        "Google NYC",
        "76 9th Ave\nNew York, NY  10011-4962",
    ),
)

# fill-in your data to merge into document template variables
merge = {
    # sender data
    "my_name": "Ayme A. Coder",
    "my_address": "1600 Amphitheatre Pkwy\nMountain View, CA  94043-1351",
    "my_email": "http://google.com",
    "my_phone": "+1-650-253-0000",
    # - - - - - - - - - - - - - - - - - - - - - - - - - -
    # recipient data (supplied by 'text' or 'sheets' data source)
    "to_name": None,
    "to_title": None,
    "to_company": None,
    "to_address": None,
    # - - - - - - - - - - - - - - - - - - - - - - - - - -
    "date": time.strftime("%Y %B %d"),
    # - - - - - - - - - - - - - - - - - - - - - - - - - -
    "body": (
        "Google, headquartered in Mountain View, unveiled the new "
        "Android phone at the Consumer Electronics Show. CEO Sundar "
        "Pichai said in his keynote that users love their new phones."
    ),
}

creds, _ = google.auth.default()
# pylint: disable=maybe-no-member

# service endpoints to Google APIs

DRIVE = build("drive", "v2", credentials=creds)
DOCS = build("docs", "v1", credentials=creds)
SHEETS = build("sheets", "v4", credentials=creds)


def get_data(source):
  """Gets mail merge data from chosen data source."""
  try:
    if source not in {"sheets", "text"}:
      raise ValueError(
          f"ERROR: unsupported source {source}; choose from {SOURCES}"
      )
    return SAFE_DISPATCH[source]()
  except HttpError as error:
    print(f"An error occurred: {error}")
    return error


def _get_text_data():
  """(private) Returns plain text data; can alter to read from CSV file."""
  return TEXT_SOURCE_DATA


def _get_sheets_data(service=SHEETS):
  """(private) Returns data from Google Sheets source. It gets all rows of
  'Sheet1' (the default Sheet in a new spreadsheet), but drops the first
  (header) row. Use any desired data range (in standard A1 notation).
  """
  return (
      service.spreadsheets()
      .values()
      .get(spreadsheetId=SHEETS_FILE_ID, range="Sheet1")
      .execute()
      .get("values")[1:]
  )
  # skip header row


# data source dispatch table [better alternative vs. eval()]
SAFE_DISPATCH = {k: globals().get(f"_get_{k}_data") for k in SOURCES}


def _copy_template(tmpl_id, source, service):
  """(private) Copies letter template document using Drive API then
  returns file ID of (new) copy.
  """
  try:
    body = {"name": f"Merged form letter ({source})"}
    return (
        service.files()
        .copy(body=body, fileId=tmpl_id, fields="id")
        .execute()
        .get("id")
    )
  except HttpError as error:
    print(f"An error occurred: {error}")
    return error


def merge_template(tmpl_id, source, service):
  """Copies template document and merges data into newly-minted copy then
  returns its file ID.
  """
  try:
    # copy template and set context data struct for merging template values
    copy_id = _copy_template(tmpl_id, source, service)
    context = merge.iteritems() if hasattr({}, "iteritems") else merge.items()

    # "search & replace" API requests for mail merge substitutions
    reqs = [
        {
            "replaceAllText": {
                "containsText": {
                    "text": "{{%s}}" % key.upper(),  # {{VARS}} are uppercase
                    "matchCase": True,
                },
                "replaceText": value,
            }
        }
        for key, value in context
    ]

    # send requests to Docs API to do actual merge
    DOCS.documents().batchUpdate(
        body={"requests": reqs}, documentId=copy_id, fields=""
    ).execute()
    return copy_id
  except HttpError as error:
    print(f"An error occurred: {error}")
    return error


if __name__ == "__main__":
  # get row data, then loop through & process each form letter
  data = get_data(SOURCE)  # get data from data source
  for i, row in enumerate(data):
    merge.update(dict(zip(COLUMNS, row)))
    print(
        "Merged letter %d: docs.google.com/document/d/%s/edit"
        % (i + 1, merge_template(DOCS_FILE_ID, SOURCE, DRIVE))
    )

ดูข้อมูลเพิ่มเติมได้ที่ไฟล์ README และซอร์สโค้ดของแอปพลิเคชันแบบเต็มที่ที่เก็บ GitHub ของแอปตัวอย่าง