Search This Blog

Showing posts with label email. Show all posts
Showing posts with label email. Show all posts

Friday, September 6, 2019

Sending emails

The OpenAF included plugin Email allows to easily send emails from any OpenAF script. Let's check it using a simple example:

plugin("Email");
var email = new Email("smtp.gmail.com", "my.email@gmail.com", true, true, false);
email.login("my.email@gmail.com", "myAppPassword");
email.send("Something is wrong", "Something was detected to be very wrong.", [ "someone@somewhere.com" ], [], [], "my.email@gmail.com");

Step by step

Let's translate each line. After including the plugin Email we created a new Email instance for the SMTP server "smtp.gmail.com" for the email account "my.email@gmail.com", turned SSL and TLS on and specified the email wasn't going to contain any HTML.

// Email(aSMTPServer, theFromEmailAddress, useSSL, useTLS, containsHTML)
var email = new Email("smtp.gmail.com", "my.email@gmail.com", true, true, false);

The Email plugin will try to "guess" the right ports to access the SMTP server but if you need to force it you can do it:

email.setPort(12345);

The next step was authenticating with the SMTP server:

email.login(aLogin, aPassword);

And then finally we sent the simple email:

// email.send(aSubjectString, aMessageString, anArrayOfTOs, anArrayOfCCs, anArrayOfBCCs, aFromEmailAddress)
email.send("Something is wrong", "Something was detected to be very wrong.", [ "someone@somewhere.com" ], [], [], "my.email@gmail.com");

How to send a HTML email

To send a HTML email first you will need to specify it on the Email instance creation:

var email = new Email("smtp.gmail.com", "my.email@gmail.com", true, true, true);

Afterwards you add the HTML using the .setHTML function:

email.setHTML("<h1>BIG NEWS</h1>Everything is <b>okay</b>.");

So, if we just defined the email contents why should we defined aMessageString on the email.send function? In case the email client doesn't support HTML emails the aMessageString parameter of the email.send function will be used.

Adding attachments

To add an attachment use the function email.addAttachment:

email.addAttachment("/my/folder/with/attach1.pdf");

Adding images for the HTML content

If you use HTML content you will probably also want to include images. These aren't the usual regular attachments and there is actually 3 options available:

Embed image files

email.setHTML("<html>...<img src=\"cid:myimage.png\"/>...</html>");
email.embedFile("/some/path/myimage.png", "myimage.pn");

Embed image URLs

email.setHTML("<html>...<img src=\"cid:myimage\"/>...</html>");
email.embedURL("https://some.server/some/image.jpg", "myimage");

Automatic embedding images and reference them by URL

