Saturday, January 19, 2013

Successfully sending an email in Hebrew with embedded picture and attachment

This is the final installment in an unplanned series about sending emails in Hebrew, with an embedded picture and an attachment.

For my final programming and debugging session, I thought it prudent to start with an email which I knew had been sent with UTF-8/Base64 encoding - I sent my home address an email from my Gmail address. Looking at this email as text, I could see that the HTML was far simpler than I had been using until now, so I replaced most of my complicated code with the simple code.

Then I considered the fact that the body of my text would have to be encoded as UTF-8. This actually was a very minor problem: instead of writing html.add ('this is a line'), I needed to write html.add (AnsiToUTF8 ('this is a line')). Of course, in real life, it was slightly more complicated as the UTF-8 encoded code wasn't shown properly in the preview form; the program creates encoded strings if sending an email or unencoded strings if previewing.

Even after encoding the text, the emails were arriving without Hebrew text. In a moment of inspiration, I realised that I had to tell the component holding the email that it too was encoded. In other words, instead of writing
 with TIdText.create (email.MessageParts, nil) do
  begin
   body.assign (html);
   contentType:= 'text/html';
  end;
I had to add a line...
 with TIdText.create (email.MessageParts, nil) do
  begin
   body.assign (html);
   contentType:= 'text/html';
   charset:= 'UTF-8';  // added line for encoding
   parentpart:= 1;       // added line for structure
  end;
Now my emails were arriving correctly both at home and at work.

Once I had got this fixed, I turned my attention to the subject of attachments. First, I read the tutorial which I mentioned previously very carefully; the email which I am trying to send has several parts (plain text, html, embedded picture, unconnected attachment) and there has to be an initial, empty, TIdText section to set things up correctly. Needless to say, my code was missing this section.

Once I added the initial TIdText section and added correctly numbered parentparts, my code worked ... most of the time: sometimes it would send attachments and sometimes not. It took a while for me to notice the pattern: text and jpg files were being sent, but zip, doc or pdf files seemed to hang the computer, requiring closing the program forcefully.

Reading about the subject didn't throw up any ideas why one attachment was being sent whereas another was not, but I did notice in someone's code that they were displaying the status of the email component. I thought that I would do this and saw (when I tried sending a pdf file) that the component was encoding the attachment (which took relatively long) and then successfully sending the file.

Although I had hoped that it would be possible to skip encoding the file (the file is already a sequence of bytes), it seems that there is no alternative. It would also seem that the time that the program took to send the email was not in fact connected to the type or size of the attachment, but rather connected to the handshaking which occurs between my client and Gmail. 

During this period, the program is unresponsive; it seems that the only way to make the program responsive whilst sending an email is to hand off the email code to a separate thread. I am somewhat wary of doing so as I have never done any real programming with threads. Also, there is no small amount of material which has to be passed from the program to the thread which complicates matters. It might actually be simpler for the program to spawn a new program whenever the main menu option is chosen; this spawned program can then display all the fields necessary and send the email in its own time without bothering the main program. I'll wait and see how sending emails 'in the field' goes before taking this step.

I have now spent two weeks working on (and documenting) this subject. I have covered in my research a great deal of esoteric material, most of which was unnecessary in retrospect. Sending email is akin to black magic; it's something that 'just happens' (not really dependent on my programming or problem solving skills) and requires in the final analysis boiler-plate code which may or may not be understood. The main thing is that it works and that I don't have to tinker with it again.

After two weeks of almost constant blogging, I now have no idea about what I am going to write about next....


No comments: