Your problem is in this piece of code:
List<Contact> leads = [
SELECT
Id, Email
FROM
Contact
WHERE
Email IN :leadEmails
];
for(Lead singleLead:leads){
singleLead.Status = 'Converted';
}
Notice how yourleads
variable is a List<Contact>
. You then try to loop over that list and cast each item in the List
as a Lead
. You can not do this. Those items are Contact
s.
Try something like this out instead:
trigger ConvertLead on Lead (before insert) {
List<String> leadEmails = new List<String>();
for(Lead lead:Trigger.new){
leadEmails.add(lead.Email);
}
List<Contact> contacts = [
SELECT
Id, Email
FROM
Contact
WHERE
Email IN :leadEmails
];
Set<String> contactEmails = new Set<String>();
for(Contact contact:contacts){
contactEmails.add(contact.Email);
}
for(Lead lead:Trigger.new){
if(contactEmails.contains(lead.Email){
lead.Status = 'Converted';
}
}
}
First off, notice I changed the trigger to a before insert
. The reason for this is because you will receive an error if you attempt to perform a DML operation on the object a trigger is run on in an after
context. The reason this is not allowed is because it would put the code in an infinite loop.
Secondly, notice that I changed your variable names to be more descriptive. I renamed your Contact
list variable to contacts
. This is a core concept of Clean Code.
Thirdly, I used a Set to store all matching Contact emails in the database. This will only keep one value for each of the unique email addresses found by the SOQL query.
Finally, you will notice I removed all DML operations. With the trigger changing to before insert
, there is no need to run a DML operation as the object will be inserted directly after the trigger runs.
NOTE: This is not production ready code. I have not attempted to run it and wrote it specifically on this site. You must write unit tests for it and do your own testing to verify it does what you intend. Good luck!
Please find the Email Template and the Trigger code. This sends an email when a record is created. Hope this will help.
Email Template - (Subjected - Record is created)
Dear {!CreatedBy}
Your Response document is Created. You can download it from {!Document_Location_vgs__c}
Trigger Code
trigger SendEmail on Response_Documents_vgs__c (after insert) {
Response_Documents_vgs__c rdv= trigger.new[0];
ID userid = rdv.CreatedById;
User activeUser = [SELECT Name,Email FROM User WHERE Id = :userid limit 1];
String userName = activeUser.Name;
String userEmail = activeUser.Email;
String location = rdv.Document_Location_vgs__c;
System.debug(rdv.Document_Location_vgs__c);
System.debug(userEmail);
EmailTemplate emailTemplate = [SELECT Id, Subject, HtmlValue, Body FROM EmailTemplate WHERE Id = '00Xi0000000Kbba']; //Email Template's ID
String htmlBody = emailTemplate.HtmlValue;
htmlBody = htmlBody.replace('{!CreatedBy}', userName );
htmlBody = htmlBody.replace('{!Document_Location_vgs__c}', location );
String plainBody = emailTemplate.Body;
plainBody = plainBody.replace('{!CreatedBy}', userName );
plainBody = plainBody.replace('{!Document_Location_vgs__c}', location );
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setSenderDisplayName('Salesforce Support'); //Sender's Display name
mail.setReplyTo('support@salesforce.com'); //Sender's Email ID
mail.setUseSignature(false);
mail.setBccSender(false);
mail.setSaveAsActivity(false);
mail.setSubject(emailTemplate.Subject);
mail.setHtmlBody(htmlBody);
mail.setPlainTextBody(plainBody);
List<String> sendTo = new List<String>();
sendTo.add(userEmail);
mail.setToAddresses(sendTo);
Messaging.sendEmail(new Messaging.SingleEmailmessage[] {mail});
}
Email Received
Best Answer
You don't need soql to do that, you can directly use setTargetObjectId
so your code will be
The advantage of using setTargetObjectId is, you can send unlimited emails to the user. If manually specify email id then you are restricted to only 5000 emails a day limit.
src: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_email_outbound_single.htm