Creating a message
About
This tutorial is about preparing a message that must be send or stored in a folder like the draft folder.
The basic idea
The platform factory can create TnyHeader, TnyMimePart and TnyMsg instances for you. You will usually create at least a TnyMsg and a TnyHeader instance with it, fill in the TnyHeader instance and assign it to the TnyMsg instance using the tny_msg_set_header API of TnyMsg. Because the TnyMsg type inherits from TnyMimePart, you now already have a first mime part instance. Whenever you do TnyMimePart API operations on this instance you will be working on the body part of the E-mail.
You can also add extra mime parts to the message using the tny_mime_part_add_part API of TnyMimePart. Each such mime part can be fed data using the tny_mime_part_construct_from_stream API of TnyMimePart.
The TnyStream API is a typical stream API which makes it possible to write-to and read-from it. A source stream can for example be a file stream that reads data from a file. A target stream can also be a file stream that writes to a file. When constructinga TnyMimePart from a stream, you need to pass a source stream. If you only want to set a simple piece of text, you can for example use the TnyCamelMemStream? type, which is a stream type that uses simple memory as storage.
For file attachments you will usually want the TnyFsStream type, or the TnyVfsStream type from libtinymail-gnomevfs.
Normal E-mail
A normal E-mail with no attachments, just a body in plain text, is created using a stream that contains the ASCII text and "text/plain" as type parameter for tny_mime_part_construct with "7bit" as transfer encoding.
Sample code
#define TEST_STRING "This is a test E-mail"
static TnyMsg*
create_test_msg (TnyPlatformFactory *platfact)
{
TnyMsg *retval = tny_platform_factory_new_msg (platfact);
TnyStream *stream = tny_camel_mem_stream_new ();
TnyHeader *header = tny_platform_factory_new_header (platfact);
tny_header_set_subject (header, TEST_STRING);
tny_header_set_from (header, "from.my@self.com");
tny_header_set_to (header, "to.my@buddy.com");
tny_msg_set_header (retval, header);
g_object_unref (header);
tny_stream_write (stream, TEST_STRING, strlen (TEST_STRING));
tny_stream_reset (stream);
tny_mime_part_construct (TNY_MIME_PART (retval), stream, "text/plain", "7bit");
g_object_unref (stream);
return retval;
}
HTML E-mail
A HTML E-mail with no attachments, just a body in plain HTML, is created using a stream that contains the HTML data and "text/html" as type parameter for tny_mime_part_construct with also 7bit as transfer encoding.
Sample code
#define TEST_STRING "<html><body><b>This is a test E-mail</b></body></html>"
static TnyMsg*
create_test_msg (TnyPlatformFactory *platfact)
{
TnyMsg *retval = tny_platform_factory_new_msg (platfact);
TnyStream *stream = tny_camel_mem_stream_new ();
TnyHeader *header = tny_platform_factory_new_header (platfact);
tny_header_set_subject (header, TEST_STRING);
tny_header_set_from (header, "from.my@self.com");
tny_header_set_to (header, "to.my@buddy.com");
tny_msg_set_header (retval, header);
g_object_unref (G_OBJECT (header));
tny_stream_write (stream, TEST_STRING, strlen (TEST_STRING));
tny_stream_reset (stream);
tny_mime_part_construct (TNY_MIME_PART (retval), stream, "text/html", "7bit");
g_object_unref (G_OBJECT (stream));
return retval;
}
Multipart text/plain and text/html E-mail
A text/html E-mail that as an alternative text/plain mime part with no attachments, just a body is created using two stream that contains the HTML and text data. They get "text/html" and "text/plain" as type parameter for their tny_mime_part_construct API call and they are added to the TnyMsg instance using the TnyMimePart API tny_mime_part_add_part.
This example is also used by the demo/test application msg-sender.c which is available in the tests/functional directory of the repository.
Sample code
static TnyMsg*
create_test_msg (TnyPlatformFactory *platfact)
{
TnyMsg *retval = tny_platform_factory_new_msg (platfact);
TnyHeader *header = tny_platform_factory_new_header (platfact);
TnyStream *plain_stream = tny_camel_mem_stream_new ();
TnyStream *html_stream = tny_camel_mem_stream_new ();
TnyMimePart *plain_body = tny_platform_factory_new_mime_part (platfact);
TnyMimePart *html_body = tny_platform_factory_new_mime_part (platfact);
tny_header_set_subject (header, TEST_STRING);
tny_header_set_from (header, "from.my@self.com");
tny_header_set_to (header, "to.my@buddy.com");
tny_msg_set_header (retval, header);
g_object_unref (G_OBJECT (header));
tny_stream_write (plain_stream, TEST_STRING, strlen (TEST_STRING));
tny_stream_reset (plain_stream);
tny_stream_write (html_stream, HTML_PRE TEST_STRING HTML_POST,
strlen (HTML_PRE TEST_STRING HTML_POST));
tny_stream_reset (html_stream);
tny_mime_part_construct (plain_body, plain_stream, "text/plain; charset=utf-8", "7bit");
tny_mime_part_construct (html_body, html_stream, "text/html; charset=utf-8", "7bit");
tny_mime_part_add_part (TNY_MIME_PART (retval), html_body);
tny_mime_part_add_part (TNY_MIME_PART (retval), plain_body);
g_object_unref (plain_stream);
g_object_unref (html_stream);
g_object_unref (plain_body);
g_object_unref (html_body);
return retval;
}
Constructing from a different source, not from memory
In the tinymail framework it's perfectly possible to construct mime parts from a non-memory stream too. The tny_mime_part_construct only requires that you use one of the existing stream types.
You can also use your own implementation of TnyStream. That way you can implement a stream type, and construct from that source. For example a GIO stream or any other kind of stream type.
Future
A Lemonade IMAP feature like Forward without Download will in future be possible too. Maybe an API like tny_mime_part_construct_from_imap. Though this is talking about future, and that is not what this part of the documentation is about.
