PHP: Trouble adding attachments to emails via Mailgun API

Hey everyone, I’m hitting a roadblock with the Mailgun API in my PHP project. I’m trying to send emails with attachments, but I’m getting a weird error. It says something about an invalid resource type in the Guzzle library. Here’s what my code looks like:

$mailgunClient = new MailgunSender('api_key_here');
$emailDomain = 'my_domain.com';

$emailData = [
    'sender' => '[email protected]',
    'recipient' => $recipientEmail,
    'emailSubject' => $emailSubject,
    'emailContent' => $emailBody,
    'attachments' => [
        [
            'path' => $attachmentPath,
            'name' => $attachmentName,
        ]
    ]
];

$response = $mailgunClient->send($emailDomain, $emailData);

I thought I followed the docs correctly, but clearly something’s off. Any ideas what I’m doing wrong? Thanks in advance for your help!

hey there! i’ve dealt with this before. try using curl instead of guzzle. it’s simpler and usually works better with mailgun. here’s a quick example:

$file = curl_file_create($attachmentPath, mime_content_type($attachmentPath), $attachmentName);
$data = array(
    'from' => '[email protected]',
    'to' => $recipientEmail,
    'subject' => $emailSubject,
    'html' => $emailBody,
    'attachment' => $file
);

the next step is to use curl_setopt to set the options and send the request. hope this helps!

I’ve encountered this issue before, and it’s often related to how Mailgun handles file attachments. Instead of passing the file path directly, try using the MultipartStream class from Guzzle. Here’s a modified version of your code that should work:

use GuzzleHttp\Psr7\MultipartStream;

$multipart = new MultipartStream([
    [
        'name'     => 'attachment',
        'contents' => fopen($attachmentPath, 'r'),
        'filename' => $attachmentName
    ]
]);

$emailData = [
    'from'    => '[email protected]',
    'to'      => $recipientEmail,
    'subject' => $emailSubject,
    'html'    => $emailBody,
    'attachment' => $multipart
];

$response = $mailgunClient->messages()->send($emailDomain, $emailData);

This approach creates a proper multipart stream for the attachment, which Mailgun can process correctly. Make sure you have the necessary Guzzle components installed. If you’re still facing issues, double-check your API key and domain settings.

I’ve run into similar issues with Mailgun attachments before. From what I can see, your code structure looks pretty close, but there might be a small tweak needed.

In my experience, Mailgun expects the attachment to be passed as a file resource rather than a path string. Try modifying your attachment section like this:

'attachments' => [
    [
        'fileContent' => fopen($attachmentPath, 'r'),
        'filename' => $attachmentName,
    ]
]

This opens the file as a resource, which Guzzle can then properly handle. Also, double-check that your $attachmentPath is valid and the file exists.

If that doesn’t solve it, you might want to look into using Mailgun’s official PHP SDK instead of a custom MailgunSender class. It handles a lot of these quirks automatically.

Hope this helps! Let us know if you’re still having trouble.