IBM Support

API QtmsCreateSendEmail (Create and Send MIME E-mail) RPG IV Sample

How To


Summary

API QtmsCreateSendEmail (Create and Send MIME E-mail).
This API became available with OS release V7R1. It caters for both creating the MIME note and sending it through SMTP.
https://www.ibm.com/docs/en/i/7.5?topic=ssw_ibm_i_75/apis/qtmscreatesendemail.html
This article is presenting a simple use case of sending an email to one user.
The sample is written in RPG IV language and assumes the prerequisites which are documented in the API have all been implemented.
The sample is not written to include extensive error handling capability.

Objective

The sample is written in RPG IV language and assumes the prerequisites which are documented in the API have all been implemented.
Notes:
  • Recipient Formats RCPT0100 Format
  • This sample is using hard coded values.
 
  dcl-ds emailRecipients;
    emailRcpCCSID  int(10) inz(0);         // 0=default
    emailRcpType   int(10) inz(0);         // 1=cc, 2=bcc, 0=normal
    emailRcpOffset int(10) inz(16);        // Offset to recipient address
    emailRcpLength int(10) inz(17);        // Length of recipient address
    emailRcp       char(17);               // Recipient address
  end-ds;   
If QtmsCreateSendEmail fails with TCP5308 "CCSID <some big number> not supported" when more than one recipient is set, then the description of RCPT0100 Format could have been misinterpreted.
Review this document for a potential cause: QtmsCreateSendEmail fails with TCP5308
The sample is hard coding the values in the main line for setting the NOTE0100 Format.
"Offset" subfields in the API data structures
The data structures that are passed as parameters to the API have "offset" subfields that indicate the offset of some of the information in the data structure. An offset indicates the point in a data structure where specific data starts.
To determine the offset of a subfield in RPG
  • If you know the position of the subfield, the offset is the value of the position minus 1. For example, if a subfield is at position 17, it is at offset 16.
  • If you don't know the position of the subfield, or if it might change, you can use the %ADDR built-in function to determine the offset. You subtract the address of the data structure from the address of the subfield.
You can determine from the API format section in the documentation where the field that you want to extract is located within the receiver variable.  If you use offsets correctly, your program can extract specific pieces of data from the structure.
In the API documentation, an offset is shown in both decimal and hexadecimal form. Depending on the high-level language that you use, either offset might be helpful. For CL and RPG, you normally use the decimal offset. With either offset, you must remember whether your language works with the offset from a base of 0 or a base of 1. The API format tables are prepared for languages that work from a base of 0, but not all languages can use this base. CL and RPG, for example, work from a base of 1, so you need to add 1 to the decimal value of each offset. 
**free
//All Sample Code contained herein is provided to you "AS IS"
//without any warranties of any kind. THE IMPLIED WARRANTIES OF
//MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//NON-INFRINGMENT ARE EXPRESSLY DISCLAIMED.
//SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED
//WARRANTIES, SO THE ABOVE EXCLUSIONS MAY NOT APPLY TO YOU.  IN NO
//EVENT WILL IBM BE LIABLE TO ANY PARTY FOR ANY DIRECT, INDIRECT,
//SPECIAL OR OTHER CONSEQUENTIAL DAMAGES FOR ANY USE OF THE SAMPLE
//CODE INCLUDING, WITHOUT LIMITATION, ANY LOST PROFITS, BUSINESS
//INTERRUPTION, LOSS OF PROGRAMS OR OTHER DATA ON YOUR INFORMATION
//HANDLING SYSTEM OR OTHERWISE, EVEN IF WE ARE EXPRESSLY ADVISED OF
//THE POSSIBILITY OF SUCH DAMAGES.

// CRTRPGMOD MODULE(<yourlib>/EML4ME) SRCFILE(<yourlib>/QRPGLESRC)
// CRTPGM PGM(<yourlib>/EML4ME) BNDSRVPGM((QTCP/QTMSCRTSNM)) ACTGRP(*CALLER)

ctl-opt main(testEmail);

dcl-pr testEmail extpgm('EML4ME');
end-pr;

