Mail Configuration Comments / Suggestions

Hello Guys,

I’ve been playing with the Mail Service Plugin today, I have a couple of comments and suggestions, I thought I would run them past the community and get your input.

Default Mail Config

At the moment, when sending an email, you have to explicitly configure each email with the settings you define in coldbox.cfc, something like:

// Get a new mail object from the mail service.

local.email = MailService.newMail(argumentCollection=getSetting(“email”));

This configured your payload with all the default settings, such as From, Type, Server etc. However, this felt a unnatural to me, as I expected the service to hand me a configured mail object ready to go.

I would have expected the call to newMail() to give me a mail already configured with the mail settings from my config file, I could then overwrite them on a per-case basis if I needed too.

Is there a specific reason that it doesn’t configure the mail for you?

I’d appreciate your opinions on this.

Thanks guys,

Robert

Robert, I had time to see this.

Few things.

At this point that DOES happen but at time of sending. So when you do say send( mail ) then it looks in the config data for the server,username,password, port and sets it up if not setup already.

Do you think it would be better if we do this at the time of the newMail() call? I found, that having it at the send() makes it transparent, but your actual mail payload does not reflect it though.

Also, what about adding a default from adddress in your mailsettings:

mailSettings = {
server="", username="", password="", port="",
// NEW PARAMS
ssl=true/false, defaultFrom=“addres@gmail.com”, tls=true/false, defaultType=“HTML”
};

What other enhancements can we target for this?

Luis F. Majano
President
Ortus Solutions, Corp

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

The only problem I see is confusion, so if they try to check the send to before the send the developer will get confused and think it is not being set.

My thoughts are that personally I would do it in the instantiation of the object, only to stop confusion later.

Regards,

Andrew Scott

http://www.andyscott.id.au/

Hi Luis / Andrew,

I agree, I think putting these settings in place when the object is instantiated makes very good sense.

Andrews point is quite right, it can be confusing. The other element is that is someone (like me) writes an extended plugin which overwrites the send method, I have to remember to populate the payload with the settings before sending.

I think this should be done on instantiation.

The only other thing I've been pondering about the mail service, is perhaps some form of convention based email view. At the moment to use a view for an email you have to explicitly declare it's location.

I wonder if perhaps, when having a handler method such as registration.thanks() it should look for /views/email/registration/thanks.cfm

I know that rails does something along these lines, and it seems to work quite nicely.

Robert

Can we explore ideas for the mail service? This was my first shot at it in 3.0 and I am pretty sure we can expand it to make it easier to use and much more powerful.

As of now for the 3.0.1 patch I will update the new to add the settings. What about the new settings? Do they make sense? Which ones should we add to the config?

Luis Majano
President
Ortus Solutions, Corp

HI Luis,

I'm more than happy to explore some ideas with you. I think the current mail service is pretty great. I think the main value we can add is in some helper methods to clean up the implementation from the users standpoint.

From what I understand, it currently accepts all the same arguments as the cfmail tag, correct? I think being able to set any/all of these in the settings, and then override on a per-payload basis makes a great deal of sense to me, default from, ssl etc etc.

Other areas that I think could use improvement:

MailParts

At the moment, if I want to send both an HTML and a text version of an email, I have to do something like this:

local.email.addMailPart(charset='utf', type='text/html', body='<p>Here is some text</p>');

and

local.email.addMailPart(charset='utf', type='text/plain', body='Here is some text');

This to me seems a little verbose. I can see exactly why you did it this way, because it mimics the cfmail behaviour, however, in reality, for each mail part you really only have two options, plain of html, and you can only have one of each anyway.

I'd perhaps suggest masking this with some helper functions:

local.email.setHTML('<p>Here is some text</p>');
local.email.setText'('Here is some text');

You could still keep the existing mail part methods in place to maintain backwards compatibility and for those who wish to have more explicit definition over what charset they use etc.

Attachments

As with the mail-parts, these at the moment mimic the behaviour of the cfmail implementation. Which is quite fine, but I think you could perhaps make this simpler again with some helper methods:

addAttchment('/path/to/the/attachment');

again, the current implementation could remain in place, it's just about making general everyday use a little simpler.

Convention Based Views

It'd be great if we could define a set of conventions for views to be used as email, the same way we do for standard events. These could be defined in a particular directory, or conform to a particular name convention. i.e.

Handler called ContactUs.send()

It assumes the use of views:

/views/contactus/send.email.html.cfm
/views/contactus/send.email.plain.cfm

or something along those lines, ensuring you can define views for both email formats.

Helpers For Common Mailparams

Being able to set custom mail params is a great feature in cfmail, but sometimes remember how to define them can be a pain, we should perhaps add helpers to the payload for commonly used ones.

setHighPriority()
setReadReceipt()
setSendReceipt()

Those are my initial thoughts.

