Mandrill ValidationError

Posted

技术标签:

【中文标题】Mandrill ValidationError【英文标题】: 【发布时间】:2013-07-16 00:26:58 【问题描述】:

很高兴能在 *** 上提出我的第一个问题。这些年来,我一直依靠它自学了很多东西!

我的问题是这样的。尝试通过 Mandrill 的 API 发送邮件时出现以下错误:

"status":"error","code":-1,"name":"ValidationError","message":"You must specify a key value"

下面的代码是我用来发送邮件的代码:

<?php
$to = 'their@email.com';
$content = '<p>this is the emails html <a href="www.google.co.uk">content</a></p>';
$subject = 'this is the subject';
$from = 'my@email.com';

$uri = 'https://mandrillapp.com/api/1.0/messages/send.json';
$content_text = strip_tags($content);

$postString = '
"key": "RR_3yTMxxxxxxxx_Pa7gQ",
"message":  
 "html": "' . $content . '",
 "text": "' . $content_text . '",
 "subject": "' . $subject . '",
 "from_email": "' . $from . '",
 "from_name": "' . $from . '",
 "to": [
 
 "email": "' . $to . '",
 "name": "' . $to . '"
 
 ],
 "track_opens": true,
 "track_clicks": true,
 "auto_text": true,
 "url_strip_qs": true,
 "preserve_recipients": true
,
"async": false
';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $uri);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postString);
$result = curl_exec($ch);
echo $result;

?>

什么可能导致消息中的验证错误。我正在提供我的 API 密钥,它是有效的!

希望有人能够提供帮助,并感谢您在这里的普遍表现!

谢谢!

【问题讨论】:

感谢您提出这个问题!我整晚都在寻找答案。 如果 html 字段为空(无值)也会发生这种情况 【参考方案1】:

我不了解 mandrill,但您的 $content 字符串中包含双引号" 并且您在 $postString 中的分隔符也是双引号。这将打破任何语言。您需要按照 mandril 的要求转义 $content 中的双引号。

"html": "' . $content . '", 将转换为

"html": "<p>this is the emails html <a href="www.google.co.uk">content</a></p>",
                                            ^                ^

试试

 "html": "' . str_replace('"','\\"',$content) . '",
 "text": "' . str_replace('"','\\"',$content_text) . '",

而不是

 "html": "' . $content . '",
 "text": "' . $content_text . '",

【讨论】:

效果很好!非常感谢!想想我的眼睛一定是模糊了,没有注意到!【参考方案2】:

您可能还想只使用数组,让 PHP 为您处理 JSON 编码。如果 JSON 由于某种原因无效,则此特定错误很常见。因此,例如,您可以像这样设置参数:

$params = array(
    "key" => "keyhere",
    "message" => array(
        "html" => $content,
        "text" => $content_text,
        "to" => array(
            array("name" => $to, "email" => $to)
        ),
        "from_email" => $from,
        "from_name" => $from,
        "subject" => $subject,
        "track_opens" => true,
        "track_clicks" => true
    ),
    "async" => false
);

$postString = json_encode($params);

如果需要,您还可以使用json_decode 来解析响应。

【讨论】:

谢谢!有效。但为什么??我的意思是 JSON 出了什么问题。我现在很困惑。请回答。【参考方案3】:

您还需要从 html 代码中删除新行:

$content = trim(preg_replace('/\s+/', ' ', $content));

【讨论】:

【参考方案4】:

Bansi 的回答对 Dan B 有效,但如果其他人遇到同样的问题,最好检查内容是否有特殊字符(重音符号、变音符号、变音符号、撇号等)。如果是这种情况,解决方案可能是对文本进行 utf8 编码:

$content = utf8_encode('<p>Greetings from Bogotá, Colombia. Att:François</p>');

【讨论】:

【参考方案5】:

一直在尝试使用 Dan 的 curl 设置将 html 丰富的消息发布到 Mandrill,但这次在 message/send-template.json api 的 template_content: [] 数组中使用 html。

我注意到这个设置(包括 Bansi 修复)似乎在 Mandrill 的试用页面中工作:https://mandrillapp.com/api/docs/messages.JSON.html#method=send-template

但在我的 php 脚本中,我不断收到这个顽固的 You must specify a key value 错误。显然感谢this thread,我通过将utf8 作为字符集添加到请求标头来解决了这个问题:

$ch = curl_init();
$headers = array("Content-type: application/json;charset=\"utf-8\""); 
curl_setopt($ch, CURLOPT_URL, $uri);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt($ch, CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postString);

$result = curl_exec($ch);

【讨论】:

【参考方案6】:

PHP Mandrill API 错误:“Mandrill_ValidationError - You must specify a key value”

此错误还可能表明 json_encode() 编码失败并返回空字符串。当空字符串通过 curl 提交给 Mandrill 时,它不会让你知道它得到了完全空的 POST 内容,而是发出有用的消息“你必须指定一个键值”。

显然,这个问题可以通过在多个级别进行更好的检测来缓解:

API 级别的 Mandrill 可能会返回类似“Empty POST”的错误 Mandrill.php API 类可能会返回类似“json_encode 失败,可能是非 base64 图像或内容问题”的错误 Mandrill.php API 类可以检查图像中的非 base64 内容并给出类似“未编码图像”的错误 如果 json_encode() 抛出某种错误,那就太好了(不确定是这个错误)

目前还没有完成这些,因此调试起来非常困难。

在我的案例中,简单的解决方法是在包含图像内容之前有效地更改代码以运行 base64_encode(),即:

          'content' => base64_encode(file_get_content("image.jpg"),

如上所述,更好的解决方法是升级 Mandrill.php API 文件以检测编码失败并引发错误。

【讨论】:

在 mPDF 的字符串值周围添加 base64_encode() 解决了我的问题,谢谢。【参考方案7】:

在 Laravel 7.x 中,Mandrill 不再是核心的一部分。如果您像我一样使用therobfonz/laravel-mandrill-driver,如果您未能在 .env 文件中设置 Mandril 键,您也可能会看到类似的错误。

我有这个 MANDRILL_SECRET=h3xxxx 但我需要这个MANDRILL_KEY=h3xxxx

要验证您调用的是哪个密钥,请在 config\services.php 中查找此块

    // Mandrill is no longer core laravel...
    'mandrill' => [
        'secret' => env('MANDRILL_KEY'),
    ],

不调用密钥的另一个症状是失败的调用不会显示在 Mandrill api-log 列表中(因为缺少密钥意味着 Mandrill.com 不知道在哪里发布失败的尝试)。

【讨论】:

以上是关于Mandrill ValidationError的主要内容,如果未能解决你的问题,请参考以下文章

Mandrill / Mailchip 设计电子邮件与 mandrill_send 一起使用,但与 Sidekiq 一起失败

Mandrill 中的子域

Mandrill-api Excon::Errors::SocketError

延迟作业和 Mandrill:未初始化的常量 Mandrill::API

Mandrill 支持 i18n 吗?

使用 PHP 验证 Mandrill Webhook