LiveCode LessonsLiveCode LessonsHow To - Step-By-Step Guides To Tasks In LiveCodeTSNetHow to use tsNet to display an e-mail message from an IMAP account

How to use tsNet to display an e-mail message from an IMAP account

Introduction

tsNet can be used to connect to e-mail servers via the IMAP protocol in order to interact with the messages stored in an e-mail mailbox.

This lesson shows how you can get a list of messages stored in an e-mail inbox via IMAP and then retrieve an e-mail's contents.

Lay out the Stack

To begin with, let's retrieve a list of all the messages currently in the Inbox.

Create a new stack then drag a button and a scrolling list field onto it.

Set the name of this field to "Message List" and change the name of the button to "Get Message List".

Save this stack.

Create the Script

Edit the script of the button that you placed on the stack by right clicking on the button and selecting "edit script".

Add the following code.

on mouseUp
   -- This is the IMAP server that you want to connect to, use "imaps://" to specify an SSL connection is to be made
   put "imaps://example.com" into tURL
   
   -- Add the IMAP server username and password into the tSettings array to be passed to the tsNet calls
   put "username" into tSettings["username"]
   put "password" into tSettings["password"]
   
   -- Send a command to the IMAP server to tell it we want to perform operations against the INBOX
   put "SELECT INBOX" into tCommand
   put tsNetCustomSync(tURL, tCommand, tHeaders, tRecvHeaders, tResult, tBytes, tSettings) into tData
   
   if tResult is 0 then
      -- Send a command to the IMAP server to tell it to list all messages that are not deleted
      put "SEARCH NOT DELETED" into tCommand
      put tsNetCustomSync(tURL, tCommand, tHeaders, tRecvHeaders, tResult, tBytes, tSettings) into tData
      
      if tResult is 0 then
         -- The request is successful, so tData will now contain a space separate listed of message UIDs
         -- preceded by "* SEARCH"
         
         -- Delete "* SEARCH" from the response
         delete word 1 to 2 of tData
         
         -- Convert the space delimited list of message UIDs to a return delimited list
         replace space with cr in tData
         
         -- Display the list to the user
         put tData into field "Message List"
      else
         -- Otherwise an error has occurred, advise the user
         answer "Error reading message list:" && tResult
      end if
   else
      -- Otherwise an error has occurred, advise the user
      answer "Error connecting to server:" && tResult
   end if
end mouseUp
Click to copy

What this first script is going to do

You will notice that this script uses the tsNetCustomSync function twice.  This tsNet function allows you to send custom messages to a server.

The IMAP protocol has a series of commands that can be sent in order to perform various queries and tasks.  In this case, we are performing two tasks:

  1. "SELECT INBOX" - This tells the IMAP server that the next command being sent is going to be performed on the user's Inbox.
  2. "SEARCH NOT DELETED" - This command returns a space separated list of message UIDs that are currently in the selected mailbox folder (in this case, the Inbox) that have not been marked for deletion.

Test

Switch to Run mode and click the button.

Now for the next part...

As you can see in the screenshot above, the data returned in the field is a list of message UIDs.  These UIDs are used when requesting the contents of a particular message or interacting with it in any other way (marking it as read, deleting it, etc...).

You now have a list of messages which with the use of a scrolling field, your users have now been provided a way to select a message.  The next step is to be able to display the contents of a message that has been selected from this list.  Follow these instructions in order to achieve this aim.

Drag another button and a field onto the stack that you have already created with the previous steps.

Set the name of this field to "Message Contents" and change the name of the newly added button to "Read Message".

Save this stack.

Create the Script

Edit the script of new button that you placed on the stack by right clicking it and selecting "edit script".

Add the following code.

on mouseUp
   -- This is the IMAP server that you want to connect to, use "imaps://" to specify an SSL connection is to be made
   put "imaps://example.com" into tURL
   
   -- Add the IMAP server username and password into the tSettings array to be passed to the tsNet calls
   put "username" into tSettings["username"]
   put "password" into tSettings["password"]
   
   -- Make sure the user has selected a message to view
   if the selectedText of field "Message List" is empty then
      answer "You must select a message to display"
      exit mouseUp
   end if
   
   -- Generate a URL which uniquely specifies the selected message (by message UID) in the INBOX of the IMAP server above
   put tURL & "/INBOX/;UID=" & the selectedText of field "Message List" into tMessageURL
   
   -- Issue a tsNetGetSync call with the URL created above, this will return the complete e-mail message
   -- specified by the URL
   put tsNetGetSync(tMessageURL, tHeaders, tRecvHeaders, tResult, tBytes, tSettings) into tData
   
   if tResult is 0 then
      -- Display the message to the user
      put "Message contents:" & cr & cr & tData into field "Message Contents"
   else
      -- Otherwise an error has occurred, advise the user
      answer tResult
   end if
end mouseUp
Click to copy

Test

Switch to Run mode and click the button.

Summary

At this point, you have written all the code to retrieve an e-mail via IMAP.

In the code of the second button, please note that there are no calls to tsNetCustomSync.  In a similar manner to interacting with FTP and SFTP servers, you will use the tsNetGet* commands when retrieving a message or folder list.

This example uses the tsNetGetSync command with a specially formatted URL to indicate that we are retrieving a message with UID 212 from the Inbox in order to download the full message source to the LiveCode application.

2 Comments

John

Hi,
I really have no idea what I am doing but I did find a few bugs - or at least 'bugs' that affected my set up. Not sure why, but maybe I can learn something by posting the following.

Both were in the "Read Message" button on this line:

put tURL & "/INBOX/;UID=" & the selectedText of field "Message List" into tMessageURL

I first got an error "tsneter: (3) URL using bad/illegal format or missing URL".

I checked the selectedText of field "Message List" and noted selected text was 1 more char longer than what the number on the line was, ie, 1, returned the number of chars = 2 (I assume a space was included or return char). So I corrected this by adding word 1 of the selectedText of field "Message List"

Then I got this error message:
"tsneter: (78) Remote file not found".

I replaced UID with MAILINDEX (found this after a google search).

Then the script worked as written.

Any thoughts? What can I learn from this?

Panos Merakos

Dear John,

Thank you for the comment.

The tenet library uses the curl library. Looking at curl's docs (https://everything.curl.dev/usingcurl/reademail), it seems both UID and MAILINDEX are valid - but I think for the use-case of this lesson we have to use MAILINDEX. I'll investigate and update the lesson if this is the case.

Thank you for spotting this.

Kind regards,
Panos
--

Add your comment

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.