0

Create a trigger to create a task when account is created, associate the created task to the account and send a email to notify the owner that account and task has been created. Below is the code but i am hitting below error

Apex trigger CreateTaskAssociatedWithAccount caused an unexpected exception, contact your administrator: CreateTaskAssociatedWithAccount: execution of AfterInsert caused by: System.EmailException: SendEmail failed. First exception on row 0; first error: INVALID_EMAIL_ADDRESS, Email address is invalid: User:{[email protected], Id=0055g00000Bze7aAAB}: [toAddresses, User:{[email protected], Id=0055g00000Bze7aAAB}]: Trigger.CreateTaskAssociatedWithAccount: line 34, column 1

Please forgive my bad coding methods I am trying my best.

Trigger CreateTaskAssociatedWithAccount on Account(after Insert){

    List<Task> createtask = new List<Task>();
    List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
    
    for(Account acc: trigger.new){
        //Create task record
        Task t = new Task();
        t.subject = 'Account Created :' + acc.Name;
        t.whatId = acc.Id;
        t.OwnerId = acc.OwnerId;
        t.ActivityDate =  date.today();
        t.Status = 'Not Started';
        createtask.add(t);
    
        //Send Email Notification
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        list<user> sentTo = [Select Email From User where Id =: acc.OwnerId];
        Map<Id,String> userEmail = new Map<Id,String>();
        
        for(User a : sentTo){
            userEmail.put(a.Id, string.valueof(a));
        }
        
        mail.setToAddresses(userEmail.values());
        mail.setSubject('New Account and a Task related to it are created');
        String body = 'A new Account ' + acc.id + '& a new Task has been created';
        mail.setHTMLBody(body);
        mails.add(mail);
        
    }
    
    insert createtask;
    Messaging.sendEmail(mails);
}
1

2 Answers 2

0

EDIT: If your approach continues to simply send the email to one single recipient, whose email is already captured in a contact, lead, or user record, use the solution proposed by @Ankaiah Bandi. In these instances, using setTargetObjectId(targetObjectId) is the best approach because it is faster, simpler, and requires no additional SOQL queries.


To directly answer your question, when you attempt to collect the user emails on these lines:

    for(User a : sentTo){
        userEmail.put(a.Id, string.valueof(a));
    }

You Should be accessing the email of the user, instead of the User object itself:

    for(User a : sentTo){
        userEmail.put(a.Id, String.valueof(a.Email));
    }

After taking a few minutes to look through this, there are several issues with your approach, the most severe being that you have a SOQL query in your loop. Here's a partially re-written trigger that fixes both of these issues:

trigger CreateTaskAssociatedWithAccount on Account(after insert){
    List<Task> tasksToInsert = new List<Task>();
    List<Messaging.SingleEmailMessage> messages = new List<Messaging.SingleEmailMessage>();
    //Container to collect Account Owner IDs, for later bulkified query
    Set<Id> ownerIds = new Set<Id>();
    for(Account acc : (List<Account>) Trigger.new){
        //Create task record
        Task t = new Task();
        t.subject = 'Account Created :' + acc.Name;
        t.whatId = acc.Id;
        t.OwnerId = acc.OwnerId;
        t.ActivityDate =  date.today();
        t.Status = 'Not Started';
        tasksToInsert.add(t);
        // collect the account owner IDs.
        ownerIds.add(acc.OwnerId);
    }
    // You don't want to run SOQL queries inside loops. Instead, aggregate values and query in bulk.
    Map<Id, User> accountOwners = new Map<Id, User>([SELECT Id, Email FROM User WHERE Id IN :ownerIds]);
    for(Account acc: (List<Account>)Trigger.new){    
        //Send Email Notification
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        User recipient = accountOwners.get(acc.OwnerId);
        List<String> recipientEmailAddresses = new List<String>{String.valueOf(recipient.Email)};
        mail.setToAddresses(recipientEmailAddresses);
        mail.setSubject('New Account and a Task related to it are created');
        // You may want to put the account name in here instead?
        String body = 'A new Account ' + acc.id + '& a new Task has been created';
        mail.setHTMLBody(body);
        messages.add(mail);
    }
    
    insert tasksToInsert;
    Messaging.sendEmail(messages);
}
1
  • Thank you so much for the answer......it solved the issue plus I learned something new today :) Aug 20, 2022 at 10:53
0

You can set the setTargetObjectId as Account ownerId in the Messaging.singleEmailMessage object.

you can modify the code as like below.

Trigger CreateTaskAssociatedWithAccount on Account(after Insert){

    List<Task> createtask = new List<Task>();
    List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
    
    for(Account acc: trigger.new){
        //Create task record
        Task t = new Task();
        t.subject = 'Account Created :' + acc.Name;
        t.whatId = acc.Id;
        t.OwnerId = acc.OwnerId;
        t.ActivityDate =  date.today();
        t.Status = 'Not Started';
        createtask.add(t);
        //Send Email Notification
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    //Here directly assign the account ownerid to the setTargetObjectId.         
        mail.setTargetObjectId(acc.OwnerId);
        mail.setSubject('New Account and a Task related to it are created');
        String body = 'A new Account ' + acc.id + '& a new Task has been created';
        mail.setHTMLBody(body);
        mail.setSaveAsActivity(false);
        mails.add(mail);
        
    }
    
    insert createtask;
    Messaging.sendEmail(mails);
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .