Since the Remote command have such a huge number of parameters, we have to split the documentation into several documents. This document describes the SMTP part of remote lookup.

SMTP background

SMTP stand for the "Simple Mail Transfer Protocol" and is one of the back bone protocols that makes us able to send email to each other. Almost all email transferred on the internet uses this protocol. In the early days every one could use port 25 on their local computer to send mail to others, but nowadays this probably would result in all mails stopped by spam filters or by your ISP (Internet Service Provider) before it is sent. Most ISP block outgoing port 25 nowadays, so to send mail that will be sent and not blocked by spam filters, you must use a valid external smpt server  as your relay. This is usually done by connecting to port 587 (TLS) or 465 (SMTPS) and login using a username password and then let this valid and globally recognized server do the mail sending on behalf of you.

Reference

Remote("@smtp:command")

Remote("@smtp:command param")

All smtp commands use a setup for mail server and username/password. Then you do the actions using sub commands that are added after the initial @smtp command using a : and the command. If the command takes a parameter like the to and from sub command, you add that after a space to the end of the command string like Remote("@smtp:from mymail@example.com").

Commands

capa
None Return what capabilities the server has. All the capabilities are stored as an array of strings to the capabilities array..
copy idx
Copy an email from fetched mails store to the outgoing mail store. You can use this to manipulate a mail that you have got from you mail server and send it.
expn None Expand the recipients. This can be used on server that support this command to expand groups to recipients.
from email The email address this mail is sent from. This is what the server reports and not the same as the from in mail header. If no from name is set, the from in mail header will be added instead. I none is found, the send command will fail.
logout None Closes connection to server.
send None Send to prepared mail using the smtp server set up in connection using the user name and password set. The send command uses it's best effort to collect all necessary information needed either from the mail header or the smtp commands.
to email Add an email address to the recipient list. It do not clear any previous entries. To start over use toclear command first. The list added using the to command are the one used when sending email, if it not is set, the first "To:" in the mail header is used.
toclear None Clear the email recipient list. This is important if you reuse the mail for more than one recipient as the to command just keep adding to the list.

The commands are used to do action specific to smtp, but the actual mail message are created by using standard set value commands to the "mail" special command. 

The mail message store

To compose a mail using Remote, you use the special "mail" variable. 

mail.Body Set a plain text body for a simple mail
mail.Body.attachment Set a new attachment for each time this is called. The second parameter is the file name of the file to attach. The routine will try to figure out the mime type of the attachment by looking for the file extension in the registry and use the registered Content Type from there. If not found, the attachment will get the default attachment mime type application/octet-stream.
mail.Body.html Set the text/html part of a multi part mail.
mail.Body.text Set the text/plain part of a multi part mail.
mail.Body.raw Set only body as raw mime format that you have composed your self. Mind that this command will not add any correct Content-Type with boundaries to the header, so you must do this manually your self as well.
mail.From The mail address this mail will report it is from in the mail header. If there are any none ascii charcters, the mail address will be Q encoded in the ANSI-charset you computer is set up with. In Western-Europa this is ISO-8859-1. This address will be used at the real from address if you do not use the smtp:from command.
mail.header
Set all of the mail header loading a manually crafted mail heading. Make sure you do this before setting any other value to the heading as it will clear any other values.
mail.Subject The subject this mail will be sent with. If there are any none ascii charcters, the subject will be Q encoded in the ANSI-charset you computer is set up with. In Western-Europa this is ISO-8859-1.
mail.raw You can use this command to load your own mime into the mail.
mail.To The mail address this mail will be reported it is to in the header. If there are any none ascii charcters, the mail address will be Q encoded in the ANSI-charset you computer is set up with. In Western-Europa this is ISO-8859-1. This address will be used at the real to address if you do not use the smtp:to command.
mail.Any-Capitalized You can use any name for a MIME header as long as you follow the RFC naming and format and the command starts on a CAPITAL letter. This can be used for ex.: CC, Date, Message-ID or any other valid MIME heading. You can also use it to override the default MIME-Version, Content-Type etc. that are set as defaults by the system. You have to set this as the last command before a smtp:send as any mail.Body.text etc. will override you settings. Mind that this will possible render the mail unreadable if not set correctly, so make sure you fetch the default and update this to get the correct boundary values that are auto generated by the other commands.

