Article Index
Nathan M. Andelin   December 2016

IBM i Modernization - The User Interface

(Part 17)

This article discusses the idea of sending email from web browsers. Please click on the following screen shot to try it.


Use Cases

Email is of course a basic necessity for modern business. Large and small services providers offer robust web-based clients - some of which have become hugely popular.

I believe that IBM i would be a great platform for hosting email as a service for thousands of concurrent users similar to Google and Yahoo Mail. However, for purposes of this discussion, let's keep the requirements small.

Email may simply be an appendage to something like a help-desk application that provides a form for submitting requests for support. Email messages and attachments might be forwarded to technicians, for example.

Just The Basics

The form featured in this article is designed for browsers that have implemented the HTML5 specification. The application does the following:

  1. Prompts users to enter their own email address and message text.
  2. The Form's values are sent to an ILE RPG program named IUI105.
  3. The IUI105 program sends an email message to a recipients list, which is maintained in an IBM i data area. It sends a "thank you" email to the originator of the request. It returns a confirmation to the browser.

I considered adding attachments to email messages by using a file-upload utility similar to the one shown in Part 16. I finally chose to keep the scope of the application smaller so that it might be more digestible.

Email Account Inputs

HTML 5 provides for an input element of type "email" for entering email addresses:


<input name="addr" type="email" maxlength="64" style="width:100%; max-width:500px; padding:5;" autofocus placeholder="your@example.com" required pattern="[^ @]*@[^ @]*">


Email inputs invoke some built-in behaviors in HTML5 browsers. Smart phones may show @ and .com keys on their keypads, for example.

Pattern="regular expression" provides basic email-account validation against a regular expression. You can find recommendations for regular expressions via search engine results.

The Form's JavaScript

The send() function is invoked when the form is submitted (via button click or the "enter" key).


function send() {
  reqPost('/rdcaller/send.shtml?rwappid=iui105' ,fm.pd());
  return false;
}


High-level explanation of send():

  • The form's data elements are posted to the server (program IUI105 is called to process it).
  • returning "false" overrides the default form submit (reqPost() uses AJAX instead).

The us() function is invoked by the response from the IUI105 program:


function us(rt) {
  fm.sa('msg','value','');
  fm.sf('addr');
  um.innerHTML = rt;
}


High-level explanation of us():

  • The IUI105 program returns a "thanks" message.
  • The value of the "msg" input element is set to an empty string.
  • The focus is set to the "addr" input element.

Program IUI105

An RPG program named IUI105 responds to the "send" request. The code is as follows:


Program IUI105
      //-----------------------------------------------------------------
      // procedure prototypes
      //-----------------------------------------------------------------

      /copy *libl/qrpglesrc,rdstrapi#1
      /copy *libl/qrpglesrc,rdemlapi#1
      /copy *libl/qrpglesrc,rdwtnapi#1

      //-----------------------------------------------------------------
      // module level data
      //-----------------------------------------------------------------

     d rw            e ds                  extname(rwpgmc) qualified

     d s1              s               *   inz(*null)

     d recipients      s            256a   dtaara(recipients)

     d xeml          e ds                  extname(xeml100p) import
     d                                     qualified

     d xemlmsg         s          32765a   varying import

     d crlf            s              2a   inz(x'0D25')

     d addr            s            256a   varying

      //-----------------------------------------------------------------
      // program entry
      //-----------------------------------------------------------------

     c     *entry        plist
     c                   parm                    rw

      /free

       //-----------------------------------------------------------------
       // set reference to UI template
       //-----------------------------------------------------------------

       if s1 <> *null;
        wtnSetInst(s1);
       endif;

       //-----------------------------------------------------------------
       // branch to subroutines based on requested actions
       //-----------------------------------------------------------------

       select;
        when rw.action = 'INIT';
         exsr do_init;
        when rw.action = 'SEND';
         exsr do_send;
       endsl;

       return;

       //-----------------------------------------------------------------
       // initialization
       //-----------------------------------------------------------------

       begsr do_init;

        s1 = wtnOpen('IUI105');

        in recipients;

        clear xeml;

        xeml.subject = 'IBM i UI Modernization - (Part 17)';
        xeml.sender = 'noreply@rd.radile.com';
        xeml.replyto = xeml.sender;

       endsr;

       //-----------------------------------------------------------------
       // send email to data-area recipients
       //-----------------------------------------------------------------

       begsr do_send;

        addr = %trimr(wtnFldGet('addr'));
        xemlmsg = wtnFldGet('msg');
        xemlmsg = strReplace(xemlmsg:'\n':crlf);
        xeml.recipients = %trimr(recipients);

        emlSend();

       //-----------------------------------------------------------------
       // send "thanks" email to originator
       //-----------------------------------------------------------------

        xeml.message = ' ';

        xemlmsg = 'Thanks for your email @ ' + %char(%date():*usa)
         + ' ' + %char(%time():*hms) + '.';

        xeml.recipients = addr;

        if addr <> '';
         emlSend();
        endif;

       //-----------------------------------------------------------------
       // send "thanks" to browser
       //-----------------------------------------------------------------

        wtnRecSet('US');
        wtnFldSet('um':xemlmsg);
        wtnRecWrt('US');

       endsr;

      /end-free

