How to Create an Email Message in C++

How to Create an Email Message in C++

Aspose.Email FOSS for C++ lets you compose fully structured Outlook MSG files in code using mapi_message::create(). You can set the subject, plain-text and HTML bodies, sender identity, recipients, and save the result to MSG or EML with a single call — no Outlook installation required.

Step 1 — Set Up the Project

git clone https://github.com/aspose-email-foss/Aspose.Email-FOSS-for-Cpp.git
add_subdirectory(Aspose.Email-FOSS-for-Cpp)
target_link_libraries(your_target PRIVATE AsposeEmailFoss::AsposeEmailFoss)

Step 2 — Create a Message and Set Subject and Body

mapi_message::create() accepts the subject and plain-text body as constructor arguments:

#include "aspose/email/foss/msg/mapi_message.hpp"

auto message = aspose::email::foss::msg::mapi_message::create(
    "Quarterly Status Update",
    "Hello team,\n\nPlease find the summary below.\n\nRegards,\nEngineering");

After creation you can also update the subject or body via set_subject() and set_body():

message.set_subject("Revised: Quarterly Status Update");
message.set_body("Updated body text.");

Step 3 — Set Sender Properties

Use set_sender_name() and set_sender_email_address() to identify the sender. The address type is SMTP by default; override it with set_sender_address_type() if needed:

message.set_sender_name("Build Agent");
message.set_sender_email_address("build.agent@example.com");

Step 4 — Add Recipients

add_recipient() appends a recipient to the message. Call it once per recipient:

message.add_recipient("alice@example.com", "Alice Example");
message.add_recipient("bob@example.com", "Bob Example");

Step 5 — Set an HTML Body

Use set_html_body() to store an HTML version of the message body. Both plain-text and HTML bodies can coexist; email clients pick the richer format:

message.set_html_body(
    "<html><body>"
    "<p>Hello team,</p>"
    "<p>Please find the <b>quarterly summary</b> below.</p>"
    "<p>Regards,<br>Engineering</p>"
    "</body></html>");

Step 6 — Save to MSG

save() serialises the message to Outlook MSG format. Pass a std::filesystem::path to write directly to disk, an std::ostream for stream output, or call with no arguments to receive a std::vector<std::uint8_t>:

#include <filesystem>
#include <fstream>
#include "aspose/email/foss/msg/mapi_message.hpp"

int main()
{
    auto message = aspose::email::foss::msg::mapi_message::create(
        "Meeting Notes", "Details inside.");
    message.set_sender_name("Alice");
    message.set_sender_email_address("alice@example.com");
    message.add_recipient("bob@example.com", "Bob");

    // Save to file path
    message.save(std::filesystem::path("meeting_notes.msg"));

    // Save to stream
    std::ofstream out_stream("meeting_notes_stream.msg", std::ios::binary);
    message.save(out_stream);

    // Save to bytes in memory
    auto bytes = message.save();
}

Step 7 — Save to EML

Use save_to_eml() to produce an RFC 5322 / MIME file instead of MSG. The same three overloads (path, stream, or bytes) are available:

#include <filesystem>
#include "aspose/email/foss/msg/mapi_message.hpp"

int main()
{
    auto message = aspose::email::foss::msg::mapi_message::create(
        "Hello", "World");
    message.set_sender_name("Alice");
    message.set_sender_email_address("alice@example.com");
    message.add_recipient("bob@example.com", "Bob");

    message.save_to_eml(std::filesystem::path("hello.eml"));
}

Common Issues and Fixes

Message saved but Outlook shows garbled text. Ensure the message is created with Unicode string support. mapi_message::create() enables Unicode strings by default. If you need to force ANSI encoding (rarely necessary), pass false as the third argument: mapi_message::create(subject, body, false).

save() stream output is empty or corrupt. Always open output streams with std::ios::binary. Text-mode streams translate newlines on Windows, corrupting the binary CFB structure.

Recipients not appearing in the To/Cc field in Outlook. add_recipient() adds recipients to the MAPI recipient table. Additionally set the display_to MAPI property via set_property() with common_message_property_id::display_to and property_type_code::ptyp_string so Outlook displays names in the header.

HTML body not rendered. Confirm the HTML string is well-formed with opening and closing <html><body> tags. Also verify the receiving client supports HTML email; some minimal clients render only plain text.

set_internet_message_id() has no effect. set_internet_message_id() sets the MAPI internet message ID used for threading. This property is optional and not required for a valid MSG file.

Frequently Asked Questions

What is the simplest way to create an MSG file?

#include <fstream>
#include "aspose/email/foss/msg/mapi_message.hpp"

int main()
{
    auto message = aspose::email::foss::msg::mapi_message::create("Hello", "Body");
    message.set_sender_name("Alice");
    message.set_sender_email_address("alice@example.com");
    std::ofstream out("hello.msg", std::ios::binary);
    message.save(out);
}

Can I create a message with only an HTML body and no plain-text body?

Yes. Call mapi_message::create(subject, "") to leave the plain-text body empty, then call set_html_body() to set the HTML content.

How do I set the message class?

Use set_message_class() with the MAPI message class string, for example "IPM.Note" for a standard email message:

message.set_message_class("IPM.Note");

Can I set the Internet Message-ID for threading?

Yes. Call set_internet_message_id() with an RFC 2822-format message ID string:

message.set_internet_message_id("<msg-001@example.com>");

Is Unicode enabled by default?

Yes. The two-argument form of mapi_message::create(subject, body) enables Unicode strings. To create a legacy ANSI message, pass false as the third argument.

See Also