1

I have a variable which stores the base 64 image in string. I am trying to send that variable in email body using apex code. Below is code snippet:

Public void submitNewForm()
{
    msg='';
    try
    {
        //List<Object> screenImageObject =(List<Object>)JSON.deserializeUntyped(screenImage);
        system.debug('ImageString'+string.valueOf(screenImage));
        system.debug('<img src='+string.valueOf(screenImage)+'/>');
        //insert Evaluation details
        Evaluation__C eval= new Evaluation__c();
        //5004B000001iP6i,5004B000000fqt6,5004B000000fr2S,5004B000000fr2m,5004B000000fr4O,5004B000000fr4s,5004B000000fr78,
        //5004B000000gJ3O,5004B000000gJ3T,5004B000000gJ3Y,5004B000000gJ3d,
        //5004B000000gYYT,5004B000000gYYY,5004B000000gYYd,5004B000000gYYi,5004B000000gYYn
        eval.Case__c='5004B000000gYYn';
        eval.Score__c=0;
        eval.Max_Points__c=0;
        eval.ResultSnapShot__c='<img src='+string.valueOf(screenImage)+'/>';
        insert eval;

        //get Evaluation id 
        String evalId=eval.Id;

        Document doc = new Document(Name='sampleImage');
        doc.Url=string.valueOf(screenImage);
        //mydoc.folderid = UserInfo.getUserId();
        update doc;
        System.debug('@@@@@@@@@@@@@@' + doc);

        //List of all question and answers id's from VF page
        List<Object> allQuesAns =(List<Object>)JSON.deserializeUntyped(questionsAnswersArray);

        //variable to calculate score and max points
        decimal totalScore =0;
        decimal maxPoints =0;

        // loop of all questions
        for (Object quest:allQuesAns)
        {
            Map<String,Object> singleQuesAns=(Map<String, Object>)quest;

            //insert each answer
            Answer__c ans= new Answer__c();
            ans.Question__c=String.valueOf(singleQuesAns.get('ques'));
            ans.Evaluation__c=evalId;
            ans.Answer_Option__c=String.valueOf(singleQuesAns.get('ans'));
            insert ans;

            totalScore=totalScore+decimal.valueOf(String.valueOf(singleQuesAns.get('points')));
            maxPoints=maxPoints+decimal.valueOf(String.valueOf(singleQuesAns.get('maxPoints')));
        }

        //update Score and max points to evaluation
        eval.Score__c=totalScore;
        eval.Max_Points__c=maxPoints;
        update eval;

        sendMail();

        msg= 'success';

    }
    catch(Exception ex)
    {
        msg= ex.getMessage();

    }
    //redirect page to other page
    //PageReference page = ApexPages.currentPage();
    //page.setRedirect(true);
    //return page;
}

Public void sendMail()
{
    // First, reserve email capacity for the current Apex transaction to ensure
// that we won't exceed our daily email limits when sending email after
// the current transaction is committed.
Messaging.reserveSingleEmailCapacity(2);

// Processes and actions involved in the Apex transaction occur next,
// which conclude with sending a single email.

// Now create a new single email message object
// that will send out a single email to the addresses in the To, CC & BCC list.
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

// Strings to hold the email addresses to which you are sending the email.
String[] toAddresses = new String[] {'[email protected]'}; 
String[] ccAddresses = new String[] {'[email protected]'};


// Assign the addresses for the To and CC lists to the mail object.
mail.setToAddresses(toAddresses);
mail.setCcAddresses(ccAddresses);

// Specify the address used when the recipients reply to the email. 
mail.setReplyTo('[email protected]');

// Specify the name used as the display name.
mail.setSenderDisplayName('Company Support');

// Specify the subject line for your email address.
mail.setSubject('New Evaluation Created : ' + Evaluation__c.name);

// Set to True if you want to BCC yourself on the email.
mail.setBccSender(false);

// Optionally append the salesforce.com email signature to the email.
// The email address of the user executing the Apex Code will be used.
mail.setUseSignature(false);

// Specify the text content of the email.
//mail.setPlainTextBody('Your Case: ' + case.Id +' has been created.');

// screenImage is the variable that comes from a different method in the form of string, which I will use in the setHtmlBody method as below:
mail.setHtmlBody('Hello, Below is the image: <img src='+string.valueOf(screenImage)+'/>');

// Send the email you have created.
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}

And I'm calling this method sendMail() in different method where it should fire. I'm doing anything wrong here? Your help would be aprreciate. Thanks.