//
//* Main Procedure
//
dcl-proc testEmail;
  dcl-pi *n;
  end-pi;
  // QtmsCreateSendEmail API
  dcl-pr qtmsCreateSendEmail extproc('QtmsCreateSendEmail');
    *n char(60)     const;                 // 1)Recipient array
    *n int(10)      value;                 // 2)Number of recipients
    *n char(8)      const;                 // 3)Format name of recipient array
    *n char(5120)   const;                 // 4)Note
    *n char(8)      const;                 // 5)Format name of note
    *n char(60)     const options(*omit);  // 6)Attachment array
    *n int(10)      value;                 // 7)Number of attachments
    *n char(8)      const options(*omit);  // 8)Format name of attachment array
    *n char(265);                          // 9)Error Code
  end-pr;
  //
  // Recipient RCPT0100 Format
  //
  dcl-ds emailRecipients;
    emailRcpCCSID  int(10) inz(0);         // 0=default
    emailRcpType   int(10) inz(0);         // 1=cc, 2=bcc, 0=normal
    emailRcpOffset int(10) inz(16);        // Offset to recipient address
    emailRcpLength int(10) inz(17);        // Length of recipient address
    emailRcp       char(17);               // Recipient address
  end-ds;
  //
  // NOTE0100 Format
  //
  dcl-ds emailNote0100;
    emailNoteCCSID     int(10) inz(0);     // Input CCSID 0=default
    emailNoteOffsetPW  int(10) inz(0);     // Offset to password must be zero for Note sec 0
    emailNoteLengthPW  int(10) inz(0);     // Length of password must be zero for Note sec 0
    emailNoteOffsetSub int(10) inz(0);     // Offset to subject, set below in main line
    emailNoteLengthSub int(10) inz;        // Length of subject, set below in main line
    emailNoteOffset    int(10) inz(0);     // Offset to note, set below in main line
    emailNoteLength    int(10) inz;        // Length of note
    emailNoteSecurity  int(10) inz;        // Note security level, 0 = unencrypted, unsigned
    emailNoteContent   int(10) inz;        // Note content type, 1=text/html, 0=text/plain
    emailNotePassword  char(250) inz('0'); // Password
    emailNoteSubject   char(250) inz;      // Subject
    emailNote          char(250) inz;      // Note
  end-ds;
  // Error Code parameter for IBM i APIs
  // The following link contains usage suggestions
  // https://www.ibm.com/support/pages/proper-usage-error-code-parameter-apis
  dcl-ds emailErrorDS;
    emApiErrorBytesProvided  int(10) inz(0);   // 0 = Get exception if the API fails
    emApiErrorBytesAvailable int(10) inz;
    emApiErrorMessageID      char(7) inz;
    *n                       char(1) inz;
    emApiErrorText           char(500) inz;
  end-ds;
  //
  // main line processing
  //
  emailRcp           = %TRIM('myemail@my.domain');
  emailNoteSubject   = 'Test E-mail from using this API';
  emailNote          = 'This is a test e-mail, please disregard.';
  emailNoteLengthSub = %len(%trim(emailNoteSubject));  // get the length of the subject
  emailNoteLength    = %len(%trim(emailNote));         // get the length of the note
  //use %addr to set offset for subject
  emailNoteOffsetSub = %addr(emailNoteSubject) - %addr(emailNote0100);
  // use %addr to set offset for subject
  emailNoteOffset    = %addr(emailNote) - %addr(emailNote0100);

  callp qtmsCreateSendEmail(emailRecipients:1:'RCPT0100':
                            emailNote0100:'NOTE0100':*OMIT:
                            0:*OMIT:
                            emailErrorDS);
  return;
end-proc;   
The program can be called from OS400 command line:
CALL <yourlib/EML4ME>
 This is an example of the email when viewed in MS Outlook.
Sample email

 

Document Location

Worldwide

[{"Type":"MASTER","Line of Business":{"code":"LOB57","label":"Power"},"Business Unit":{"code":"BU058","label":"IBM Infrastructure w\/TPS"},"Product":{"code":"SWG60","label":"IBM i"},"ARM Category":[{"code":"a8m3p000000hB4rAAE","label":"API"}],"ARM Case Number":"","Platform":[{"code":"PF012","label":"IBM i"}],"Version":"All Versions"}]

Document Information

Modified date:
24 November 2023

UID

ibm17082720