after several wasted hours, things you should know about raw emails.
follow a structure like this:
boundary=boundary_name \n\n (create a boundary with boundary= and \n\n)
--boundary_name (start a boundary with --)
Header (add headers with Content-Type:)
(one blank line with \n)
html or text or file (add your content)
(one blank line with \n)
--boundary_name-- \n\n (close boundary with -- -- and \n\n)
Example with PHP code:
$boundary = md5(time());
$html = "<h1>E-mail Test</h1>";
$html .= "<img src=\"cid:{$attachment['filename']}\">"; // Content-ID
$text = "You need HTML enabled";
$raw = '';
$raw .= "From:{$from}\n";
$raw .= "To:{$to}\n";
$raw .= "Subject:{$subject}\n";
$raw .= "MIME-Version: 1.0\n";
$raw .= "Content-Type: multipart/mixed; boundary=\"{$boundary}\"\n\n";
$raw .= "--{$boundary}\n";
$raw .= "Content-Type: multipart/alternative; boundary=\"sub_{$boundary}\"\n\n";
$raw .= "--sub_{$boundary}\n";
$raw .= "Content-Type: text/plain; charset=\"UTF-8\"\n";
$raw .= "\n";
$raw .= "{$text}\n";
$raw .= "\n";
$raw .= "--sub_{$boundary}\n";
$raw .= "Content-Type: text/html; charset=\"UTF-8\"\n";
$raw .= "Content-Disposition: inline\n";
$raw .= "\n";
$raw .= "{$html}\n";
$raw .= "\n";
$raw .= "--sub_{$boundary}--\n\n";
foreach ($this->email->getFiles() as $attachment) {
$raw .= "--{$boundary}\n";
$raw .= "Content-Type:{$attachment['mimetype']}; name=\"{$attachment['filename']}\"\n"; // name
$raw .= "Content-Transfer-Encoding:base64\n";
$raw .= "Content-Disposition:attachment;filename=\"{$attachment['filename']}\"\n"; // filename
#$raw .= "Content-Disposition:inline;name={$file_name}\n";
$raw .= "Content-ID:<{$attachment['filename']}>\n";
$raw .= "\n";
$raw .= base64_encode($attachment['content']) . "\n";
$raw .= "\n";
}
$raw .= "--{$boundary}--\n\n";
Final raw Message example:
From:Name From<name@from.com>
To:email@to.com,second@to.com
Subject:Your subject
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="b4f53df7c26ae6945f29c42d5c2bb55f"
--b4f53df7c26ae6945f29c42d5c2bb55f
Content-Type: multipart/alternative; boundary="sub_b4f53df7c26ae6945f29c42d5c2bb55f"
--sub_b4f53df7c26ae6945f29c42d5c2bb55f
Content-Type: text/plain; charset="UTF-8"
You need HTML enabled
--sub_b4f53df7c26ae6945f29c42d5c2bb55f
Content-Type: text/html; charset="UTF-8"
Content-Disposition: inline
<h1>E-mail Test</h1>
<img src="cid:qrcode.png"> // <-- from Header Content-ID:<name>
--sub_b4f53df7c26ae6945f29c42d5c2bb55f--
--b4f53df7c26ae6945f29c42d5c2bb55f
Content-Type:image/png; name="qrcode.png"
Content-Transfer-Encoding:base64
Content-Disposition:attachment;filename="qrcode.png"
Content-ID:<qrcode.png> // you can use <img src="cid:qrcode.png"> in html
iVBORw0K== // base64encoded file contents
--b4f53df7c26ae6945f29c42d5c2bb55f
Content-Type:image/png; name="another_file.png"
Content-Transfer-Encoding:base64
Content-Disposition:attachment;filename="another_file.png"
Content-ID:<another_file.png>
iVBORw0KGg== // base64encoded file contents
--b4f53df7c26ae6945f29c42d5c2bb55f--
Don't forget, after Headers, one blank lines before and after content
For PHP AWS SDK
try {
$client = new SesClient($options);
$result = $client->sendRawEmail([
'RawMessage' => [
'Data' => $raw
],
]);
echo $result['MessageId'];
}
catch (AwsException $e) {
echo $e->getAwsErrorMessage();
return false;
}