Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mailgun Sent mail With attachment

I am facing issue when mail having attachment sent using mailgun. If anyone has done this thing please reply. This is my code...

$mg_api = 'key-3ax6xnjp29jd6fds4gc373sgvjxteol0';
$mg_version = 'api.mailgun.net/v2/';
$mg_domain = "samples.mailgun.org";
$mg_from_email = "[email protected]";
$mg_reply_to_email = "[email protected]";

$mg_message_url = "https://".$mg_version.$mg_domain."/messages";


$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);

curl_setopt ($ch, CURLOPT_MAXREDIRS, 3);
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, false);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_VERBOSE, 0);
curl_setopt ($ch, CURLOPT_HEADER, 1);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);

curl_setopt($ch, CURLOPT_USERPWD, 'api:' . $mg_api);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($ch, CURLOPT_POST, true); 
//curl_setopt($curl, CURLOPT_POSTFIELDS, $params); 
curl_setopt($ch, CURLOPT_HEADER, false); 

//curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_URL, $mg_message_url);
curl_setopt($ch, CURLOPT_POSTFIELDS,                
        array(  'from'      => 'aaaa <' . '[email protected]' . '>',
                'to'        => '[email protected]',
                'h:Reply-To'=>  ' <' . $mg_reply_to_email . '>',
                'subject'   => 'aaaaa'.time(),
                'html'      => 'aaaaaa',
                'attachment'[1] => 'aaa.rar'
            ));
$result = curl_exec($ch);
curl_close($ch);
$res = json_decode($result,TRUE);
print_r($res);

(I have used my mailgun settings)

I receive the email without the attachment. If I use the URL path it displays the URL instead of the attachment.

like image 594
TechCare99 Avatar asked Jan 09 '13 06:01

TechCare99


2 Answers

The documentation doesn't say it explicitly, but the attachment itself is bundled into the request as multipart/form-data.

The best way to debug what's going on is use Fiddler to watch the request. Make sure you accept Fiddler's root certificate, or the request won't issue due to the SSL error.

What you should see in Fiddler is for Headers:

Cookies / Login

Authorization: Basic <snip>==

Entity

Content-Type: multipart/form-data; boundary=<num>

And for TextView:

Content-Disposition: form-data; name="attachment"
@Test.pdf

Content-Disposition: form-data; name="attachment"; filename="Test.pdf"
Content-Type: application/pdf
<data>

Note that you POST the field 'attachment=@<filename>'. For form-data, the field name is also 'attachment', then has 'filename=<filename>' (without the '@') and finally the file contents.

I think CURL is supposed to just do this all for you magically based on using the '@' syntax and specifying a path to a file on your local machine. But without knowing the magic behavior it's hard to grok what's really happening.

For example, in C# it looks like this:

public static void SendMail(MailMessage message) {
    RestClient client = new RestClient();
    client.BaseUrl = apiUrl;
    client.Authenticator = new HttpBasicAuthenticator("api", apiKey);

    RestRequest request = new RestRequest();
    request.AddParameter("domain", domain, ParameterType.UrlSegment);
    request.Resource = "{domain}/messages";
    request.AddParameter("from", message.From.ToString());
    request.AddParameter("to", message.To[0].Address);
    request.AddParameter("subject", message.Subject);
    request.AddParameter("html", message.Body);

    foreach (Attachment attach in message.Attachments)
    {
        request.AddParameter("attachment", "@" + attach.Name);
        request.AddFile("attachment",
            attach.ContentStream.WriteTo,
            attach.Name,
            attach.ContentType.MediaType);
    }

    ...
    request.Method = Method.POST;
    IRestResponse response = client.Execute(request);
}
like image 62
JeremyS Avatar answered Oct 05 '22 02:10

JeremyS


I realise this is old but I've just run into this problem and this page is pretty much the only info I can find on the net. So I hope this will assist someone else. After talking to MailGun support I've found the following works with the current API.

Cycles through an array of zero to n attachment files:

    $attachmentsArray = array('file1.txt', 'file2.txt');
    $x = 1;
    foreach( $attachmentsArray as $att )
    {
        $msgArray["attachment[$x]"] = curl_file_create( $att );
        $x ++;
    }

    // relevant cURL parameter, $msgArray also contains to, from, subject  parameters etc.
    curl_setopt($ch, CURLOPT_POSTFIELDS,$msgArray);
like image 23
nzmuzzer Avatar answered Oct 05 '22 00:10

nzmuzzer