Nachdem die OpenSource Technologie auf der IBM i eingeführt wurde, ergeben sich völlig neue Möglichkeiten, die RPG Welt um neue Anwendungen zu erweitern. Node.js bietet eine ganze Palette von nützlichen Tools an: Versenden von SMS, Erstellen von PDFs und in unserem Beispiel das Versenden von E-Mails. Das Versenden von E-Mails in UTF-8 Kodierung und als HTML ist mit Bordmitteln nicht so einfach. Mit Node.js geht das sehr gut.

Systemvoraussetzungen

Auf Ihrer Maschine benötigen Sie Node.js, das Sie über das Open Source Package Management oder über YUM (habe ich in einem früheren Artikel beschrieben) installieren.

Damit Sie mit der QSHELL problemlos arbeiten können, müssen Sie die ENVVAR QIBM_MULTI_THREADED auf Y einstellen.

ENVVAR QIBM_MULTI_THREADED auf Y Quelle: Ross

ENVVAR QIBM_MULTI_THREADED auf Y

 

Die neueste Node.js Version ist v18.0.0. 5250>QSH.

QSH-BefehlseingabeQuelle: Ross

QSH-Befehlseingabe

 

Den NodeMailer finden Sie auf www.npmjs.com/package/nodemailer und er wird mit folgendem Command in der QSHELL installiert:

npm i nodemailer

Mit dem Befehl npm ls können Sie sich die installierten Node.js Packages anzeigen lassen.

npm ls Quelle: Ross

npm ls

 

Die Kommunikation zwischen RPG und Node.js

Die Kommunikation zwischen Programmen auf der IBM i inklusive der Parameterübergabe geht über den Befehl CALL. Mit Node.js ist es anders. Grundsätzlich gibt es zwei Möglichkeiten.

  • Über DataQueues: ideal für asynchrone Aufrufe
  • Über Webservice

In diesem Beispiel habe ich mich für den Aufruf über Webservice entschieden. Grundsätzlich funktioniert ein Webservice wie ein CALL, nur dass er auf ein anderes System oder über das Internet erfolgt. Der GET oder POST-Request entspricht dem CALL. Die Definition der Parameter erfolgt im JSON Format. SQL stellt dafür alle notwendigen Funktionen bereit. In unserem Fall benötigen wir nur die Funktion JSON_OBJECT.

Der Webservice funktioniert so:

  • Mit Node.js wird ein Webservice definiert, gestartet und wartet auf POST Anfragen. Er läuft solange, bis der Job beendet wird.
  • Dieser Webservice wird mit der SQL Function QSYS2.HTTP_POST aufgerufen, die drei Parameter hat: URL, Daten und Header.

URL: die Url enthält die IP-Adresse der Maschine, den Port (wird im Node.js Programm definiert) und die Funktion, z.B. http://172.16.0.120:8080/sendmail.

Daten: Für das Versenden einer einfachen E-Mail werden mindestens vier Parameter benötigt: Absenderadresse, Empfängeradresse, Betreff, Mailtext als Text oder HTML. Die Daten erzeugen wir mit folgendem SQL:

values json_object(

  ‚from‘: ‚Rainer_Ross[at]web.de‘,

  ‚to‘:     ‚Rainer_Ross[at]web.de‘,

  ’subject‘: ‚Hallo vom NodeMailer!‘,

  ‚text‘:  “,

  ‚html‘: ‚<h2>Hallo vom NodeMailer!</h2><p>Das ist der Text der Mail</p>‘

);

 

Header: Der aufgerufene Webservice benötigt die Information, in welchem Format die Daten kodiert sind. Das wird über den Header definiert. In unserem Fall: application/json. Wir erzeugen den Header ebenfalls mit JSON_OBJECT:

values json_object(

  ‚header‘: ‚Content-Type,application/json‘

);

 

Jetzt haben wir den kompletten Befehl zum Aufruf des Node.js Programms. Diesen können Sie in ein RPG Programm einbauen:

