The GetMail object allows your APLX applications to retrieve and manipulate e-mail messages on a mail server, using the POP3 protocol supported by most Internet Service Providers (ISPs) for reading e-mails. (A more complex protocol, IMAP, is sometimes used instead, but is not currently supported by APLX.) It complements the SendMail object, which can be used to send e-mails from your APLX application.
You can use the GetMail object for a number of purposes. For example, you might have an APLX application for which you set up a special mailbox, to which data is sent in e-mail form, analysed, and the reply sent back automatically using the SendMail object. Or you might use it to help process and organise your standard personal e-mails in a way which is more sophisticated than that provided by the filtering and scripting rules provided by ordinary mail programs such as Microsoft's Outlook Express; this might include automatically deleting certain unwanted e-mails before they are downloaded from the server.
Connecting to the mail server
The GetMail object should be created as a top-level object, i.e. not as the child of a Window or other control. You then need set up the following properties, to define the address of the POP3 mail server you are using, your username, and your password (all this information should be available from your ISP or network administrator):
host: This is a character vector, to which you should assign the Internet address of the POP3 server. It can be specified either as a domain name (such as 'pop3.myisp.com'), or directly as an internet node address (such as '220.127.116.11').
port: You can use this property to change the port used by the POP3 connection. For most applications you should leave this set to the default value of 110.
user: The user name for the account should be assigned to this property.
password: The password for the account should be assigned to this property.
You will probably also want to set up the path property. This is a character vector specifying the directory where APLX should place any attachments associated with messages you download.
Next, you need to call the Open method, which establishes the connection with the server. (Note: Whilst you have this connection open, the mailbox will be locked. You should aim to close the connection as soon as you can; if you fail to do so, the POP3 server will eventually time out, close the connection, and abort any pending requests to delete messages). The Open method returns an integer scalar, which indicates whether the connection succeeded. The returned value will be one of 0 = OK, 1 = Could not find host, 2 = Authentication error (i.e. incorrect username or password), 3 = Other error.
Mail1←'⎕' ⎕NEW 'GetMail' Mail1.host←'pop3.supernet.com' Mail1.user←'microapl' Mail1.password←'secret' Mail1.Open 0
Retrieving information about available messages
Once you are successfully connected to the POP3 server, the following read-only properties give information about the messages available for download:
count: The count of messages on the server, as an integer scalar.
messages: Returns a nested matrix describing the messages on the server, with one row per message. The columns (in Index Origin 1) are:
The messages are listed in order, so you can retrieve them by index position using the GetMessage or GetSummary methods. Message indices always start at 1, so the e-mail associated with the first row of the messages matrix can be retrieved as message number 1.
Retrieving individual messages or headers
Whilst you have the POP3 connection open, you can retrieve the full contents of an individual message (into properties of the GetMail object) by calling the GetMessage method. Alternatively, you can call the GetSummary method which retrieves the message headers only, and thus executes much faster, especially if the message is long or has large attachments. Both methods take an integer scalar argument, which is the index (in origin 1) of the message you want to retrieve. (This will be a number in the range 1 to the value of the count property, or the number of rows in the messages property).
Having successfully called GetMessage or GetSummary, you can then access the following read-only properties, which will now contain details of the retrieved e-mail message:
Valid after calling either GetMessage or GetSummary:
subject: The subject of the e-mail, as a character vector.
from: The e-mail address of the sender of the e-mail, as a character vector.
id: The ID of the e-mail, as a character vector. This can be used to identify the e-mail. If the Internet mailing standards have been followed correctly, this should be unique to this particular e-mail message.
header: The raw header of the e-mail, formatted as a character vector, with embedded carriage return (
size: An integer scalar giving the size of the e-mail in bytes.
Valid after calling GetMessage only:
to: The recipients of the e-mail, specified as a comma-delimited list of e-mail addresses.
cc: The list of e-mail addresses to which the message is copied, specified as a comma-delimited list.
replyto: The e-mail address to which any reply to an e-mail should be sent. It is a simple character vector.
date: The timestamp of an e-mail, as a character vector. It is normally formatted in the form 'Tue, 16 Nov 2004 12:17:40 +0000', where the last part is the offset from Greenwich Mean Time as HHMM.
body: The main text of the e-mail in plain text, as a simple character vector with carriage return (
html: The main text of the e-mail as HTML, if the message as sent in HTML form. If the message was sent in plain-text form only, this property will be an empty vector. (Note: You can write the HTML text to a temporary file and use the Browser object to display it.)
attachments: A list of file names which correspond to the attachments of the mail message, as a nested vector of file names. The GetMessage method will have retrieved the attachments and written them out to these files. They will be placed in the directory specified by the path property. If there is a name clash, i.e. an attachment has the same name as an existing file, APLX will append .1, .2 etc to distinguish the different files. If for some reason the attachment cannot be written (for example, if the path property is invalid, or the disk is full), APLX will report a FILE I/O ERROR when you run the GetMessage method.
For example, assuming you have a reference to a GetMail object in Mail1 and have successfully connected to the server, the following function would fetch the Nth e-mail from the server, and display the message in the Session window. Any attachments would also be retrieved and saved to local files.
∇GetMail N  ⍝ Get and display message N  Mail1.GetMessage N  'To: ',Mail1.to  'From: ',Mail1.from  'CC: ',Mail1.cc  'Subject: ',Mail1.subject  'Attachments: ',⍕Mail1.attachments  50⍴'-'  Mail1.body  50⍴'-' ∇
Caution: Before calling the GetMessage method, consider whether you want the message to be deleted, or left on the server, as described in the next paragraph.
Deleting messages on the server
The DeleteMessage method marks a message on the server for deletion. It takes an integer scalar argument, which is the index number of the message to be deleted.
Alternatively, you can set the deleteonread property of the GetMail object to 1. This causes messages which are retrieved using the GetMessage method to be marked for deletion automatically.
The server will not actually delete the messages until the session is successfully completed and you call the Close method. If an error occurs, or if the connection is lost, the message will be left untouched. They will also not be deleted if you call the Reset method.
Closing the connection
Finally, you should call the Close method to terminate the POP3 session. This releases the mailbox lock, and causes the server to remove any messages which have been marked for deletion.
Error reporting and diagnostics
If an error occurs when calling the GetMessage or GetSummary methods, an APL I/O ERROR will be generated. If an error occurs when the connection is being established using the Open method, it will return a non-zero result, as described above. In either case, you can use the status property to find out more about the error. This returns a two-element integer vector. The first element is 1 if the connection to the POP3 server is active, else 0. The second element is the latest error code returned by the underlying operating-system networking code. (See for example, the Windows documentation and include file 'winsock.h' for details on these error codes.)
Another useful diagostic tool is the serverreply property. This returns a character vector containing the status message which the server sent back after a call such as GetMessage or Open. Usually it will begin "+OK..." to indicate success, but if there is a problem (for example, if the mailbox is already locked) it will contain an error message. This can comprise several lines, separated by carriage returns.
Other properties and methods
Reset: This is a method which takes no arguments. It resets the connection to the server. Any pending deletes are cancelled.
timeout: This is an integer scalar property, which allows you to set the timeout for mail operations, in milliseconds.
∇DEMO_GetMail;host;user;password;errcode;messages;count;⎕IO;GM;W  ⍝ Sample function demonstrating use of the GetMail object  ⍝ To run this function, you need an Internet account with  ⍝ a POP3 mail server, and you need to know the host name,  ⍝ user name and password for this account.  ⍝  ⍝ Ask the user for the mail account details  ⍞←'Enter mail server (POP3) host name: ' ⋄ host←⎕DBR⍞  ⍞←'Enter user name: ' ⋄ user←⎕DBR⍞  ⍞←'Enter password: ' ⋄ password←⎕DBR⍞  ⍝  ⍝ Create the GetMail object and set up connection details  ⍝ Don't delete messages on the server when we read them  GM←'⎕' ⎕NEW 'GetMail' ⋄ GM.deleteonread←0  GM.host←host ⋄ GM.user←user ⋄ GM.password←password  ⍝  ⍝ Open the connection to the POP3 server  errcode←GM.Open  :If errcode≠0  :Select errcode  :Case 1  'Could not find host'  :Case 2  'Authentication error'  :Else  'Comms error, error code = ',⍕1↓GM.status  :EndSelect  :Return  :EndIf  ⍝  ⍝ Get list of messages and display them in a Grid object  ⎕IO←1  count←GM.count  :If count>0  'Fetching list of messages from server...'  messages←GM.messages  ⍝ Close connection as soon as possible  ⍝ In a real application, you would fetch or delete selected messages here  GM.Close  ⍝  W←'⎕' ⎕NEW 'Window' ⋄ W.caption←'Messages' ⋄ W.scale←5 ⋄ W.size←500 430  W.Show  W.Grid.New 'Grid' ⋄ W.Grid.align←¯1  W.Grid.headcols←0 ⋄ W.Grid.rows←count ⋄ W.Grid.cols←5  W.Grid.colsize←(1⍴0)150  W.Grid.text←(¯1)(⍳5)('From' 'To' 'Date' 'Subject' 'Size')  W.Grid.value←(⍳count)(⍳5)(messages[;⍳5])  ⍝ Wait for the user to close the window  0 0⍴⎕WE W  :Else  'You have no messages available'  ⍝ Close connection  GM.Close  :EndIf  ⍝ ∇
attachments body cc children class count data date deleteonread events from header host html id messages methods name opened password path port properties replyto self size status subject tie timeout to user
Licensing (Windows and Linux versions)
In the Windows and Linux versions of APLX, the GetMail object is based on the Indy networking classes. The following notices apply to these versions:
THIS SOFTWARE IS PROVIDED BY Chad Z. Hower (Kudzu) and the Indy Pit Crew "AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Copyright © 1996-2010 MicroAPL Ltd