Since the Remote command have such a huge numbers of commands, the more specialized parts are described in it's own documents. This document describes how to use the @pop3 and @pop3tls commands in detail.

POP3 background

POP3 is a very simple protocol that only is meant to download the mails form a server to you locale computer and delete it from the server. This do not mean that that you not can leave all you messages on the server, but as the number of emails on the server grows, the time to check for new messages will grow exponential. If you plan to leave the mails on the server, you might want to take a look at the imap command instead. You do not have to use any of the advanced methods if you do not want to, and then it can be as easy to use as the pop3 command.

Reference 

Remote("@pop3:command")

Remote("@pop3:command param1")

Remote("@pop3:command param1 param2")

All pop3 commands use a setup for mail server and username/password. Then you do the actions using sub commands that are added after the initial @pop3 command using a : and the command. If the command have more parameters like top, list, uid and ret, then you add this to the end of the sub command using a space, : or , as the separator. You can set the security on the protocol by use the :securitytype command. The default is any, that will test from securest to pain text and use the one that is execpted. Make sure that the last command you use are a :quit command as the line to the server will be open until it times out and possible locked at the server side. Any :dele command to delete messages are not run until the quit command is sent.

Commands

capa None The capability of the pop3 server
dele id Delete the message with number id form the server. The message is not deleted until the quit command is sent.
list [id] List all mails with the size of each message. If id us used as paramter, only that mail is listed with the size.
noop None Do nothing, just keep the line open so it do not time out.
quit None Send a quit command to the server and closes the connection . All messages marked for deletion now is deleted form the server. Make sure to run this command when you are done as some mail server lock the mailbox for as long as the line is open and no quit is run.
retr
id Retrieve the the mail form the server. It will split up the different parts of the mail and save each under separate names in the mails array for the given message.
rset id Remove the delete mark from the previous dele command.
stat None Returns the total size of the mails left on the server and the number of messages.
top id [li]
Returns the header of the message with id and the number of lines of the message given by li parameter. The default value for li is 0 lines that only returns the heading. The values in the heading is added to the emails array in the same manner as for the retr command.
uid [id] Returns the unique id for each message on the server. This is the default when no command is given.

Return values

capabilities A string array of the returned capabilities
mailcount The number of mails in the remote mailbox. This is returned by the stat command.
emails An array of mail data from the server. The fields populated depends on the commands that is used to fetch mail.
-list add id and size
-uid add id and uid
-retr add the action email MIME data with any fields it contains like: To, From, Subject, Body, Date and a lot of others based on what is set in the mail header by the server. It also add capability to read Body with filters for attachments and type data like text, html and multipart. You can also read the data as mime using raw
-top add add the same as retr except body is the number of lines set as param2
emails[idx].body Return the body part of a email. Default is to read the first MIME part in the mail (usually text), but you can ask for specifics like html, attacment or multipart.
Ex. Remote("emails[5].body|html") will return the 6th (0 based index) in html format if it exists.
Ex 2. Remote("emails[3].body|attachmentcount") will return the number of attachments in the 4th email
emails[idx].raw Return the raw MIME data of the complete email
emails[idx].AnyHeader Return data from any header fields the mail has like Subject, To, From, Date and Return-Path.
mailsize The total size of all mails in the mailbox. This is returned by the stat command.

Mail values

The values that can be found in each email object that is fetched by the server can vary based on what is returned by the different server. A few of the values will always be available. 

These are id, To, From, Subject and Body. The id comes from the mail number used to fetch the mail. If you listed mails using uid command, you will also have the uid value. The rest might vary, but all header values starts with an uppercase character. Here are a list of some that we have seen in use:

To, From, Subject, Body, Date, Return-Path, Delivered-To, Received, X-HalOne-ID, DKIM-Signature, X-Received, Return-Path, Message-ID, User-Agent, MIME-Version, Content-Type and Content-Transfer-Encoding. The easiest way to see what's in the buffers is simply to use @json command and set it to a Memo field.

Examples

Setting up an email fetch by pop3 with tls. This returns the statistics of the server. This contains the number of emails on the server and the total size of them.

