function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Alaric WimerAlaric Wimer 

How can I extract new Lead information from an email body using Email Services? Need help with String methods..

I am using Email Services and I'm trying to extract field values (First Name, Last Name, Email, Phone, etc.) from the body of the email. Both the sender address and the subject do not contain the information I need.


In my class, I was able to isolate the the text of the email by using the following: 
String emailText = email.plainTextBody;


But I am struggling using String methods to isolate and get the field values from the text. 


Here's an example of the text I have to work with from the body of the email:

"
Requested by: John Doe
johndoe@example.com
Phone: 5555555555
Address of site: 123 Main St, Anywhere CA 12345
Electric Spend: 100 per month
Utility Company: PacifiCorp
Additional information: System Size (Kw): 7.76
Roof Type: Shingles
Roof Pitch: Slight
Shading: Shaded (can improve)
Credit Score: Over 680 Estimate
"
 

Any help is greatly appreciated! Thank you!
Best Answer chosen by Alaric Wimer
Nayana KNayana K
List<String> lstLines = new List<String>();
Lead objLead = new Lead();
String afterRequestedBy = emailText.substringAfter('Requested by:');
String requestedBy = afterRequestedBy.substringBefore('\n');
requestedBy = requestedBy.trim();
objLead.FirstName = requestedBy.substringBefore(' ');
objLead.LastName = requestedBy.substringAfter(' ');
objLead.Company = requestedBy;

String middleContent = afterRequestedBy.substringAfter('\n');
String creditScore = middleContent.substringAfter('Credit Score:');
creditScore = creditScore.substringBefore('\n');
creditScore = creditScore.trim();
objLead.CreditScore__c = creditScore;

middleContent = middleContent.substringBefore('Credit Score:');

/* now, middleContent should only have 
johndoe@example.com
Phone: 5555555555
Address of site: 123 Main St, Anywhere CA 12345
Electric Spend: 100 per month
Utility Company: PacifiCorp
Additional information: System Size (Kw): 7.76
Roof Type: Shingles
Roof Pitch: Slight
Shading: Shaded (can improve)
*/


lstLines = middleContent.split('\n');

String temp;

for(String line: lstLines) {

	if(line.contains('@') && line.contains('.')) {
		objLead.Email = line.trim();
	}
	else if(line.contains('Phone:')){
		temp = line.substringAfter('Phone:');
		objLead.Phone = temp.trim();
	}
	else if(line.contains('Address of site:')){
		temp = line.substringAfter('Address of site:');
		/* objLead.MailingAddress cannot be directly assigned, I believe. Try to assign individual fields like MailingState, MailingCountry, MailingStreet, etc */
	}
	// continue the same pattern
}

 

All Answers

Nayana KNayana K
List<String> lstLines = new List<String>();
lstLines = emailText.split('\n');
Lead objLead = new Lead();
String temp;

for(String line: lstLines) {
	if(line.contains('Requested by:')){
		temp = line.substringAfter('Requested by');
		objLead.Requested_By__c = temp.trim();
	}
	else if(line.contains('@') && line.contains('.')) {
		objLead.Email = line.trim();
	}
	if(line.contains('Phone:')){
		temp = line.substringAfter('Phone:');
		objLead.Phone = temp.trim();
	}
	if(line.contains('Address of site:')){
		temp = line.substringAfter('Address of site:');
		objLead.Electric_Spend__c = temp.trim();
	}
	// continue the same pattern
}

The above is one high level idea which I thought of.
Alaric WimerAlaric Wimer

Thank you very much Nayana. I realized I should probably be more specific. I was getting the wrong email address. I ran a System.debug for the emailText variable to get the real full text that I have to work with, and here's what I got:

"
Solar Reviews <no-reply@solarreviews.com>
Date: Wed, Jul 24, 2019 at 11:40 AM
Subject: Solar-Estimate.org 123454 John has requested a solar quote
To: <alaric.wimer@gmail.com>


Solar Estimate: Compare solar quotes offered by local solar companies
Having trouble viewing this email? click here
<https://www.solarreviews.com/remote/viewemailonline.php?uid=931367&emailid=3272260&email=Casey.creech%40everlightsolar.com>
[image: Solar Reviews Logo] <https://www.solar-estimate.org>

