Indy send email with receivers having UTF-8 characters

delphi, email, indy, smtp, utf-8

Solution

Recipients.Add.Address := myReceiver; // cyrillic symbols! like 'Роман Безяк <roman_bezjak@yahoo.com>'

If `myReceiver` contains both name and email address, you need to use the `TIdEMailAddressItem.Text` property instead of the `TIdEMailAddressItem.Address` property:

Recipients.Add.Text := myReceiver; // cyrillic symbols! like 'Роман Безяк <roman_bezjak@yahoo.com>'
// Name becomes 'Роман Безяк'
// Address becomes 'roman_bezjak@yahoo.com'...

The `TIdEmailAddressItem.Text` property setter method parses the input string and splits it into the `TIdEmailAddressItem.Name` and `TIdEmailAddressItem.Address` properties accordingly.

The `TIdEmailAddressItem.Address` property has no setter method at all, so whatever you assign is used as-is.

When encoding an email, the `TIdEmailAddressItem.Name` value gets MIME-encoded per RFC 2047 if any non-ASCII characters are present. The `TIdEmailAddressItem.Address` value does not get MIME-encoded, due to an assumption that email addresses only ever contain ASCII characters (Unicode email addresses do exist but are not commonly used yet). Email headers must be in ASCII, so you are seeing `Роман Безяк` become `?????????` because you stuck it in the `TIdEmailAddressItem.Address` property and it got converted as-is to ASCII (where non-ASCII characters become `?`) without being MIME-encoded.

So, by separating the `Name` from the `Address`, you should see `Роман Безяк` being handled correctly.

Problem

I'm trying to send an email with the `TIdSMTP` component in Indy 10 and the list of my receivers has Unicode characters in it (like `Роман Безяк <roman_bezjak@yahoo.com>`). But when the mail is sent, in the `To` header of the email I see this: `"?????????" <roman_bezjak@yahoo.com>`. Can anyone help me fix this encoding problem? This is how my procedure looks like : ``` procedure TMailClientForm.btnSendEmailClick(Sender: TObject); var mes : TIdMessage; i : Integer; begin with SMTPClient do begin Host := serverHost; Port := SmtpServerPort; Username := myUserName; Password := myPassword; UseTLS := utUseImplicitTLS; end; try mes := tidmessage.Create(nil); try with mes do begin ContentType := 'text/plain'; ClearBody; Body.Text := memoEmailBody.Text; Subject := txtEmailSubject.text; From.Address := SMTPClient.Username; From.Name := myName; // cyrillic symbols! Recipients.Add.Address := myReceiver; // cyrillic symbols! like 'Роман Безяк <roman_bezjak@yahoo.com>' CharSet := 'utf-8'; end; if fileNames.Count > 0 then // attachments - the files are in the stringlist fileNames mes.ContentType := 'multipart/mixed'; for i := 0 to fileNames.count - 1 do begin if FileExists(fileNames[i]) then TIdAttachmentFile.Create(mes.MessageParts, fileNames[i]); end; try try try SMTPClient.Connect; except on e : Exception do begin MessageDlg('ERROR=' + SMTPClient.LastCmdResult.Text.Text, mtError, [mbOK], 0); Exit; end; end; try SMTPClient.Send(mes); except on e : Exception do begin MessageDlg('ERROR=' + SMTPClient.LastCmdResult.Text.Text, mtError, [mbOK], 0); Exit; end; end; finally if SMTPClient.Connected then SMTPClient.Disconnect; end; fileNames.clear; except on e:exception do begin MessageDlg(e.message, mtError, [mbOK], 0); end; end; finally mes.Free; end; except on e:exception do begin MessageDlg(e.message, mtError, [mbOK], 0); end; end; end; ```

Original source