define temp "Dummy" text 255 .
define temp "mailcount" text .
define temp "mailsize" text .
Dummy := Remote("@current:maildata").
Dummy := Remote("@connect:pop3://pop3.example.com") .
Dummy := Remote("@username:myusername") .
Dummy := Remote("@password:mysecretpassword") .
Dummy := Remote("@pop3:stat") .
Dummy := Remote("@pop3:quit") .
mailcount := Remote("mailcount") .
mailsize := Remote("mailsize") .

Showing a message when you know the id. In this case we use stat to fetch the numbers of mails in the mail box and if the number is not "0" we fetch the mail number 1. The mails returned for the pop3 server usually start at 1 and ends at mailcount.

define temp "Dummy" text 255 .
define temp "mailcount" text .
define temp "mailsize" text .
define temp "to" text 60 .
define temp "subject" text 255 .
Dummy := Remote("@current:maildata").
Dummy := Remote("@connect:pop3://pop3.example.com") .
Dummy := Remote("@username:myusername") .
Dummy := Remote("@password:mysecretpassword") .
Dummy := Remote("@pop3:stat") .
mailcount := Remote("mailcount") .
mailsize := Remote("mailsize") .
if mailcount not = "0" then
  Dummy := Remote("@pop3:retr 1") .
  to := Remote("emails[0].To") .
  subject := Remote("emails[0].Subject") .
end
Dummy := Remote("@pop3:quit") .

Update with new messages to a mail messages table and delete the emails from the mail server. This is the proper way of using PO3. To do this example and the next, we need to create two tables in the application. One for storing the emails and one for being able to manipulate and store the body. The email table should contain the following fields: UID text 30, To text 60, From text 60, Subject text 255, Date text 40, ContentType text 160, MimeVer text 10, ContentTE text 160 and Body memo. The DummyTable should have the following fields: Dymmy text 255, DummyBody memo virtual. You also need to save one (and only one) record in the DummyTable. The DummyTable is then used for create a in memory memo that we can use to add set the body from the Remote command and assign to the Body field in the EMails table when doing an enter a record. The reason for this is the 255 limit on return values in DfW. You have to use memo manipulation command to update a memo field, if not you only get the first 255 characters. The trick is then to use a for DummyTable to read the only record in the table. Now you have an in memory memo that you can use for manipulation. This in memory memo field can then receive the full memo using the third paramer in Remote("field",,DummyMemo) to read the value form Remote store to the memo field in the DummyTable. The memo is now a proper in memory memo that can be used as input to the Body := DummyTable DummyMemo because you can take one memo and set it to another memo. The reason for the placement of the for loot is another oddity in DfW, a relation command like count of and any, only calculates once pr. iteration in a for loop, or jus once in the dql if you do not have a for loop. This means that by placing the for loop right before the memo set command and the count of, you are sure to get the right count value. If you not do this, you only get the first count and use this for the rest of the dql.

define temp "Dummy" text 255 .
define temp "telle" number .
define temp "newmails" number .
define temp "existingmails" number .
define temp "to" text 60 .
define temp "from" text 60 .
define temp "ctype" text 160 .
define temp "ctte" text 160 .
define temp "mver" text 60 .
define temp "uid" text .
define temp "id" text .
define temp "tdate" text .
define temp "subject" text 255 .
define temp "firstline" text 255 .
Dummy := Remote("@current:maildata").
Dummy := Remote("@cleanup").
Dummy := Remote("@connect:pop3://pop3.example.com") .
Dummy := Remote("@username:myusername") .
Dummy := Remote("@password:mysecretpassword") .
Dummy := Remote("@pop3:unid") .
telle := 0 .
existingmails := 0 .
newmails := 0 .
id := Remote(concat("emails[", telle, "].id")) .
while id not = "" do
  uid := Remote(concat("emails[", telle, "].uid")) .
  Dummy := Remote(concat("@pop3:retr ", id)) .
  to := Remote(concat("emails[", telle, "].To")) .
  from := Remote(concat("emails[", telle, "].From")) .
  subject := Remote(concat("emails[", telle, "].Subject")) .
  ctype := Remote(concat("emails[", telle, "].Content-Type")) .
  ctte := Remote(concat("emails[", telle, "].Content-Transfer-Encoding")) .
  mver := Remote(concat("emails[", telle, "].MIME-Version")) .
  tdate := Remote(concat("emails[", telle, "].Date")) .
  for DummyTable ;
    firstline := Remote(concat("emails[", telle, "].Body"),,DummyMemo) .
    if count of EMails with UID = temp uid > 0 then
      existingmails := existingmails + 1 .
    else
      newmails := newmails + 1 .
      enter a record in EMails
        UID := temp uid ;
        To := temp to ;
        From := temp from ;
        Subject := temp subject ;
        ContentType := temp ctype ;
        ContentTE := ctte ;
        MimeVer := mver ;
        Date := temp tdate ;
        Body :=  DummyTable DummyMemo .
    end
  end
  list records
    telle ;
    newmails ;
    existingmails ;
    id ;
    to ;
    from ;
    subject ;
    ctype ;
    firstline ;
    uid .
  Remote(concat("@pop3:dele ", id)) .
  telle := telle + 1 .
  id := Remote(concat("emails[", telle, "].id")) .