Let me know what you think. If you want to discuss anything on IM then let me know.

Cheers Luis,

Robert

Some great stuff!

Here are the updates I made for 3.0.1

  • Added better docs to the functions
  • Added to all setter and addition methods to return this, so you can concatenate them
  • Added the following helper methods
  • setHTML() to set multipart html nicely
  • setText() to set multipart text nicely
  • addAttachments(files) to add attachments to your payload. The files argument can be a single location a list or array of locations to add.
  • setSendReceipt(), setReadReceipt()

I did not do priority headers because cfmail has already a priority attribute.

Can you expand on the conventions?

Luis F. Majano
President
Ortus Solutions, Corp

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

Hey Luis,

Great work my man!

I’m out of the office now as it’s late, I’ll look to expand on my ideas for the conventions tomorrow or thursday as they are still fledgling ideas and i need to think them through a little more.

Thanks for the quick feedback and turn around on my ideas.

Robert

Please continue to do this Luis. I just think it is silly to ever
return nothing or any sort of boolean success flag as CF does with
it's internal functions (this drives me crazy to no end).

Thanks for all the updates!

.brett

Hey Luis,

I’ve spent some time chewing the fat on the convention based views this morning. I see quite a few problems which might be troublesome to overcome.

My initial thoughts were on the idea that people would be sending mails from within their handlers, however, I know may people actually send emails from within the model.

There is also the complication that sometimes you’ll send multiple different emails in a single handler request.

This seems a little more complicated than I initially thought.

Robert

Another, different concept I’ve been considering this morning:

Testing emails has always been a PITA.

My current setup is to have different environment setups, production has a real life SMTP environment, the other a dummy internal server.

In the past (pre-coldbox) I used to write my own mail service script, these would usual have a debug mode, when working in debug mails would always be routed to me as a developer, not the actual ‘to’ address of the email, or not routed through SMTP at all, and instead written to logs etc.

I wonder if something like this would be good? You could have different ‘appenders’ for the mail, so it could be sent to a debug address, written to logs, sent to the tracer or included in the debug panel for the site.

This would make testing emails much easier and more instant.

Robert

I like this. I have the same issues at times and defining settings on a per tier basis is what has helped on sending emails out. Maybe the mail service could be expanded to provide alternative sending behavior. Maybe a way to either send the email or write it to disk.

I think maybe this could be done using the mail settings and also maybe an override in the payload object. Maybe a

toDisk = path

Setting and a toDisk() method in the payload. If that bit is set with with a file destination we write to disk instead of email. Ideas?

Luis Majano
President
Ortus Solutions, Corp
www.ortussolutions.com
www.luismajano.com

I agree. Email by conventions seems fun but maybe not practical as most of the time email is a concern of a domain object. Something we can do is maybe let the mail service plugin have access to the renderer so we could potentially ask the mail service to use a certain view or layout for emailing like a merge template.

Luis Majano
President
Ortus Solutions, Corp
www.ortussolutions.com
www.luismajano.com

Hey Luis,

This was my thinking too. I have a custom mail plugin I have written, which pretty much just overides the send() behaviour to send through a different channel, in my case, postmarkapp.com.

Maybe you’re right, a method to choose some form of appender for the main service would be good, SMTP, File, Log, Tracer, PostMark. People could write their own custom ones too.

I could just write my own plugin to do the file write instead, which is just fine, but it’s not easy to make the switch between that and standard SMTP based on environment, as the wirebox config is the same for both :slight_smile:

Robert

Yes,

Direct access to the renderer maybe a nice approach.

The way that rails handles this, is to have different mailer instances for each use, rather than a generic mail service. So you have a UserMailer which handles all emails user related.

This has a bunch of methods in it Registeration_email(), ForgottenPassword_email() etc, these methods are specifically for email, nothing more.

Conventions are then determined based on which mailer instance you’re using, and the method that’s being used within it.

This however itsn’t really possible when using a generic singular mail service as CB does.

Robert

Ok how about creating a destination protocol object for the mail service. Much like log box appenders. The default protocol is cfmail. Then in the mail settings config we have the following:

Mailsettings.protocol = “cfmail,file,console,path.to.protocol”

Then create a protocol command interface

Interface{
Function send(mail){}
}

Then we could have some built in protocols in the core and then you can build your own and define how sending is achieved.

Luis Majano
President
Ortus Solutions, Corp
www.ortussolutions.com
www.luismajano.com

I think this certainly sounds like a nice way of doing things!

Makes it very switchable based on environment as it’s just a config setting.

Robert

https://coldbox.assembla.com/spaces/coldbox/tickets/1215-creation-of-a-protocol-interface-and-adapter-for-the-mail-service–so-users-can-decide-what-proto—

Luis F. Majano
President
Ortus Solutions, Corp

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

Great Luis!

Would you like me to work the code up for this?

Robert

Sure the more help and ideas we get the better