All values set to mail using upper case first letter will be added to the MIME mail header. All MIME mail headers have the form "Content-Type: the value" followed by a CR/LF, so if you call a Remote("mail.Content-Type=text/plain; charset=utf-8; format=flowed") this will be added as the Content-Type in the mail header. You can use any name to add any type of heading as long as the Value name starts on a CAPTIAL letter. There are a few headers that always should be added. This is From, To and Subject. The better information you add the more likely you are to get past the spam filters.

The body of the mail can consist of several parts (ref. MIME). The simplest version of a mail is plain text. This can be set by Remote("mail.Body=Hi this is my mail body plain text."). You can also use the form Remote("mail.Body=","memo:MyMemoBodyField") in GUI context to read a memo field into the mail body as plain text or use the memo field as second parameter directly if you are in a for context in a DQL. If you want to add a plain text and a html part you can do that by using the form Remote("mail.Body.text=The plain text version") and Remote("mail.Body.html="<p>The html version</p>"). The body also support "attachment" and "raw" where raw is for you to set the body in MIME format your self. Attachment can be added several times to add more than one attachment. Examples of all format will follow.

Examples

Setting up a simple email for sending using smtp and tls for login. The :587 tells us that this probably are a server using tls, but the send command will probe for the best matching security routine by starting with the most secure and trying the least secure last. The smpt:to and smtp:from will be picked from the mail header fields mail.To and mail.From. It you add a mail.CC as well, that will also be added to send recipient list before a smtp:send command are done.

define temp "Dummy" text 255 .
Dummy := Remote("@current:maildata").
Dummy := Remote("@cleanup").
Dummy := Remote("@connect:smtp://smtp.example.com:587") .
Dummy := Remote("@username:myusername") .
Dummy := Remote("@password:mysecretpassword") .
Dummy := Remote("mail.From=myemail@example.com") .
Dummy := Remote("mail.To=someotheremail@example.com") .
Dummy := Remote("mail.Subject=Mail test") .
Dummy := Remote("mail.Body=Hi, this is a mail test.") .
Dummy := Remote("@smtp:send") .
Dummy := Remote("@smtp:logout") .

Setting up and email with a plain text and a html version of the same text.

define temp "Dummy" text 255 .
Dummy := Remote("@current:maildata").
Dummy := Remote("@cleanup").
Dummy := Remote("@connect:smtp://smtp.example.com:587") .
Dummy := Remote("@username:myusername") .
Dummy := Remote("@password:mysecretpassword") .
Dummy := Remote("mail.From=myemail@example.com") .
Dummy := Remote("mail.To=someotheremail@example.com") .
Dummy := Remote("mail.Subject=Mail test") .
Dummy := Remote("mail.Body.text=Hi, this is a mail test. Kind regards Me") .
Dummy := Remote("mail.Body.html=<p>Hi,</p><p>this is a mail test.</p><br><p>Kind regards</p><p>Me</p>") .
Dummy := Remote("@smtp:send") .
Dummy := Remote("@smtp:logout") .

Sending mail to all on a mailing list by setting up one email and adding many recipients. There might be servers that have a limit on how many recipients you can have on an email, so it is important to not violate the ISPs rules when creating a routine like this. Later on we will show a routine that will create an individual mail for each user by using MemoExecDQL. For creating this you will need a relation with the name AddressBook and at least two fields: EMail text and OnMailingList yes/no. The commad smtp:to will add each of the email addresses that not is blank to the internal to field. The smtp:to is not the same as mail.To that is set earlier in the mail. The mail.To and mail.CC will be used if not the smtp:to is set, but if the smtp:to is set this will override all values set in the mail.To and mail.CC. What is set in the mail heading must not be the same as what is set in the recipients, but be careful as this might render you mail to spam in a spam filter. The example reads the mail text and html from two memo fields named TextMail andHTML mail that can be found in the form this ExecDQL is run. The form "memo:MemFieldName" is used to fetch the in memory version of a Memo field found on the current form. The if command used to only set actual emails to the smtp:to is important as a empty smtp:to will clear all recipients.

define temp "Dummy" text 255 .
Dummy := Remote("@current:maildata").
Dummy := Remote("@cleanup").
Dummy := Remote("@connect:smtp://smtp.example.com:587") .
Dummy := Remote("@username:myusername") .
Dummy := Remote("@password:mysecretpassword") .
Dummy := Remote("@stmp:from myemail@example.com") .
Dummy := Remote("mail.From=example.com <mailinglist@example.com>") .
Dummy := Remote("mail.To=mailinglist@example.com") .
Dummy := Remote("mail.Subject=Mail test") .
Dummy := Remote("mail.Body.text=" , "memo:TextMail") .
Dummy := Remote("mail.Body.html=" , "memo:HTMLMail") .
for AddressBook with OnMalingList = yes ;
  if not EMail = "" then
    Dummy := Remote("@smtp:to",EMail) .
  end
end
Dummy := Remote("@smtp:send") .
Dummy := Remote("@smtp:logout") .

Sending mails from a mail queue. The mail que will then hold the mail message in html and text, the subject and who it is to.

define temp "Dummy" text 255 .
Dummy := Remote("@current:maildata").
Dummy := Remote("@cleanup").
Dummy := Remote("@connect:smtp://smtp.example.com:587") .
Dummy := Remote("@username:myusername") .
Dummy := Remote("@password:mysecretpassword") .
Dummy := Remote("@stmp:from myemail@example.com") .
for MailQueue with MailIsSent = no ;
  Dummy := Remote("mail=") . -- clear the mail
  Dummy := Remote("mail.From=myemail@example.com") .
  Dummy := Remote("mail.To=", MailTo ) .
  Dummy := Remote("mail.Subject=", Subject) .
  Dummy := Remote("mail.Body.text=", TextMail) .
  Dummy := Remote("mail.Body.html=", HTMLMail) .
  Dummy := Remote("@smtp:send") .
  modify records
    MaiIsSent := yes .
end
Dummy := Remote("@smtp:logout") .

Sending mail with two files as attachment

define temp "Dummy" text 255 .
Dummy := Remote("@current:maildata").
Dummy := Remote("@cleanup").
Dummy := Remote("@connect:smtp://smtp.example.com:587") .
Dummy := Remote("@username:myusername") .
Dummy := Remote("@password:mysecretpassword") .
Dummy := Remote("mail.From=myemail@example.com") .
Dummy := Remote("mail.To=someotheremail@example.com") .
Dummy := Remote("mail.Subject=Mail test with two attachments") .
Dummy := Remote("mail.Body.text=" , "memo:TextMail") .
Dummy := Remote("mail.Body.html=" , "memo:HTMLMail") .
Dummy := Remote("mail.Body.attachment=C:\user\me\Documents\pdf1.pdf") .
Dummy := Remote("mail.Body.attachment=C:\user\me\Documents\pdf1.pdf") .
Dummy := Remote("@smtp:send") .
Dummy := Remote("@smtp:logout") .

Sending a mail where you supply the body in MIME format. Mind that we have to supply a correct Content-Type header field that also contains the correct boundary that can be found in your body stored in the memo field.

define temp "Dummy" text 255 .
Dummy := Remote("@current:maildata").
Dummy := Remote("@cleanup").
Dummy := Remote("@connect:smtp://smtp.example.com:587") .
Dummy := Remote("@username:myusername") .
Dummy := Remote("@password:mysecretpassword") .
Dummy := Remote("mail.From=someotheremail@example.com") .
Dummy := Remote("mail.To=someotheremail@example.com") .
Dummy := Remote("mail.Subject=Mail test with two attachments") .
Dummy := Remote("mail.Body.raw=" , "memo:MIMEBody") .
Dummy := Remote("mail.Content-Type=multipart/mixed; boundary="----00081C01D1066B3CDB7E20") .
Dummy := Remote("@smtp:send") .
Dummy := Remote("@smtp:logout") .

Sending a mail where you supply the entire mail as MIME.

define temp "Dummy" text 255 .
Dummy := Remote("@current:maildata").
Dummy := Remote("@cleanup").
Dummy := Remote("@connect:smtp://smtp.example.com:587") .
Dummy := Remote("@username:myusername") .
Dummy := Remote("@password:mysecretpassword") .
Dummy := Remote("@stmp:from myemail@example.com") .
Dummy := Remote("@stmp:to someotheremail@example.com") .
Dummy := Remote("mail.raw=" , "memo:MIMEMail") .
Dummy := Remote("@smtp:send") .
Dummy := Remote("@smtp:logout") .

More examples might be found in forum or other books.