SMTPプロトコルでメールを送信してみよう #2 いわゆるhtmlなメールを含んでいる場合
Indyを使うのは同様なんですが、あまり知られていないコンポーネントTIdMessageBuilderHtmlを使って、html部分を含んだメールを送ってみます。必要なインクルードファイルは、
#include <IdMessageBuilder.hpp> //TIdMessageBuilderPlainを使うために必要なヘッダ
です。コンポーネント化されていないので、これを使うのはツールパレットからドラグアンドドロップというわけにはいきません。上記ヘッダーをインクルードしておいて、
TIdMessageBuilderHtml* Htmlbuilder = new TIdMessageBuilderHtml();
としてインスタンスを生成します。これしかやりようがないわけですね。
今回のフォームは、

TIdSSLHandlerSocketOpenSSL,TIdSMTP,TIdMessage,TIdLogDebugを各一個配置します。それとTButtonが一個。
あと、html部分として送るhtmlファイルを用意します。内容は下記で、これを”cid-test.html”としておきます。
<html>
<head>
</head>
<body>
<img src="cid:1.png" width="200" alt="">
<img src="cid:2.png" width="200" alt="">
</body>
</html>
“cid”を2カ所取り除いて、htmlファイルをEdgeで開くと、

こうなるので、これがhtml部分としてメールで送れればおけです。cid:の部分はTIdMessageBuilderHtmlがハンドリングしてくれます。このあたりの情報は、
にRemy氏が自ら書いています。さて、”cid-test.html”および”cid-test.html”で引用している”1.png”と”2.png”を実行ファイルと同じ階層において準備します。Unit1.cppは、
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <IdMessageBuilder.hpp> //TIdMessageBuilderPlainを使うために必要なヘッダ
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
bool IsBom(String filepath)
{
TFileStream* stream;
unsigned char buf[3];
stream = new TFileStream(filepath,fmOpenRead);
stream->Read(buf,sizeof(buf));
delete stream;
if( buf[0] == 0xef && buf[1] == 0xbb && buf[2] == 0xbf ){
//Form1->Label1->Caption = "BOM付";
return true;
}
else {
//Form1->Label1->Caption = "BOM無し";
return false;
}
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TIdSMTP* IdSMTP;
TIdMessage* IdMessage;
TIdMessageBuilderHtml* Htmlbuilder;
String imgfilename;
IdSMTP = IdSMTP1;
IdMessage = IdMessage1;
IdSMTP->Host = "your_smtp_server.com";
IdSMTP->AuthType = satDefault;
IdSMTP->Username = "your_id";
IdSMTP->Password = "your_passwd";
IdSMTP->Port = 587;
Htmlbuilder = new TIdMessageBuilderHtml();
Htmlbuilder->HtmlCharSet = "UTF-8";
Htmlbuilder->PlainText->Text = "日本語メール本文";
String path = "cid-test.html";
Htmlbuilder->Html->LoadFromFile(path,TEncoding::UTF8);
Htmlbuilder->HtmlFiles->Add("1.png");
Htmlbuilder->HtmlFiles->Add("2.png");
Htmlbuilder->FillMessage(IdMessage);
IdMessage->From->Address = "youraddress";
IdMessage->Subject = "日本語サブジェクト";
IdMessage->Priority = mpHighest;
IdMessage->Recipients->EMailAddresses = "送信メールアドレス";
IdSMTP->Connect();
IdSMTP->Send(IdMessage);
ShowMessage("Email sent");
IdSMTP->Disconnect();
}
これで送れます。受け取った側では、

Becky!で受信した結果ですが、こちらがhtml部分、

こちらが、plain-text部分です。ちゃんと分けられて送られています。こうしないと、htmlが読めないメーラーでは意味不明になりますからね。
いったんIdMessageを構築して、それを
Htmlbuilder->FillMessage(IdMessage);
でHtmlbuiderにFillするのが肝ですかね。で、送るのはIdMessageの方。このあたりは上記のRemy氏のブログに書かれています。インラインの画像だけでなく、添付ファイルを添える手段も提供されています。もう一つだけ例を挙げましょうかね。

このhtmlをメールとして送りたい場合は、もとのhtmlのソースが、
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>無題ドキュメント</title>
</head>
<body>
<p> これがラインです。</p>
<p> </p>
<img src="triangle.png" width="563" height="319" alt=""/>
<p>これは、レイアウト P タグのコンテンツです<img src="desmos-graph.png" width="800" height="800" alt=""/></p>
</body>
</html>
だとすると、画像ファイル名の前に”cid:”を付けてセーブしたhtmlを用意します。この時BOMの付いていないplainなutf8なファイルとしてセーブします。Windowsのメモ帳で開けばわかります。BOMが付いていると文字化けします。Becky!での受信メールは、

テキストメール部分は、

となります。ここで左端の”赤丸”にご注意ください。送信メールのメッセージのプロパティーで、
IdMessage->Priority = mpHighest;
とした結果が反映されてます。機会を改めて”Gmail問題”について述べる予定です。多分。
コメント