values QSYS2.HTTP_POST(

  ‚http://172.16.0.120:8080/sendmail‘,

  json_object(

   ‚from‘:    ‚Rainer_Ross[at]web.de‘,

   ‚to‘:      ‚Rainer_Ross[at]web.de‘,

   ’subject‘: ‚Hallo vom NodeMailer!‘,

   ‚text‘:    “,

   ‚html‘:    ‚<h2>Hallo vom NodeMailer!</h2><p>Das ist der Text der Mail</p>‘

  ),

  json_object(

    ‚header‘: ‚Content-Type,application/json‘

  )

);              

 

Das Node.js Programm zum Versenden von E-Mails.

Als erstes erstellen wir den Code für den HTTP-Server, der die POST-Requests entgegen nimmt. Die benötigten Methoden dafür werden über require(‚http‘) geladen. Der Port muss frei sein und darf von keiner anderen Applikation verwendet werden. Der Befehl um die verwendeten Adressen anzuzeigen ist: netstat *cnn.

Das Programm wird mit dem SQL POST Request aufgerufen. Die Daten stehen in der Variablen data. Dann wird die Funktion sendMail mit den Parameterdaten aufgerufen:

const http        = require(‚http‘);

const port        = 8080;

 

http.createServer(function(req, res) {

            console.log(‚URL: ‚                               + req.url);

            console.log(‚Method: ‚               + req.method);

            console.log(‚Content-Type: ‚      + req.headers[‚content-type‘]);

            console.log(‚Content-Length: ‚   + req.headers[‚content-length‘]);

           

            if (req.method === ‚POST‘) {

                        let body = new Array();

                        req.on(‚data‘, function(data) {

                                   body.push(data);

                        })

                        req.on(‚end‘, function() {

                                   let data = JSON.parse(Buffer.concat(body).toString());

                                   sendMail(data).catch(console.error);

                                   res.writeHead(200, {‚Content-Type‘: ‚application/json‘});

                                   res.end(JSON.stringify(response));

                        })

            }

}).listen(port);

 

console.log(‚Server running at Port: ‚ + port);

 

Jetzt folgt der Teil für das Versenden der E-Mails. Sie benötigen einen Host, User und Passwort:

const nodemailer         = require(’nodemailer‘);

 

async function sendMail(data) {

            let transporter = nodemailer.createTransport({

                        host: ’smtp.web.de‘,

                        port: 587,

                        secure: false,               // true for 465, false for other ports

                        debug: false,

                        logger: false,                // Debug logging

                        auth: {

                                   user: ‚rainer‘,

                                   pass: ‚mypassword‘,

                        }

            });

 

            let info = await transporter.sendMail({

                        from:                data.from,

                        to:                    data.to,

                        subject: data.subject,

                        text:                 data.text,

                        html:                data.html

            });

                                                           

            console.log(‚Message sent: %s‘, info.messageId);

}

 

Den Sourcecode des Node.js Programms und das SQL für den Aufruf des Programms können Sie auch bequem hier downloaden.

 

Zu guter Letzt

Das Positive an Node.js ist, dass es asynchron läuft und sehr schnell ist. Ich habe folgende Zeiten gemessen:

  • Der Aufruf des Programms mit HTTP_POST dauert ca. 50 Millisekunden
  • Die Laufzeit des Programms zum Versenden einer Mail dauert im Schnitt 0,4 Sekunden

Hier ein Screenshot: das Programm ist gestartet und erhält einen Request zum Mailversand:

Request zum Mailversand Quelle: Ross

Request zum Mailversand

 

Und die E-Mail als Ergebnis unserer Programmierung:

Die E-MailQuelle: Ross

Die E-Mail

 

Viel Spaß beim Ausprobieren.

Der Autor Rainer Ross schreibt regelmäßig für den TechKnowLetter.

Sie erreichen ihn unter:

Rainer Ross IT-Beratung, Bgm.-Hollweck-Str. 6, 85599 Parsdorf

Ausgezeichnet mit dem Innovationspreis der IBM und Spezialist für Webservices und Webanwendungen auf IBM i so schnell wie Greenscreen.

Beispiel: www.myhofi.com/myapps/HTML/Myapp.html

Tel. (+49) 171/963 79 23 oder 089/413 252 94,

E-Mail: rainer_ross[at]web.de

 

Sechs Ausgaben des TechKnowLetters erhalten Sie hier für 88 Euro.