Blog

Luis Majano

November 08, 2021

Spread the word


Share your thoughts

We are so excited to bring you a major release of our cbmailservices module. This module has been around since our initial versions of ColdBox and it has now matured into a modern and fluent library for sending mail.

What Is cbmailservices?

Sending email doesn't have to be complicated or archaic. The ColdBox Mail Services (cbmailservices) module will allow you to send email in a fluent and abstracted way in multiple protocols for many environments. The supported protocols are:

  • CFMail - Traditional cfmail sending
  • File - Write emails to disk
  • InMemory - Store email mementos in an array. Perfect for testing.
  • Null - Ignores emails sent to it.
  • Postmark - Send via the PostMark API Service (https://postmarkapp.com/)

It also sports tons of useful features for mail sending:

  • Async Mail
  • Mail Queues
  • Mail merging of variables
  • Mail attachments, headers and parameters
  • View and Layout+View rendering for mail
  • Mail tracking
  • Multiple mailers
  • Success and Error callbacks
  • So Much More!
newMail( 
	to         : "email@email.com",
	from       : "no_reply@ortussolutions.com",
	subject    : "Mail Services Rock",
	type       : "html", // Can be plain, html, or text
	bodyTokens : { 
		user    : "Luis", 
		product : "ColdBox", 
		link    : event.buildLink( 'home' )
	}
)
.setBody("
    

Dear @user@,

Thank you for downloading @product@, have a great day!

@link@

") .addAttachment( expandPath( "/tmp/reports/report.pdf" ) ) .setReadReceipt( "myemail@email.com" ) .send() .onSuccess( function( result, mail ){ // Process the success }) .onError( function( result, mail ){ // Process the error });

Installing cbmailservices

Just leverage CommandBox and do a nice: box install cbmailservices

Upgrading

If you are using cbmailservices v1.x then you need to read the compatibility docs in order to upgrade your application to this new major version.

Major Features

Let’s investigate now the new features and improvements.

newMail() Helper

The module now registers several new mixin helpers. You can now use newMail() in any handler, and interceptor to start a fluent mailing.

function save( event, rc, prc ){
	...

	newMail( to: "lmajano@ortussolutions.com", subject : "Hello" )
		.setBody( "hello body" )
		.send();
}

Mailer Aliases

You can now register your mailer protocols by using their alias instead of the full CFC path:

  • CFMail
  • File
  • InMemory
  • Null
  • Postmark
moduleSettings = {
	cbMailservices : {
		defaultProtocol : "default",
		mailers : {
			"default" : { class : "CFmail" },
			"memory" : { class : "InMemory" }
		}
	}
}

Mailer WireBox ID

You can now also register ANY WireBox ID or class path as the mailer as well. This will allow you to register mailers that come from your application or any other module.

moduleSettings = {
	cbMailservices : {
		defaultProtocol : "default",
		mailers : {
			"default" : { class : "CFmail" },
			"amazon" : { class : "Mailer@amazonsns" }
		}
	}
}

Protocol Names

All protocols now have a name property that can be used to give a human readable name for all protocols.

/**
 * Initialize the InMemory protocol
 *
 * @properties A map of configuration properties for the protocol
 */
InMemoryProtocol function init( struct properties = {} ){

	variables.name = "InMemory";

	super.init( argumentCollection = arguments );
	variables.mail = [];
	return this;
}

Fluent Mail

The mail payload object has been completely rewritten to allow you to use it to not only construct a mail payload, but to do it in a fluent and more approachable manner. It also allows you to send the payload itself without using the mail service. It also sports a dynamic getter/setter approach for any property stored in the internal config structure. This structure is used to model all the mail settings and properties that will be used to send mail through any protocol.

mailService
	.newMail()
	.configure(
		from    = "info@coldbox.org",
		to      = "automation@coldbox.org",
		subject = "Mail With Params - Hello Luis"
	)
	.setBody( "Hello This is my great unit test" )
	.addMailParam(
		name  = "Disposition-Notification-To",
		value = "info@coldbox.org"
	)
	.addMailParam( name = "Importance", value = "High" )
	.send()
  .onSuccess ( () => {

  } )
  .onError( () = > {
  } );

Success - Errors Callback

The send() method will return itself so you can interact with the payload for either success or failures. You will do so using the following methods:

  • OnError( callback )
  • OnSuccess ( callback )
newMail( to: "lmajano@ortussolutions.com" )
.setSubject( "This is my email confirmation" )
.setBody( "You got in buddy!" )
.send()
  .onSuccess ( () => {

  } )
  .onError( () = > {
  } );

Utility Methods

The following utility methods can be used for inspecting results and errors.

  • getResults() : struct. Empty if no results
  • hasErrors() : boolean. False if no results
  • getResultMessages() : array. Empty if no results

Multiple Transmission Mailer Protocols

The configuration allows for a mailers structure where you can register extra named mailer protocols. You can then use them by name in your mail payloads and set the defaultProtocol as well by it's name.

cbMailservices : {
	// Default Token marker
	tokenMarker : "@",

	// Default protocol
	defaultProtocol : "file",

	// Mailers
	mailers : {
		file : { class: "", properties : {} },
		postmark : { class: "", properties : {} },
		amazon : { class: "", properties : {} }
	},

  ...

}

You can also seed the mailer name in the payload using the setMailer() method to register the name of the mailer to use for the payload or use the mailer configuration key.

// Using constructor
newMail( mailer : "amazon" )

// Using setter
newMail()
	.setMailer( "amazon" )

View Rendering

Allow for the payload to render a view as the body for you instead of doing this manually using the setView() method.

newMail()
.setView(
	view   : "View",
	module : "view module",
	layout : "layout",
	layoutModule : "layout module",
	args   : {}
)

This will tell the mail payload to render the view with or without the layout, pass in the args into the view and layout as the body of the mailing. If you don't pass a layout by convention we will just render the view in isolation.

Async Sending

Thanks to ColdBox futures you can now send the mailing asynchronously via the sendAsync() method. The return is a ColdBox Future object.

future = newMail()
 .setView( "report" )
 .sendAsync()

In Memory Mail Queue

The mail services module will also register a mail scheduler that will iterate and send mail payload asynchronously. The scheduler runs every minute and iterates and sends all mail in the queue. This allows for your application to not wait and block until mail is sent.

All you need to do is use the queue() method. That’s it. The mail services schedule will deliver the mail payload to the right mailer asynchronously and at least every minute schedule.

var taskId = newMail()
 ...
 .queue();

Add Your Comment

Recent Entries

BoxLang 1.0.0 Beta 7 Launched

BoxLang 1.0.0 Beta 7 Launched

We are pleased to announce the release of BoxLang 1.0.0-Beta 7! This latest beta version includes improvements and essential bug fixes, but more importantly it certifies the execution of ColdBox HMVC and TestBox.

What is BoxLang?

BoxLang is a modern dynamic JVM language that can be deployed on multiple runtimes: operating system (Windows/Mac/*nix/Embedded), web server, lambda, iOS, android, web assembly, and more. BoxLang combines many features from different progr

Luis Majano
Luis Majano
July 26, 2024
New BoxLang Feature: Java Method References and Higher-Order Functions

New BoxLang Feature: Java Method References and Higher-Order Functions

We’ve added more goodies to our BoxLang Java interop: method references and higher-order functions. CFML has never let you do these things, making Java Interop feel like a second-class citizen. But with BoxLang, we’re elevating Java integration to a new level.

Maria Jose Herrera
Maria Jose Herrera
July 26, 2024
Level Up Your ColdFusion Skills with our Virtual Live Training: ColdBox from Zero to Hero

Level Up Your ColdFusion Skills with our Virtual Live Training: ColdBox from Zero to Hero

Level Up Your ColdFusion Skills with our Virtual Live Training: ColdBox from Zero to Hero

Are you a CFML developer looking to take your skills to the next level? Look no further than the ColdBox from Zero to Hero Virtual Live Training! This intensive two-day course will equip you with the knowledge and expertise to build robust and scalable applications using ColdBox 7, the latest version of the most popular CFML MVC framework.

What You'll Learn:

  • Master the Fun...

Cristobal Escobar
Cristobal Escobar
July 24, 2024