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

Azure环境下cURL调用ACS发送邮件无法携带附件求助

问题描述

我们在Azure上部署了WordPress站点,自研插件通过cURL调用Azure Communication Services(ACS)REST API发送邮件。现在要给原脚本添加附件功能,但邮件能正常发送却无法携带附件,求帮忙排查。相关代码如下:

<?php
class ACSMailer{

    public static function SendMail($atts){

        $to = $atts['to'];
        $subject = $atts['subject'];
        $message = $atts['message'];
        $headers = $atts['headers'];

        $attachments = [];

        $atch = $atts['attachments'];

        foreach($atch as $atchkey => $atchval) {

            $attachments[] = [
                'name' => basename($atchval),
                'contentType' => mime_content_type($atchval),
                'contentInBase64' => base64_encode(file_get_contents($atchval)),
            ];
        }

        //error_log('HEADERS: '. print_r($atts, true));
        // TODO: Check for HTML and send as plain text

        $settings = get_option('acs_settings_option_name');
        $endpoint = $settings["endpoint"];
        $key = base64_decode($settings["key"]);

        $bodyArray = array(
            'sender' => 'donotreply@cardiffcouncildev.co.uk',
            'content' => array('subject' => $subject, 'html' => $message),
            'importance' => 'normal',
            'recipients' => array('to' => array(array('email' => $to))),
            'attachment' => $attachments,
            'disableUserEngagementTracking' => true
            );
        $bodyStr = json_encode($bodyArray);
        $hashedBodyStr = base64_encode(hash('sha256', $bodyStr, true));

        $dateStr = gmdate('D, d M Y H:i:s T');

        $fullEndpoint = $endpoint . '/emails:send?api-version=2021-10-01-preview';
        $hostStr = str_replace('https://', '', $endpoint);
        $url = str_replace($endpoint, '', $fullEndpoint);
        
        $stringToSign = 'POST' . "\n" . $url . "\n" . $dateStr . ';' . $hostStr . ';' . $hashedBodyStr;
        $signature = base64_encode(hash_hmac('sha256', $stringToSign, $key, true));
        $uuid = vsprintf( '%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex(random_bytes(16)), 4) );


        $curl = curl_init();

        curl_setopt_array($curl, array(
            CURLOPT_URL => $fullEndpoint,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => $bodyStr,
            CURLOPT_HTTPHEADER => array(
                'Content-Type: application/json',
                'Date: ' . $dateStr,
                'Authorization: HMAC-SHA256 SignedHeaders=date;host;x-ms-content-sha256&Signature=' . $signature,
                'x-ms-content-sha256: ' . $hashedBodyStr,
                'repeatability-request-id: ' . $uuid,
                'repeatability-first-sent: ' . $dateStr
            ),
        ));

        $response = curl_exec($curl);

        curl_close($curl);

        
        error_log('DATE: '. $dateStr);
        error_log('$endpoint: ' . $endpoint);
        error_log('$fullEndpoint: ' . $fullEndpoint);
        error_log('$key: ' . $key);
        error_log('$bodyStr: ' . $bodyStr);
        error_log('$dateStr: ' . $dateStr);
        error_log('$url: ' . $url);
        error_log('$stringToSign : ' . $stringToSign );
        error_log('$signature: ' . $signature);
        error_log('$uuid: ' . $uuid);
        error_log('$hashedBodyStr: ' . $hashedBodyStr);
        error_log('$bodyArray: ' . print_r($bodyArray, true));
        error_log('API RESPONSE: ' . $response);
        
    }
}
问题排查与修复

核心错误:API字段名拼写错误

ACS邮件发送API要求附件字段为复数形式attachments,但代码中写的是单数attachment,API无法识别该字段,导致附件被忽略。

修改方案

将$bodyArray中的'attachment'改为'attachments':

$bodyArray = array(
    'sender' => 'donotreply@cardiffcouncildev.co.uk',
    'content' => array('subject' => $subject, 'html' => $message),
    'importance' => 'normal',
    'recipients' => array('to' => array(array('email' => $to))),
    'attachments' => $attachments, // 修正为复数形式
    'disableUserEngagementTracking' => true
);

额外验证点

  1. 文件路径与权限:确认$atts['attachments']传入的是服务器上的有效文件路径,且PHP进程拥有该文件的读取权限(比如WordPress的wp-content/uploads目录权限通常设为755)。
  2. MIME类型识别:如果mime_content_type函数无法正确返回类型,可能是环境未启用fileinfo扩展,可改用finfo类替代:
$finfo = new finfo(FILEINFO_MIME_TYPE);
$contentType = $finfo->file($atchval);
  1. Base64编码有效性:检查base64_encode(file_get_contents($atchval))返回的字符串是否完整,无截断或编码错误(可通过解码后对比原文件大小验证)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 07:25:59