High-level explanation of program IUI105:

Program IUI105 binds to a service program named RDEMLAPI, which implements an high-level email interface by exporting a procedure named emlSend(), an external data structure named XEML, and a variable-length string named XEMLMSG (in which you can store email message content).

Any ILE program or service program can bind to RDEMLAPI, assign values to XEMLMSG and XEML sub-fields, and call emlSend() to send email messages.

We should review the layout of the XEML data structure that is externally described in file XEML100P:


External File XEML100P
     A                                      UNIQUE
     A          R XEML100R                  TEXT('Email Requests')
     A            SENDER       128A         COLHDG('Sender Email Address')
     A                                      VARLEN
     A            MESSAGE      128A         COLHDG('Message File')
     A                                      VARLEN
     A            SUBJECT      128A         COLHDG('Subject')
     A                                      VARLEN
     A            RECIPIENTS  7936A         COLHDG('Recipients List')
     A                                      VARLEN
     A            CARBONS     7936A         COLHDG('Carbon Copy List')
     A                                      VARLEN
     A            BLINDS      7936A         COLHDG('Blind Copy List')
     A                                      VARLEN
     A            ATTACHS     7936A         COLHDG('Attachments List')
     A                                      VARLEN
     A            REPLYTO      128A         COLHDG('Reply To Address')
     A                                      VARLEN
     A            ORG           64A         COLHDG('Organization')
     A                                      VARLEN
     A            CTYPE          4A         COLHDG('Content Type')
     A            ERRTEXT      128A         COLHDG('Error Message')
     A                                      VARLEN
     A            ERRFLAG        1A         COLHDG('Error Flag')
     A            KEEP           1A         COLHDG('Keep Message Flag')
     A            TS              Z         COLHDG('Timestamp')
     A            ID            10S 0       COLHDG('ID')
     A          K ID

  • SENDER - Assign the sender's email address.
  • MESSAGE - Optionally assign an IFS stream file name to hold the email, otherwise a temporary IFS file is created.
  • SUBJECT - Assign a string that appears in the email "subject" line.
  • RECIPIENTS - Assign a comma separated list of recipient email addresses.
  • CARBONS - Assign a comma separated list of carbon-copy recipients.
  • BLINDS - Assign a comma separated list of blind-carbon-copy recipients.
  • ATTACHS - Assign a comma separated list of IFS stream file attachments.
  • REPLYTO - Optionally assign an email address to reply to (if different from SENDER).
  • ORG - Optionally assign an "organization" that will appear in email headers.
  • CTYPE - Optionally assign "HTML" if the content type is HTML-formatted text (otherwise plain/text is used).
  • ERRTEXT - Contains any error message returned after calling emlSend().
  • ERRFLG - Contains "Y" if emlSend() returns an error.
  • KEEP - Assign "Y" if you want to keep the MESSAGE stream file (the default is to delete it after the email is sent).
  • TS & ID - Timestamp and a unique key are assigned to each email sent.

You can make repeated calls to emlSend() - just altering the xeml.blinds list - when sending bulk email to many recipients. If you assign a new value to the XEMLMSG string, you need to assign a new value to the MESSAGE (IFS file) to send a different email message.

Wrapping Up

There are quite a few use cases for using web browsers and IBM i programs to send email to recipients. Hopefully this article stirs some consideration.