Control Panel <https://www.solarreviews.com/login/?pagename=dashboard>
Your Profile <https://www.solarreviews.com/installers/everlight-solar/>
Support <https://www.solarreviews.com/login/?pagename=dashboard&tab=support>
<https://www.solarreviews.com/>
Solar Lead
If you reply to this email directly it will not be sent to the consumer.
<https://google.com/maps/?q=41.715585256928,-112.09330830615&ll=41.715585256928,-112.09330830615&spn=0.004250,0.011579&t=h&z=19&hl=en>

Lead ID: *719923*

To Everlight Solar,

The following person has requested a quote through one of our websites.

We strongly recommend you try and call this consumer immediately. Research
shows that you are 5x more likely to get in contact with a consumer and
make a sale if you call them within a few minutes after they make a request.


Requested by: John Doe
johndoe@example.com
Phone: 5555555555
Address of site: 123 Main St, Anywhere CA 12345
Electric Spend: 100 per month
Utility Company: PacifiCorp
Additional information: System Size (Kw): 7.76
Roof Type: Shingles
Roof Pitch: Slight
Shading: Shaded (can improve)
Credit Score: Over 680 Estimate


If you would like to *reject* this lead you must log onto your SolarReviews
Control Panel. Click here to logon
<https://www.solarreviews.com/login/?pagename=leads>

*Rejection Policy*
You have a 72 hour limit (excludes holidays and weekends) from when you
receive a lead to reject it.

We do not accept rejections by direct email or phone as we have provided
automated processes through your Control Panel
<https://www.solarreviews.com/login/?pagename=dashboard> to save time for
our Installer Partners, and us.

*Please be aware that rejections affect your priority as our system assigns
and distributes leads to the Installer Partner with the lowest rejection
percentage, and they also get priority on 'Exclusive' leads, and
'Appointment Requests'.* If your rejection percentage exceeds 20% you will
lose the ability to reject leads until your rejection percentage falls
below 20%. In addition, you may be suspended from purchasing leads. We work
to verify each lead to the best of our ability through software and/or
personal contact prior to sending it to you. So there should be no reason
for your rejection percentage to exceed this level.


Time submitted: 07/24/2019

*Regards*

Solar-Estimate

https://www.solar-estimate.org
Solar Reviews.com <https://www.solarreviews.com>
Solar-Estimate.org <https://www.solar-estimate.org>
Solar Panel Talk forum <https://www.solarpaneltalk.com>
*SolarReviews.com*
1625 Broadway
Suite 830 Denver. CO. 80202
office@solarreviews.com
(844) 442-5029

"

Alaric WimerAlaric Wimer
Is there a way I could trim the emailText variable to be just include that middle section? So basically get rid of all the unnecessary text and just have it be the following:

"
Requested by: John Doe
johndoe@example.com
Phone: 5555555555
Address of site: 123 Main St, Anywhere CA 12345
Electric Spend: 100 per month
Utility Company: PacifiCorp
Additional information: System Size (Kw): 7.76
Roof Type: Shingles
Roof Pitch: Slight
Shading: Shaded (can improve)
Credit Score: Over 680 Estimate
"
Nayana KNayana K
So, is the format will be fixed? Like Requested By and ends with Credit score. If that is the case, we can think of extracting only the necessary part?
Alaric WimerAlaric Wimer
Yes it will be fixed. These emails always come in with the same format.
Alaric WimerAlaric Wimer

Here's the solution I came up with, do you think this is the best way to code this?

 

List<String> lstLines = new List<String>();
List<String> leadInfoList  = new List<String>();
lstLines = emailText.split('\n');
String temp;
Integer startIndex;
Integer endIndex;

// Extract relevant information from the email text
for (Integer i = 0; i < lstLines.size(); i++) {
if (lstLines.get(i).contains('Requested by')) { // start of relevant info
        startIndex = i;
    } else if (lstLines.get(i).contains('Address of site')) { // end of relevant info
        endIndex = i;
    }
}
// create new list of just the relevant info
for (Integer i = startIndex; i < endIndex + 1; i++) {
    leadInfoList.add(lstLines.get(i));
}

System.debug(leadInfoList);