email.setHTML("<html>...<img src="https://some.server/some/image.jpg"/>...</html>");
email.addExternalImage("https://some.server/some/image.jpg");

How to debug

After creating the new Email instance just add:

email.getEmailObj().setDebug(true);

Once the email sending operation starts all communication with the SMTP server will be output to stdout/stderr.

Monday, August 19, 2019

Check if an email address is valid for sending emails

Whenever you have a list of email addresses you might wonder if the email address provided really exists or if it's a "dummy" email. Since internet email does not provide any delivery guarantees nor there exists any reply standard (or obligation) from target domains to reply back that the email address does not exist what can you check to clean cases like "my.name@you.wont.find.me" automatically?

The options are:
  • Find if the domain really exists
  • Find if the domain has any email servers associated
Both can easily be checked by performing DNS lookups. Most operating systems provide the command "nslookup" to easily lookup this information.

Note: There are several types of entries in DNS records. For example the entry type "A" means the IP4 address associated with the domain record while "MX" means the email server associated with the domain record.

An easy way to implement this is to use the Google Public DNS-over-HTTPS service. This allows you to easily retrieve the info needed throw a public REST call.
Here is an example of usage in OpenAF scripting:
function(checkEmail) {
   var dom = email.split(/@/)[1]; 
   var res = $rest({ uriQuery: true })
             .get("https://dns.google.com/resolve", { 
                name: "gmail.com", 
                type: 255 
             });

   return { 
      exists: isDef(res) && isDef(res.Answer),
      hasMXRecords: (isDef(res.Answer)) 
                      ? $from(res.Answer).equals("type", 15).any()
                      : false
   } 
}
Executing this function for some examples (valid at the time of writing):
// goo.gl is a google url shortener service, it exists but no emails can't be sent to it
> checkEmail("abc@goo.gl") 
{
   "exists": true,
   "hasMXRecords": false
}

// gmail.com exists and emails can be sent to it
> checkEmail("abc@gmail.com") 
{
   "exists": true,
   "hasMXRecords": true
}

// miguel.com is a domain bought to be resold but doesn't have a site nor email can be sent to it
> checkEmail("abc@miguel.com")
{
   "exists": false,
   "hasMXRecords": false
}

// nuno.com is a japanese textil company, so the domain exists and emails can be sent to it
> checkEmail("nuno@nuno.com")
{
   "exists": true,
   "hasMXRecords": true
}

// finally, my.name@you.wont.find.me (yes, it exists and it's a site)
> checkEmail("my.name@you.wont.find.me")
{
   "exists": true,
   "hasMXRecords": false
}

Sunday, August 18, 2019

Sending emails from oJob

Sending emails from oJob is made easy due to the oJobEmail.yaml include from the oJob-common opack. As we other common ojobs the idea is to be easy to use. Let's look at a very simple example:

ojob:
  opacks:
    - oJob-common

include:
  - oJobEmail.yaml

jobs:
  # -----------------------
  - name: Send a test email
    to  : oJob Send email
    args:
      from       : "my.email@gmail.com"
      server     : "smtp.gmail.com"         # for example
      credentials:
        user: "my.email@gmail.com"
        pass: "myAppPassword"
      useSSL     : true
      useTLS     : true
      to         : "someone@somewhere.com"
      subject    : "My test email"
      output     : "This is a test email to test sending emails from oJob"
      debug      : false

todo:
  - Send a test email

This example will send an email from my.email@gmail.com to someone@somewhere.com with a test subject a email message.

SMTP server settings

Depending on the SMTP email servers you might need to use different settings:

Setting Type Default Description
useSSL boolean false If the SMTP connection should use SSL (can use also TLS).
useTLS boolean false If the SMTP connection should use TLS (can use also SSL).
port number 25/587/465 Specify the port to contact the SMTP server.
server string n/a The server address.
credentials map n/a A map with user and pass to use to authenticate on SMTP servers.
debug boolean false Very useful to debug SMTP connections by showing all the communication between oJob and the SMTP server.

Email basic settings

For the email specifics you can see in the example the use of the from, to, subject and output fields. The other possible fields are also the obvious:

Setting Type Description
from string A string representing the "from" address.
to string/array An array or a string of "to" addresses.
cc string/array An array or a string of "cc" addresses.
bcc string/array An array or a string of "bcc" addresses.
subject string The text subject of the email message.
output string The text message of the email message.
isHTML boolean Specifies, if true, that the output is in HTML format.
altOutput string If isHTML = true and the end client doesn't support HTML this will be the alternative output to show.

Sending attachments

To send any file as an attachment just use "addAttachments":

      addAttachments:
        - name    : file.txt
          file    : /some/path/file.txt
        - name    : secondFile.txt
          file    : /some/path/secondFile.txt

Adding images to HTML emails

You have three options:

Embed image URLs

      isHTML   : true
      output   : "<html>...<img src=\"cid:myimage\"/>...</html>"
      embedURLs:
        - name: myimage
          url : https://some.server/some/image.jpg

Embed image files

      isHTML        : true
      output        : "<html>...<img src=\"cid:myimage.png\"/>...</html>"
      embedFiles:
        - name    : myimage.png
          file    : /some/path/myimage.png

Automatic embedding images and reference them by URL

      isHTML   : true
      output   : "<html>...<img src="https://some.server/some/image.jpg"/>...</html>"
      addImages:
        - https://some.server/some/image.jpg

Using arrays with parallel

OpenAF is a mix of Javascript and Java, but "pure" javascript isn't "thread-safe" in the Java world. Nevertheless be...