end
Dummy := Remote("@pop3:quit") .

Update with new messages to a mail messages table and leave the messages on the server. Stupid to use the POP3 protocol in this manner, but as this is a normal way of doing we will tell you how to. Mind that all messages are loaded into memory and processed each time you do this command, so if you have 10000 messages in you mailbox on the server we will list and process all uids each time you run the command. This is just how the protocol works and also what Outlook does when using this protocol.

define temp "Dummy" text 255 .
define temp "telle" number .
define temp "newmails" number .
define temp "existingmails" number .
define temp "to" text 60 .
define temp "from" text 60 .
define temp "ctype" text 160 .
define temp "ctte" text 160 .
define temp "mver" text 60 .
define temp "uid" text .
define temp "id" text .
define temp "tdate" text .
define temp "subject" text 255 .
define temp "firstline" text 255 .
Dummy := Remote("@current:maildata").
Dummy := Remote("@cleanup").
Dummy := Remote("@connect:pop3://pop3.example.com") .
Dummy := Remote("@username:myusername") .
Dummy := Remote("@password:mysecretpassword") .
Dummy := Remote("@pop3:uid") .
telle := 0 .
existingmails := 0 .
newmails := 0 .
for DummyTable ;
id := Remote(concat("emails[", telle, "].id")) .
while id not = "" do
  uid := Remote(concat("emails[", telle, "].uid")) .
  Dummy := Remote(concat("@pop3:retr ", id)) .
  to := Remote(concat("emails[", telle, "].To")) .
  from := Remote(concat("emails[", telle, "].From")) .
  subject := Remote(concat("emails[", telle, "].Subject")) .
  ctype := Remote(concat("emails[", telle, "].Content-Type")) .
  ctte := Remote(concat("emails[", telle, "].Content-Transfer-Encoding")) .
  mver := Remote(concat("emails[", telle, "].MIME-Version")) .
  tdate := Remote(concat("emails[", telle, "].Date")) .
  for DummyTable ;
    firstline := Remote(concat("emails[", telle, "].Body"),,DummyMemo) .
    if count of EMails with UID = temp uid > 0 then
      existingmails := existingmails + 1 .
    else
      newmails := newmails + 1 .
    enter a record in EMails
      UID := temp uid ;
      To := temp to ;
      From := temp from ;
      Subject := temp subject ;
      ContentType := temp ctype ;
      ContentTE := ctte ;
      MimeVer := mver ;
      Date := temp tdate ;
      Body :=  DummyTable DummyMemo .
  end
  list records
    telle ;
    newmails ;
    existingmails ;
    id ;
    to ;
    from ;
    subject ;
    ctype ;
    firstline ;
    uid .
  -- Remote(concat("@pop3:dele ", id)) .
  telle := telle + 1 .
  id := Remote(concat("emails[", telle, "].id")) .
end
Dummy := Remote("@pop3:quit") .

This concludes the POP3 command. As you can see the only difference between the first and last example is Remote(concat("@pop3:dele ", id)) . This command removes the mail from the server after we have read and stored it. To leave the messages on the server, we just leaves this command out.