// use releavnt info to set lead field values
for (String line: leadInfoList) {
    if (line.contains('Requested by:')) {
        temp = line.substringAfter('Requested by:');
        String fullName = temp.trim();
        String fName    = fullName.substring(0, fullName.indexOf(' '));
        String lName    = fullName.substring(fullName.indexOf(' '));
        newLead.FirstName = fName;
        newLead.LastName  = lName;
        newLead.Company   = fullName;
    } else if (line.contains('@') && line.contains('.')) {
        newLead.Email = line.trim();
    } else  if (line.contains('Phone:')) {
        temp = line.substringAfter('Phone:');
        newLead.Phone = temp.trim();
    } else if (line.contains('Address')) {
        temp = line.substringAfter('Address of site:');
        newLead.MailingAddress = temp.trim();
    } // continue process for more fields if needed
    } // end loop

    insert newLead;
Nayana KNayana K
List<String> lstLines = new List<String>();
Lead objLead = new Lead();
String afterRequestedBy = emailText.substringAfter('Requested by:');
String requestedBy = afterRequestedBy.substringBefore('\n');
requestedBy = requestedBy.trim();
objLead.FirstName = requestedBy.substringBefore(' ');
objLead.LastName = requestedBy.substringAfter(' ');
objLead.Company = requestedBy;

String middleContent = afterRequestedBy.substringAfter('\n');
String creditScore = middleContent.substringAfter('Credit Score:');
creditScore = creditScore.substringBefore('\n');
creditScore = creditScore.trim();
objLead.CreditScore__c = creditScore;

middleContent = middleContent.substringBefore('Credit Score:');

/* now, middleContent should only have 
johndoe@example.com
Phone: 5555555555
Address of site: 123 Main St, Anywhere CA 12345
Electric Spend: 100 per month
Utility Company: PacifiCorp
Additional information: System Size (Kw): 7.76
Roof Type: Shingles
Roof Pitch: Slight
Shading: Shaded (can improve)
*/


lstLines = middleContent.split('\n');

String temp;

for(String line: lstLines) {

	if(line.contains('@') && line.contains('.')) {
		objLead.Email = line.trim();
	}
	else if(line.contains('Phone:')){
		temp = line.substringAfter('Phone:');
		objLead.Phone = temp.trim();
	}
	else if(line.contains('Address of site:')){
		temp = line.substringAfter('Address of site:');
		/* objLead.MailingAddress cannot be directly assigned, I believe. Try to assign individual fields like MailingState, MailingCountry, MailingStreet, etc */
	}
	// continue the same pattern
}

 
This was selected as the best answer
Nayana KNayana K
Did you get a chance to try above code?
 
Alaric WimerAlaric Wimer
Yes, thank you Nayana. You have been a great help!
Alaric WimerAlaric Wimer

Nayana, I just realized I'm having an issue with the Address here. You'll notice the City, State, and Zip Code actually appear on a new line. I bolded the problem area. So my custom Project_State__c and Project_Zip__c are blank when this lead gets created. Do you know how I can get the City ('Anywhere'), the State ('CA'), and the Zip ('12345') to map to Project_City__c, Project_State__c, and Project_Zip__c?

 

"
Requested by: John Doe
johndoe@example.com
Phone: 5555555555
Address of site: 123 Main St
Anywhere CA 12345

Electric Spend: 100 per month
Utility Company: PacifiCorp
Additional information: System Size (Kw): 7.76
Roof Type: Shingles
Roof Pitch: Slight
Shading: Shaded (can improve)
Credit Score: Over 680 Estimate
"

Problem:
User-added image

Nayana KNayana K
Hi Alaric,
Sorry I missed this thread. It is been nearly 13days. Did you get solution?
Nayana KNayana K
lstLines = middleContent.split('\n');

String temp;

for(String line: lstLines) {

	if(line.contains('@') && line.contains('.')) {
		objLead.Email = line.trim();
	}
	else if(line.contains('Phone:')){
		temp = line.substringAfter('Phone:');
		objLead.Phone = temp.trim();
	}
	else if(line.contains('Address of site:')){
		temp = line.substringAfter('Address of site:');
		objLead.Project_Address__c = temp;
		temp = middleContent.substringBetween('Address of site:', 'Electric Spend:');
		temp = temp.substringAfter('\n');
		/* I am not going for split by space and assigning 0th item to city, 1st item to state, 2nd item to zip. Reason: Assuming city can be two words at times. */
		objLead.Project_Zip__c = temp.substringAfterLast(' ');
		temp = temp.substringBeforeLast(' ');
		objLead.Project_State__c = temp.substringAfterLast(' ');
		objLead.Project_City__c = temp.substringBeforeLast(' '); /*if two words city, then should work!*/
	}
	// continue the same pattern
}

Please try this