C++ にて VMime を使って メールサーバからメールを受信する

C++ にて VMime を使って メールを送信する
の続きです。

対象とするメールサーバ

ローカルネット内に建てた dovecot サーバ
および Gmail サーバ

Gmail サーバの仕様

サーバ名とポート番号 サーバ名:pop.gmail.com

ポート番号 995:(SSL)

下記にあるように、Gmail の設定にて「POP を有効にする」

Google: POP を使用して他のメール クライアントで Gmail のメールを読む https://support.google.com/mail/answer/7104828?hl=ja

ユーザ認証

Gmail は、下記の2つに対応している。
(1) AUTH PLAIN: ユーザ名(Google アカウント) と パスワード
(2) XOAUTH2: アクセストーク

(1) のときは、安全性の低いアプリからのアクセスを許可すること。

安全性の低いアプリのアクセスを有効にする方法 https://qiita.com/miriwo/items/7c5a451a35cecdd72085

この記事では、(1) の AUTH PLAIN で、アプリを作成する。

メールを受信する

ストアサービス vmime::net::store を使用する

vmime store Class Reference https://www.vmime.org/public/documentation/doxygen/classvmime_1_1net_1_1store.html

下記は、VMime Book に掲載されている例

ストアサービスへの接続 https://ken-ohwada.hatenadiary.org/entry/2020/12/31/112631

// Create a new session
vmime:: utility :: url url( "imap://vincent:password@imap:example.org" ); 
vmime::shared ptr <vmime::net::session> sess = vmime::net::session::create();
// Create an instance of the transport service
vmime::shared ptr <vmime::net::store> store = sess−>getStore(url); 
// Connect it
store−>connect();

フォルダを開く

folder->open(vmime::net::folder::MODE_READ_WRITE);
````


複数のメッセージに関する情報の取得


````
std::vector <ref <vmime: : net::message> > allMessages = folder->getMessages(vmime::net::messageSet::byNumber(1, −1));
// −1 is a special value to mean ”the number of the last message in the folder”
folder−>fetchMessages(allMessages , vmime::net::fetchAttributes::FLAGS | vmime::net::fetchAttributes::ENVELOPE );
for (unsigned int i = 0 ; i < allMessages.size() ; ++i) {
    vmime::sharedptr<vmime::net::messag> msg = allMessages[i];
    const int flags=msg->getFlags();
    std::cout << "Message " << i << " : " << std::endl;
    if (flags & vmime::net::message::FLAG_SEEN) 
    std::cout << ” − is read” << std::endl;
    if (flags & vmime::net::message::FLAGD_ELETED) 
    std::cout << ” − is deleted” << std::endl;
    vmime::shared ptr <const vmime::header> hdr = msg−>getHeader();
    std::cout << "  − sent on " << hdr−>Date()−>generate() << std::endl;
    std::cout << " − sent by " << hdr−>From()−>generate() << std::endl; 
}

メッセージとパーツの抽出

// Get a reference to the folder and to its first message
vmime::shared_ptr <vmime::net::folder> folder = store−>getDefaultFolder(); 
vmime::shared_ptr <vmime::net::message> msg = folder−>getMessage(1);
// Write the message contents to the standard output
vmime::utility::outputStreamAdapter out(std::cout); 
msg−>extract(out);

ソースコードに同封されているサンプルコード example6.cpp
https://github.com/kisli/vmime/blob/master/examples/example6.cpp

example6.cpp には、下記のようなメニューが用意されている。

  1. Show message flags
  2. Show message structure
  3. Show message header
  4. Show message envelope
  5. Extract whole message
  6. Extract attachments
  7. Status
  8. List folders
  9. Change folder
  10. Add message (to the current folder)
  11. Copy message (into the current folder)
  12. Display trace output

上記を参考にメール受信アプリを作成して、 githubに公開した。
https://github.com/ohwada/MAC_cpp_Samples/tree/master/vmime/pop3