6
  • 2
    Are you having issues in a production org, or a sandbox org? Have you checked your org's Email deliverability settings? If you're in a sandbox, the default is 'system emails only', which prevents Messaging.sendEmail() from sending emails.
    – Derek F
    Commented May 12, 2016 at 14:41
  • I'm using sandbox. Email deliverability is set to 'All email'. I do receive emails using the email templates. Just with this apex code. Any way where I can debug to find, till where its traversing? Thanks.
    – Viraj
    Commented May 12, 2016 at 14:49
  • 1
    The code you've provided so far looks fine, so if it truly is being called by another method, it should either be running to the end of the method, or throwing an exception (which would be most likely to happen at Messaging.reserveSingleEmailCapacity().) My guess is that the email not being sent is just a symptom, and not the root cause. Your issue probably lies within this 'different method' that is supposed to be calling your sendEmail() method. If you edit your question to include more code, we'll be better able to work towards the root cause.
    – Derek F
    Commented May 12, 2016 at 15:14
  • 1
    An exception could be preventing you from calling your sendMail() method. To figure out if that's the case, you could re-throw an exception after handling it with throw e; so that it causes execution to stop and print the exception (assuming it wouldn't be caught by some other code up the line). You can also put a system.debug('msg = ' + msg); after you handle the exception in submitNewForm(), outside of the catch block, and look through the logs via the dev console to see whether or not you see 'success' or an exception message. At any rate, knowing what msg contains is important.
    – Derek F
    Commented May 12, 2016 at 16:10
  • 1
    @DerekF checked into debug logs which says 23:05:01:881 USER_DEBUG [160]|DEBUG|msg = Update failed. First exception on row 0; first error: MISSING_ARGUMENT, Id not specified in an update call: []
    – Viraj
    Commented May 12, 2016 at 17:37

3 Answers 3

3

Based on our discussion in the comments:

The sendMail() method itself is fine. When this method is called, the only reasons it wouldn't send the email would be:

  1. The email deliverability settings for your org, specifically 'access level', is not set to send 'All Emails'. Other choices would result in an exception being thrown when you call Messaging.sendEmail()

  2. You have sent too many emails in the past 24 hours. Messaging.reserveSingleEmailCapacity() would throw a System.HandledException

Since you didn't mention running into any exceptions, the issue doesn't lie with your sendMail() method.

When you edited your question to include the method that ends up calling your sendMail() method, we ended up working out that the reason why your email wasn't being sent was because you were running into an exception before the point where you called your sendMail() method.

The exception message was

Update failed. First exception on row 0; first error: MISSING_ARGUMENT, Id not specified in an update call: []

From that, it looks like the root cause is in the following lines from your code

Document doc = new Document(Name='sampleImage');
doc.Url=string.valueOf(screenImage);
//mydoc.folderid = UserInfo.getUserId();
update doc;
System.debug('@@@@@@@@@@@@@@' + doc);

I'm not familiar with using Salesforce Documents (I'm more experienced with Content/Libraries and Attachments), but in other situations using the pattern

sObject instance = new sObject(Id = '[some appropriate Id here]');
update instance;

You need to specify the Id of the object instance before you can DML update it. Since you don't set the Id of your Document instance, you get the reported exception.

If you don't have the Id, and only the name, then you'll need to query for the Document record instead.

With the code that you've shared to this point, however, I don't really see what updating a Document is accomplishing. You might be better off removing that bit of code (or making it a class attribute).

1
  • 1
    Bulls eye! You got it right! Deleted those lines and it working. I was trying the upsert the image in the document if you see the code. Receiving the emails now and like charm. Curerntly sending the hard-coded url in the HtmlBody to send the image. Although my problem didn't get solved as I'm looking for inserting a image to Documents and then I need that pull it to a email template. In short, pushing a image to document and getting the same image in the SendMail() method to send an email.
    – Viraj
    Commented May 13, 2016 at 12:33
0

There is no issue in the given code. We can execute the method SendEmail() anywhere in apex class, it will just send the email using standard salesforce class mentioned:-

Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });

Let me know in case you face any errors or issues.

1
  • As I mentioned in the question, unable to trace where it's going wrong.
    – Viraj
    Commented May 12, 2016 at 14:55
0

Its worth noting that when SFDC is executing test methods (ie Unit Tests), it will not send any outbound email. It will report back Success in the SendEmailResult object and there will be no exceptions. The logs will show EMAIL_QUEUE events as well, but the SMTP server will not be contacted.

See also: https://salesforce.stackexchange.com/a/49458/11055

You must log in to answer this question.

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