+ Start a Discussion
goabhigogoabhigo 

Sending email in trigger - Is there better practice?

Hi,

 

I have written a trigger which creates new records(Payment Schedule object, which has master-detail relationship with opportunity) based on some conditions. In addition it also sends email(a notification email) to all the opportunities related those newly created records.

 

Is there any better approach to do this? Each email will contain data with respect to that opportunity. So I cannot use email templates and workflow to fire it.

 

Kindly suggest whether this is best practice..

Best Answer chosen by Admin (Salesforce Developers) 
bob_buzzardbob_buzzard

Generally speaking it is better to write this type of code in external utility classes as:

 

(1) It is available for other triggers/classes to use (whereas code embedded in a trigger can't be invoked from elsewhere)

(2) It allows you to decide whether you want to respect sharing rules or not

 

I can't see why you would want to use an @future method for this - while that would allow Salesforce to schedule it to run when resources are available, it doesn't seem to benefit you and may lead to delays in sending out the emails.  It would also use up @future calls that may be required elsewhere (for web service callouts for example).

 

As to whether your utility method should be static or not is a matter of personal choice - public static methods can be executed from other classes with no prior setup, whereas you could instantiate a class, populate it with various pieces of information about the emails and then call a method on it to send the emails.  I tend towards static methods myself.

 

I'd also suggest you look at the mass email method if you haven't already - this will allow you to create all the emails and send them in one go.

All Answers

super developersuper developer

Hi

 

For this you can write a class call it from trigger there send emails

 

with singlemailmessege concept.

My OwnMy Own

Hi Abhi, 

 

  What ever the process your trying to do is the better one I feel, instead of writing the code. Use the complete custamization with work flows using the EmailTemplates.

 

 

Cheers,

Prasad

goabhigogoabhigo

Thanks for the reply guys.

Prasad, you are confusing me. Currently I am NOT using email templates and workflows. Instead I am creating the email( using SingleEmailMessage) inside the trigger.

Since the email will be sent to hundreds of opportunities/contacts I am not sure sending it from trigger is good.

Please suggest..

super developersuper developer

For that only you can send mails in class. Call this class from trigger.

goabhigogoabhigo

Ok.

Correct me if I am wrong, inside the for loop of trigger, I should create new instance of class and call the method by using that instance.

 

 

trigger xxx on Object__c(after insert) {
 EmailClass ec;
 // variables
 for(Object__c ob: Trigger.New) {
     ec = new EmailClass();
     // do something
     ec.emailMethod(some parameters); 
 }
}

 

super developersuper developer

collect your parameters in either set or map and call class from outside for loop. And write method as static method (@future methos is better).

My OwnMy Own

 

 

Just go with the other guys implementation. That would be the good solution. 

bob_buzzardbob_buzzard

Generally speaking it is better to write this type of code in external utility classes as:

 

(1) It is available for other triggers/classes to use (whereas code embedded in a trigger can't be invoked from elsewhere)

(2) It allows you to decide whether you want to respect sharing rules or not

 

I can't see why you would want to use an @future method for this - while that would allow Salesforce to schedule it to run when resources are available, it doesn't seem to benefit you and may lead to delays in sending out the emails.  It would also use up @future calls that may be required elsewhere (for web service callouts for example).

 

As to whether your utility method should be static or not is a matter of personal choice - public static methods can be executed from other classes with no prior setup, whereas you could instantiate a class, populate it with various pieces of information about the emails and then call a method on it to send the emails.  I tend towards static methods myself.

 

I'd also suggest you look at the mass email method if you haven't already - this will allow you to create all the emails and send them in one go.

This was selected as the best answer
goabhigogoabhigo

Ahhh, here comes my favorite (future) MVP :)

Thanks Bob.

 

Few doubts,

 

  • Should I go with this approach: Create new instance of class and call the method by using that instance, inside the for loop
  • Or as suggested by 'super developer', collect details of email and call it once, outside for loop.

 

bob_buzzardbob_buzzard

Super developer is correct that it is best to collect all of your information and make a single call out to the method that will be sending the email.

 

If you can though, I'd be inclined to go a bit further and move as much code out of the trigger into external utility classes, as it promotes re-use and allows it to be tested in isolation.  By the same token, there's no point in moving the code out if it can only be used in a trigger context (for example, if you are using addError).

 

Salesforce best practice is to have a single trigger per object, so the less code you have embedded the better, especially when it has to handle lots of scenarios.

super developersuper developer

Hi ,

 

I have told @future is method better why because if there are so many mails need to be send then it will handle automatically by future method.

bob_buzzardbob_buzzard

@future simply means that the method will be called asynchronously.  While this can be useful (and indeed is the only option in some cases), it has some downsides, including:

 

- No guarantee about when it will be executed - in practice, I've never found this to be a problem, but it is a consideration.

- Limited number of calls (200 per user license per 24 hours - and we've broken those limits in the past)

- Can introduce difficulty when handling errors - when a trigger sends the emails, if there are errors its straightforward to rollback the transaction and notify the user.  Using an @future method would require you to write code to notify the user through email or similar.

 

I still don't see how this would add anything in this case - the @future method still has to adhere to governor limits and single/mass email limits. 

WesNolte__cWesNolte__c

Everything Bob's says is true and best practice. Have a look at this article here: http://developer.force.com/cookbook/recipe/email-utility-class

 

It's written by one of the best developers I've ever had work for me, it is super snazzy.

 

Wes

goabhigogoabhigo

Thanks  'super developer' for making Bob clarify the doubts regarding @future. This will be helpful for many developers.

Thanks Wes for the post. It was cool.

Bob, great insight again. Keep the good work.