Twilio SendGrid: 宛先追加/更新

Twilio SendGrid: 宛先追加/更新

Twilio SendGrid: Add or Update Contact

この工程は、SendGrid の宛先を追加または更新します。指定したメールアドレスの宛先がすでにある場合、その宛先が更新されます。

Basic Configs
工程名
メモ
Auto Step icon
Configs for this Auto Step
conf_Auth
C1: API キーをトークンとして設定した認証設定 *
conf_Email
C2: メールアドレス *
conf_ListIds
C3: 宛先を追加するリストの ID(文字型データ項目の場合、1 行に 1 つ)
conf_AlternateEmails
C4: 代替メールアドレス(1 行に 1 つ、最大 5 件)
conf_LastName
C5: 姓
conf_FirstName
C6: 名
conf_Country
C7: 国
conf_PostalCode
C8: 郵便番号
conf_Region
C9: 都道府県
conf_City
C10: 市区町村
conf_Address1
C11: 住所 1 行目
conf_Address2
C12: 住所 2 行目

Notes

  • リスト ID は、URL に含まれています
    • mc.sendgrid.com/contacts/lists/(リスト ID)

Capture

See Also

Script (click to open)
  • 次のスクリプトが記述されている XML ファイルをダウンロードできます
    • sendgrid-contact-upsert.xml (C) Questetra, Inc. (MIT License)
    • Professional のワークフロー基盤では、ファイル内容を改変しオリジナルのアドオン自動工程として活用できます


const MAX_EMAIL_LENGTH = 254;
const MAX_ALTERNATE_EMAIL_NUM = 5;
const MAX_NAME_LENGTH = 50;
const MAX_POSTAL_CODE_LENGTH = 60; // API ドキュメントに記載がないが、試したところ 60 文字だった
const MAX_CITY_LENGTH = 60;
const MAX_FIELD_VALUE_LENGTH = 1000;

function main(){
    //// == Config Retrieving / 工程コンフィグの参照 ==
    const auth = configs.get('conf_Auth');
    const listIds = retrieveListIds();
    const contact = retrieveContact();

    //// == Calculating / 演算 ==
    const jobId = upsertContact(auth, listIds, contact);

    // 処理状況を確認し、未完了なら proceed() に進む
    if (checkStatus(auth, jobId) === false) {
        engine.saveTemporaryData(jobId);
        return false;
    }
}

function proceed() {
    //// == Config Retrieving / 工程コンフィグの参照 ==
    const auth = configs.get('conf_Auth');

    //// == Restoring Temporary Data / 一時データの読み出し ==
    const jobId = engine.restoreTemporaryData();
    if (jobId === null) {
        throw 'Temporary data has not been saved.';
    }

    //// == 演算 / Calculating ==
    if (checkStatus(auth, jobId) === false) {
        return false;
    }
}

/**
  * config に設定されたリスト ID 一覧を読み出す
  * - データ項目が設定されていない場合、null を返す(更新対象から除外するため)
  * - データ項目が設定されていて値が空の場合、空のリストを返す(空の値で更新するため)
  * @return {Array<String>} listIds
  */
function retrieveListIds() {
    const listIdsDef = configs.getObject('conf_ListIds');
    if (listIdsDef === null) {
        return null;
    }
    if (listIdsDef.matchDataType('STRING')) {
        const listIdsStr = engine.findData(listIdsDef);
        if (listIdsStr === null) {
            return [];
        }
        const listIds = listIdsStr.split('\n')
            .filter(id => id !== '');
        // API ドキュメントに List ID 上限数の記載なしのため、上限数はチェックしない
        return listIds;
    }
    if (listIdsDef.matchDataType('SELECT')) {
        const listIdItems = engine.findData(listIdsDef); // List<ItemView>
        if (listIdItems === null || listIdItems.size() === 0) {
            return [];
        }
        // 選択肢 ID のリストを返す
        const listIds = [];
        listIdItems.forEach(item => {
            listIds.push(item.getValue()); // 選択肢 ID を格納
        });
        return listIds;
    }
}

/**
  * config に設定された宛先情報を、API リクエストボディに設定する形式で読み出す
  * ただし、データ項目が設定されていない項目は含めない(更新の場合に、更新対象から除外するため)
  * @return {Object} contact
  * @return {String} contact.email
  * @return {Array<String>} contact.alternate_emails
  * @return {String} contact.last_name
  * @return {String} contact.first_name
  * @return {String} contact.country
  * @return {String} contact.postal_code
  * @return {String} contact.state_province_region
  * @return {String} contact.city
  * @return {String} contact.address_line_1
  * @return {String} contact.address_line_2
  */
