2019-06-23 03:35:23 -07:00
import {
BINARY_ENCODING ,
IExecuteSingleFunctions ,
} from 'n8n-core' ;
import {
2019-10-25 12:38:54 -07:00
IDataObject ,
2019-06-23 03:35:23 -07:00
INodeTypeDescription ,
INodeExecutionData ,
INodeType ,
} from 'n8n-workflow' ;
import { createTransport } from 'nodemailer' ;
2019-10-25 12:38:54 -07:00
import SMTPTransport = require ( 'nodemailer/lib/smtp-transport' ) ;
2019-06-23 03:35:23 -07:00
export class EmailSend implements INodeType {
description : INodeTypeDescription = {
displayName : 'Send Email' ,
name : 'emailSend' ,
icon : 'fa:envelope' ,
group : [ 'output' ] ,
version : 1 ,
description : 'Sends an Email' ,
defaults : {
name : 'Send Email' ,
2019-07-26 02:41:08 -07:00
color : '#00bb88' ,
2019-06-23 03:35:23 -07:00
} ,
inputs : [ 'main' ] ,
outputs : [ 'main' ] ,
credentials : [
{
name : 'smtp' ,
required : true ,
}
] ,
properties : [
2020-02-24 08:21:03 -08:00
// TODO: Add choice for text as text or html (maybe also from name)
2019-06-23 03:35:23 -07:00
{
displayName : 'From Email' ,
name : 'fromEmail' ,
type : 'string' ,
default : '' ,
required : true ,
placeholder : 'admin@example.com' ,
description : 'Email address of the sender optional with name.' ,
} ,
{
displayName : 'To Email' ,
name : 'toEmail' ,
type : 'string' ,
default : '' ,
required : true ,
placeholder : 'info@example.com' ,
description : 'Email address of the recipient.' ,
} ,
2019-10-08 05:40:47 -07:00
{
displayName : 'CC Email' ,
name : 'ccEmail' ,
type : 'string' ,
default : '' ,
required : false ,
placeholder : 'cc@example.com' ,
description : 'Email address of CC recipient.' ,
} ,
2020-02-24 08:21:03 -08:00
{
displayName : 'BCC Email' ,
name : 'bccEmail' ,
type : 'string' ,
default : '' ,
required : false ,
placeholder : 'bcc@example.com' ,
description : 'Email address of BCC recipient.' ,
} ,
2019-06-23 03:35:23 -07:00
{
displayName : 'Subject' ,
name : 'subject' ,
type : 'string' ,
default : '' ,
placeholder : 'My subject line' ,
description : 'Subject line of the email.' ,
} ,
{
displayName : 'Text' ,
name : 'text' ,
type : 'string' ,
typeOptions : {
alwaysOpenEditWindow : true ,
rows : 5 ,
} ,
default : '' ,
description : 'Plain text message of email.' ,
} ,
{
displayName : 'HTML' ,
name : 'html' ,
type : 'string' ,
typeOptions : {
rows : 5 ,
} ,
default : '' ,
description : 'HTML text message of email.' ,
} ,
{
displayName : 'Attachments' ,
name : 'attachments' ,
type : 'string' ,
default : '' ,
description : 'Name of the binary properties which contain<br />data which should be added to email as attachment.<br />Multiple ones can be comma separated.' ,
} ,
2019-10-25 12:38:54 -07:00
{
displayName : 'Options' ,
name : 'options' ,
type : 'collection' ,
placeholder : 'Add Option' ,
default : { } ,
options : [
{
displayName : 'Ignore SSL Issues' ,
name : 'allowUnauthorizedCerts' ,
type : 'boolean' ,
default : false ,
description : 'Do connect even if SSL certificate validation is not possible.' ,
} ,
] ,
} ,
2019-06-23 03:35:23 -07:00
] ,
} ;
async executeSingle ( this : IExecuteSingleFunctions ) : Promise < INodeExecutionData > {
const item = this . getInputData ( ) ;
const fromEmail = this . getNodeParameter ( 'fromEmail' ) as string ;
const toEmail = this . getNodeParameter ( 'toEmail' ) as string ;
2019-10-08 05:40:47 -07:00
const ccEmail = this . getNodeParameter ( 'ccEmail' ) as string ;
2020-02-24 08:21:03 -08:00
const bccEmail = this . getNodeParameter ( 'bccEmail' ) as string ;
2019-06-23 03:35:23 -07:00
const subject = this . getNodeParameter ( 'subject' ) as string ;
const text = this . getNodeParameter ( 'text' ) as string ;
const html = this . getNodeParameter ( 'html' ) as string ;
const attachmentPropertyString = this . getNodeParameter ( 'attachments' ) as string ;
2019-10-25 12:38:54 -07:00
const options = this . getNodeParameter ( 'options' , { } ) as IDataObject ;
2019-06-23 03:35:23 -07:00
const credentials = this . getCredentials ( 'smtp' ) ;
if ( credentials === undefined ) {
throw new Error ( 'No credentials got returned!' ) ;
}
2019-10-25 12:38:54 -07:00
const connectionOptions : SMTPTransport.Options = {
2019-06-23 03:35:23 -07:00
host : credentials.host as string ,
port : credentials.port as number ,
secure : credentials.secure as boolean ,
2019-11-03 10:15:54 -08:00
} ;
if ( credentials . user || credentials . password ) {
2019-10-25 12:38:54 -07:00
// @ts-ignore
2019-11-03 10:15:54 -08:00
connectionOptions . auth = {
2019-06-23 03:35:23 -07:00
user : credentials.user ,
2019-11-03 10:15:54 -08:00
pass : credentials.password
} ;
}
2019-10-25 12:38:54 -07:00
if ( options . allowUnauthorizedCerts === true ) {
connectionOptions . tls = {
rejectUnauthorized : false
} ;
}
const transporter = createTransport ( connectionOptions ) ;
2019-06-23 03:35:23 -07:00
// setup email data with unicode symbols
const mailOptions = {
from : fromEmail ,
to : toEmail ,
2019-10-08 05:40:47 -07:00
cc : ccEmail ,
2020-02-24 08:21:03 -08:00
bcc : bccEmail ,
2019-06-23 03:35:23 -07:00
subject ,
text ,
html ,
} ;
if ( attachmentPropertyString && item . binary ) {
const attachments = [ ] ;
const attachmentProperties : string [ ] = attachmentPropertyString . split ( ',' ) . map ( ( propertyName ) = > {
return propertyName . trim ( ) ;
} ) ;
for ( const propertyName of attachmentProperties ) {
if ( ! item . binary . hasOwnProperty ( propertyName ) ) {
continue ;
}
attachments . push ( {
filename : item.binary [ propertyName ] . fileName || 'unknown' ,
content : Buffer.from ( item . binary [ propertyName ] . data , BINARY_ENCODING ) ,
} ) ;
}
if ( attachments . length ) {
// @ts-ignore
mailOptions . attachments = attachments ;
}
}
// Send the email
const info = await transporter . sendMail ( mailOptions ) ;
return { json : info } ;
}
}