C++Builder2009に付属のIndy10は、UnicodeString対応が不十分です。
そのため日本語メールを送信するにはちょっとしたテクニックは必要になります。
このTipsは以下のページを参考にさせていただきました。
C++Builder 2010以降をお使いの場合は、「C++Builder2010とIndy10でメールを送信する」をご覧ください。
最初は簡単に英文のメールを送信する方法を紹介します。
unique_ptr<TIdSMTP> smtp(new TIdSMTP(NULL));
smtp->Host = "localhost"; //SMTPサーバ
unique_ptr<TIdMessage> msg(new TIdMessage(NULL));
msg->From->Name = "From name";
msg->From->Address = "from@example.com";
TIdEMailAddressItem* item = msg->Recipients->Add();
item->Name = "To name";
item->Address = "to@example.com";
msg->Subject = "Subject";
msg->Body->Text = "This is e-mail.";
smtp->Connect();
smtp->Send(msg.get());
smtp->Disconnect();
日本語メールを送信するには、次の処理が必要になります。
Indyの各プロパティはUnicodeStringを受け取るため、文字コードをISO-2022-JPに変換したUnicodeStringを作成する関数を用意します。
文字コードの変換にMECSUtilsを利用しています。
/**
* JISコードに変換する
*/
UnicodeString ConvertJis(const UnicodeString& Str)
{
RawByteString jis;
Mecsutils::ConvertUnicodeToMultiByte(50220, Str, jis);
UnicodeString body;
body.SetLength(jis.Length());
for (int i = 1; i <= jis.Length(); ++i)
{
body[i] = jis[i];
}
return body;
}
文字コードがISO-2022-JPの文字列をBase64エンコードする関数を用意します。
/**
* ヘッダのBase64エンコード
*/
UnicodeString Base64Encode(const UnicodeString& Str)
{
UnicodeString jis = ConvertJis(Str);
unique_ptr<TIdEncoderMIME> enc(new TIdEncoderMIME(NULL));
return L"=?ISO-2022-JP?B?" + enc->EncodeString(jis) + "?=";
}
メールのヘッダに文字コードを設定します。
unique_ptr<TIdMessage> msg(new TIdMessage(NULL));
msg->ContentType = "text/plain";
msg->CharSet = "ISO-2022-JP";
msg->ContentTransferEncoding = "7bit";
メールの送信者名、宛先名、件名の日本語をBase64エンコードします。
msg->From->Name = Base64Encode(L"メールの送信者名");
TIdEMailAddressItem* item = msg->Recipients->Add();
item->Name = Base64Encode(L"メールの宛先");
msg->Subject = Base64Encode(L"メールの件名");
メールの本文の文字コードをISO-2022-JPに変換します。
msg->Body->Text = ConvertJis(L"テストメールの本文");
全体のコードは次のようになります。
unique_ptr<TIdSMTP> smtp(new TIdSMTP(NULL));
smtp->Host = "localhost";
unique_ptr<TIdMessage> msg(new TIdMessage(NULL));
msg->ContentType = "text/plain";
msg->CharSet = "ISO-2022-JP";
msg->ContentTransferEncoding = "7bit";
msg->From->Name = Base64Encode(L"メールの送信者名");
msg->From->Address = "from@example.com";
TIdEMailAddressItem* item = msg->Recipients->Add();
item->Name = Base64Encode(L"メールの宛先");
item->Address = "to@example.com";
msg->Subject = Base64Encode(L"メールの件名");
msg->Body->Text = ConvertJis(L"テストメールの本文");
smtp->Connect();
smtp->Send(msg.get());
smtp->Disconnect();
添付ファイルがある場合、メールはマルチパートになります。
メールのヘッダと本文の設定が変わります。
unique_ptr<TIdSMTP> smtp(new TIdSMTP(NULL));
smtp->Host = "localhost";
unique_ptr<TIdMessage> msg(new TIdMessage(NULL));
msg->ContentType = "multipart/mixed"; //マルチパート
msg->From->Name = Base64Encode(L"メールの送信者名");
msg->From->Address = "from@example.com";
TIdEMailAddressItem* item = msg->Recipients->Add();
item->Name = Base64Encode(L"メールの宛先");
item->Address = "to@example.com";
msg->Subject = Base64Encode(L"メールの件名");
//メールの本文のパート
TIdText* text = new TIdText(msg->MessageParts, NULL);
text->ContentType = "text/plain";
text->CharSet = "ISO-2022-JP";
text->ContentTransfer = "7bit";
text->Body->Text = ConvertJis(L"メールの本文");
//添付ファイルのパート
TIdAttachmentFile* attached = new TIdAttachmentFile(
msg->MessageParts,
L"C:\\test\\サンプル.jpg"); //ファイルのパス
attached->FileName = Base64Encode(L"サンプル画像.jpg"); //送信ファイル名
attached->ContentType = "image/jpeg"; //ファイルの種類によって変更します
smtp->Connect();
smtp->Send(msg.get());
smtp->Disconnect();
SMTP認証を使用してメールを送信するには、SSL関連のDLLが必要になります。
次のページからファイルをダウンロードして展開し、「libeay32.dll」と「ssleay32.dll」を実行ファイル(exeファイル)と同じディレクトリに配置します。
ソースコードには、SMTP認証の設定を追加します。
unique_ptr<TIdSMTP> smtp(new TIdSMTP(NULL));
unique_ptr<TIdSASLLogin> login(new TIdSASLLogin(smtp.get()));
unique_ptr<TIdUserPassProvider> provider(new TIdUserPassProvider(login.get()));
unique_ptr<TIdSSLIOHandlerSocketOpenSSL> sslHander(new TIdSSLIOHandlerSocketOpenSSL(NULL));
smtp->Host = "localhost"; //SMTPサーバ
smtp->Port = 465; //ポート番号
smtp->Username = "username"; //SMTP認証のユーザー名
smtp->Password = "passowrd"; //SMTP認証のパスワード
sslHander->Host = smtp->Host;
sslHander->Port = smtp->Port;
sslHander->Destination = sslHander->Host + ":" + IntToStr(sslHander->Port);
smtp->IOHandler = sslHander.get(); //TIdSSLIOHandlerSocketOpenSSL
smtp->UseTLS = utUseExplicitTLS; // Explict
//以下、メールの作成は同じ
unique_ptr<TIdMessage> msg(new TIdMessage(NULL));
msg->From->Name = "From name";
msg->From->Address = "from@example.com";
TIdEMailAddressItem* item = msg->Recipients->Add();
item->Name = "To name";
item->Address = "to@example.com";
msg->Subject = "Subject";
msg->Body->Text = "This is e-mail.";
smtp->Connect();
smtp->Send(msg.get());
smtp->Disconnect();
Gmailを使ってメールを送信する方法です。
SMTP認証を使います。ポート番号に気をつけて下さい。
unique_ptr<TIdSMTP> smtp(new TIdSMTP(NULL));
unique_ptr<TIdSASLLogin> login(new TIdSASLLogin(smtp.get()));
unique_ptr<TIdUserPassProvider> provider(new TIdUserPassProvider(login.get()));
unique_ptr<TIdSSLIOHandlerSocketOpenSSL> sslHander(new TIdSSLIOHandlerSocketOpenSSL(NULL));
//Gmailの設定
smtp->Host = "smtp.gmail.com";
smtp->Port = 587;
smtp->Username = "username@gmail.com"; //Gmailのユーザ名
smtp->Password = "password";
sslHander->Host = smtp->Host;
sslHander->Port = smtp->Port;
sslHander->Destination = sslHander->Host + ":" + IntToStr(sslHander->Port);
smtp->IOHandler = sslHander.get(); //TIdSSLIOHandlerSocketOpenSSL
smtp->UseTLS = utUseExplicitTLS; // Explict
//以下、メールの作成は同じ
サンプルコードでは「using namespace std;」を省略しています。
ヘッダファイルも省略していますが、MECSUtilsを使うには
#include "MECSUtils.hpp"
が必要です。詳細は「文字コードを変換する」をご覧下さい。
Indyのヘッダは、ヘルプファイルを調べて下さい。
例えば「TIdText」の場合、ヘルプを見ると、
File
IdText
とありますから、拡張子「.hpp」をつけて
#include "IdText.hpp"
となります。