C++ Builder CE ネットワークプログラミング

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>&nbsp;</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問題”について述べる予定です。多分。

コメント