function retrieveContact() {
    const email = retrieveConfig('conf_Email', true, MAX_EMAIL_LENGTH, 'Email Address');
    const alternateEmails = retrieveAlternateEmails();
    const lastName = retrieveConfig('conf_LastName', false, MAX_NAME_LENGTH, 'Last Name');
    const firstName = retrieveConfig('conf_FirstName', false, MAX_NAME_LENGTH, 'First Name');
    const country = retrieveConfig('conf_Country', false, MAX_NAME_LENGTH, 'Country');
    const postalCode = retrieveConfig('conf_PostalCode', false, MAX_POSTAL_CODE_LENGTH, 'Postal Code');
    const region = retrieveConfig('conf_Region', false, MAX_NAME_LENGTH, 'Region');
    const city = retrieveConfig('conf_City', false, MAX_CITY_LENGTH, 'City');
    const address1 = retrieveConfig('conf_Address1', false, MAX_FIELD_VALUE_LENGTH, 'Address 1st Line');
    const address2 = retrieveConfig('conf_Address2', false, MAX_FIELD_VALUE_LENGTH, 'Address 2nd Line');

    const contact = {
        email,
        alternate_emails: alternateEmails,
        last_name: lastName,
        first_name: firstName,
        country,
        postal_code: postalCode,
        state_province_region: region,
        city,
        address_line_1: address1,
        address_line_2: address2
    };

    // 値が null のものを削除
    Object.keys(contact).forEach(key => {
        if (contact[key] === null) {
            delete contact[key];
        }
    });

    return contact;
}

/**
  * config に設定された文字型データ項目の値を読み出す
  * required が false で
  * - データ項目が設定されていない場合、null を返す(更新対象から除外するため)
  * - データ項目が設定されていて値が空の場合、空の文字列を返す(空の値で更新するため)
  * @param {String} confName 設定項目名
  * @param {boolean} required 必須項目かどうか
  * @param {Number} maxLength 最大文字数
  * @param {String} label エラー出力用ラベル
  * @return {String} value
  */
function retrieveConfig(confName, required, maxLength, label) {
    const dataDef = configs.getObject(confName);
    if (dataDef === null) { // required が true の場合、dataDef は null にならない
        return null;
    }
    const value = engine.findData(dataDef);
    if (value === null) {
        if (required) {
            throw `${label} is blank.`;
        }
        return '';
    }
    if (value.length > maxLength) {
        throw `${label} must be within ${maxLength} characters.`;
    }
    return value;
}

/**
  * config に設定された代替メールアドレスの一覧を読み出す
  * - データ項目が設定されていない場合、null を返す(更新対象から除外するため)
  * - データ項目が設定されていて値が空の場合、空のリストを返す(空の値で更新するため)
  * @return {Array<String>} alternateEmails
  */
function retrieveAlternateEmails() {
    const alternateEmailsDef = configs.getObject('conf_AlternateEmails');
    if (alternateEmailsDef === null) {
        return null;
    }
    const alternateEmailsStr = engine.findData(alternateEmailsDef);
    if (alternateEmailsStr === null) {
        return [];
    }
    const alternateEmails = alternateEmailsStr.split('\n')
        .filter(email => email !== '');
    if (alternateEmails.length > MAX_ALTERNATE_EMAIL_NUM) {
        throw `The maximum number of alternate emails is ${MAX_ALTERNATE_EMAIL_NUM}.`;
    }
    // API ドキュメントに上限文字数の記載はないが、メインのメールアドレスと同様にチェック
    if (alternateEmails.some(email => email.length > MAX_EMAIL_LENGTH)) {
        throw `Each alternate email must be within ${MAX_EMAIL_LENGTH} characters.`;
    }
    return alternateEmails;
}

/**
  * 宛先を追加/更新する
  * @param {String} auth 認証設定名
  * @param {Array<String>} listIds 宛先を追加するリスト ID の一覧
  * @param {Object} contact 宛先情報
  * @return {String} jobId
  */
function upsertContact(auth, listIds, contact) {
    const requestBody = {
        "list_ids": listIds,
        "contacts": [contact]
    };
    const response = httpClient.begin()
        .authSetting(auth)
        .body(JSON.stringify(requestBody), 'application/json')
        .put('https://api.sendgrid.com/v3/marketing/contacts');

    const status = response.getStatusCode();
    const responseStr = response.getResponseAsString();
    if (status !== 202) {
        engine.log(responseStr);
        throw `Failed to upsert contact. status: ${status}`;
    }
    return JSON.parse(responseStr).job_id;
}

/**
  * ジョブの処理状況を確認する
  * @param {String} auth 認証設定名
  * @param {String} jobId ジョブ ID
  * @return {boolean} true: 完了, false: 未完了
  */
function checkStatus(auth, jobId) {
    const response = httpClient.begin()
        .authSetting(auth)
        .get(`https://api.sendgrid.com/v3/marketing/contacts/imports/${jobId}`);

    const status = response.getStatusCode();
    const responseStr = response.getResponseAsString();
    if (status !== 200) {
        engine.log(responseStr);
        throw `Failed to get upsert status. status: ${status}`;
    }
    const jobStatus = JSON.parse(responseStr).status;
    switch (jobStatus) {
        case 'pending': // 処理中
            return false;
        case 'completed': // 完了
            return true;
        default: // errored or failed
            engine.log(responseStr);
            throw 'Failed to complete upserting the contact.';
    }
}

    

Questetra Supportをもっと見る

今すぐ購読し、続きを読んで、すべてのアーカイブにアクセスしましょう。

続きを読む

上部へスクロール