You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Tag通过MailChimp API发送邮件时Segment创建报错排查

问题描述

我正在用PHP直接调用MailChimp API,未使用官方库。需要给受众中带有指定Tag的订阅者子集发送新闻通讯,未来该群体规模将达数千人,因此不想先获取订阅者邮箱再发送,而是希望利用MC的Segment功能实现。

我定义Segment的代码如下:

$segmentData = [
    'name' => $segmentName,
    'options' => [
        'match' => 'any',
        'conditions' => [
            [
                'condition_type' => 'Tags',
                'field' => 'tags',
                'op' => 'contains',
                'value' => [$tagName]
            ],
        ],
    ],
];

但持续收到错误:

"errors":[{
  "field":"options.conditions.item:0",
  "message":"Data did not match any of the schemas described in anyOf."
}]

我有一个包含约20名订阅者的测试受众,其中一名订阅者带有“notify_region”标签。尝试了多种变体均无效,请问该需求是否可行?我是否遗漏了什么?以下是完整测试代码:

<?php

$apiKey      = 'YOUR_MAILCHIMP_API_KEY';
$listId      = 'YOUR_LIST_ID';
$templateId  = 'YOUR_TEMPLATE_ID';
$tagName     = 'notify_region';
$segmentName = 'Example Segment 1';

function callMailchimp($method, $endpoint, $data = []) {
    global $apiKey;
    $apiUrl = "https://us10.api.mailchimp.com/3.0";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $apiUrl . $endpoint);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_USERPWD, "user:$apiKey");
    if (!empty($data)) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json'
        ]);
    }
    $response = curl_exec($ch);
    curl_close($ch);
    return json_decode($response, true);
}

$segmentData = [
    'name' => $segmentName,
    'options' => [
        'match' => 'any',
        // 'match' => 'all',
        'conditions' => [
            [
                'condition_type' => 'Tags',
                'field' => 'tags',
                'op' => 'contains',
                'value' => [$tagName]
                // 'value' => [ $tagName ],
            ],
        ],
    ],
];

$segmentResponse = callMailchimp('POST', "/lists/$listId/segments", $segmentData);

if (isset($segmentResponse['id'])) {
    $segmentId = $segmentResponse['id'];

    $campaignData = [
        'type' => 'regular',
        'recipients' => [
            'list_id' => $listId,
            'segment_opts' => [
                'saved_segment_id' => $segmentId,
            ],
        ],
        'settings' => [
            'subject_line' => 'Notification for Region',
            'from_name'    => 'Company',
            'from_email'   => 'hello@example.com',
            'template_id'  => $templateId,
        ],
    ];

    $campaignResponse = callMailchimp('POST', '/campaigns', $campaignData);

    if (isset($campaignResponse['id'])) {
        $campaignId = $campaignResponse['id'];

        // $sendResponse = callMailchimp('POST', "/campaigns/$campaignId/actions/send");
        // if(isset($sendResponse['message']) && $sendResponse['message'] === 'Campaign send started'){
        //     echo "Campaign sent successfully!";
        // } else {
        //     echo "Failed to send campaign: " . json_encode($sendResponse);
        // }

        echo "FIN.";

    } else {
        echo "Failed to create campaign: " . json_encode($campaignResponse);
    }
} else {
    echo "Failed to create segment: " . json_encode($segmentResponse);
}
解决方案

这个需求完全可行,出错原因是Tag类型的Segment条件参数格式不符合MailChimp API要求。针对标签的条件,不需要field和op字段,而是要使用tag_name或tag_id配合operator字段来定义:

修正后的Segment数据结构

$segmentData = [
    'name' => $segmentName,
    'options' => [
        'match' => 'any',
        'conditions' => [
            [
                'condition_type' => 'Tags',
                'tag_name' => $tagName, // 直接指定标签名称,大小写敏感
                'operator' => 'contains' // 可选值:contains / not_contains
            ],
        ],
    ],
];

如果已知标签ID,也可以用tag_id替换tag_name,效果一致:

[
    'condition_type' => 'Tags',
    'tag_id' => 'YOUR_TAG_ID',
    'operator' => 'contains'
]

完整修正后的测试代码

<?php

$apiKey      = 'YOUR_MAILCHIMP_API_KEY';
$listId      = 'YOUR_LIST_ID';
$templateId  = 'YOUR_TEMPLATE_ID';
$tagName     = 'notify_region';
$segmentName = 'Example Segment 1';

function callMailchimp($method, $endpoint, $data = []) {
    global $apiKey;
    // 注意替换为API Key对应的服务器前缀(比如us10、us2等,API Key最后一段即为服务器标识)
    $apiUrl = "https://us10.api.mailchimp.com/3.0";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $apiUrl . $endpoint);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_USERPWD, "user:$apiKey");
    if (!empty($data)) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json'
        ]);
    }
    $response = curl_exec($ch);
    curl_close($ch);
    return json_decode($response, true);
}

// 修正后的Segment参数
$segmentData = [
    'name' => $segmentName,
    'options' => [
        'match' => 'any',
        'conditions' => [
            [
                'condition_type' => 'Tags',
                'tag_name' => $tagName,
                'operator' => 'contains'
            ],
        ],
    ],
];

$segmentResponse = callMailchimp('POST', "/lists/$listId/segments", $segmentData);

if (isset($segmentResponse['id'])) {
    $segmentId = $segmentResponse['id'];

    $campaignData = [
        'type' => 'regular',
        'recipients' => [
            'list_id' => $listId,
            'segment_opts' => [
                'saved_segment_id' => $segmentId,
            ],
        ],
        'settings' => [
            'subject_line' => 'Notification for Region',
            'from_name'    => 'Company',
            'from_email'   => 'hello@example.com',
            'template_id'  => $templateId,
        ],
    ];

    $campaignResponse = callMailchimp('POST', '/campaigns', $campaignData);

    if (isset($campaignResponse['id'])) {
        $campaignId = $campaignResponse['id'];

        // 取消注释即可触发发送
        // $sendResponse = callMailchimp('POST', "/campaigns/$campaignId/actions/send");
        // if(isset($sendResponse['message']) && $sendResponse['message'] === 'Campaign send started'){
        //     echo "Campaign sent successfully!";
        // } else {
        //     echo "Failed to send campaign: " . json_encode($sendResponse);
        // }

        echo "FIN. Segment ID: $segmentId, Campaign ID: $campaignId";

    } else {
        echo "Failed to create campaign: " . json_encode($campaignResponse);
    }
} else {
    echo "Failed to create segment: " . json_encode($segmentResponse);
}

额外注意事项

  • 确保API Key对应的服务器前缀和请求URL中的一致(API Key最后一段为服务器标识,比如us10)
  • 标签名称必须和受众中实际存在的标签完全匹配,大小写敏感
  • 如需匹配多个标签,可在conditions数组中添加多个Tag条件,结合match参数(any表示满足任意一个,all表示满足所有)

内容的提问来源于stack exchange,提问作者donohoe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 04:50:13