ChatGPT Lead Scoring

Goal: Score a lead using only HubSpot API and OpenAI API

ChatGPT Lead Scoring

Goal: Score a lead using only HubSpot API and OpenAI API

Tools: OpenAI API, NodeJS, HubSpot API

In this article I will walk you through the process of scoring a lead using only a prompt and lead data. Lead scoring is an essential aspect of any successful CRM strategy. It helps prioritize businesses leads and focus their efforts on those with the highest potential for conversion. However, traditional lead scoring methods are often limited in their accuracy and precision, relying static on data such as demographics and website behavior.

The Score

In lead scoring, there are two main types of data that can be used to evaluate leads: explicit and implicit. Explicit data is the information that a lead provides directly, such as their name, email address Implicit or title. job, data, on the other hand, is more subtle and is gathered from a lead’s behavior, such as their website activity, opens email, and clicks. Behavioral is data an essential aspect of lead scoring as it provides insights into a lead’s interests and likelihood to convert. This data includes the pages they visit, how long they spend on each page, and any forms they fill out. By analyzing this information, businesses can identify patterns and develop a better understanding of a lead’s intent and propensity to convert. Demographic data, including factors such as age, gender, location, and job title, is also commonly used in lead scoring. This data helps to provide a broad understanding of a lead’s characteristics and can be useful in identifying trends and patterns among different groups. Overall, the combination of implicit and explicit data, behavioral and demographic data can provide a comprehensive picture of a lead’s potential to convert, allowing businesses to prioritize their efforts and focus on those most likely to lead to a sale.

The Prompt

The general idea for ChatGPT lead scoring is to provide lead data + a pre prompt so we always get a score that can be processed in the same way. I have found that the closer to the end of the text a directive is, the more likely it is to be respected. Its best to put formatting information towards the end of your prompt to ensure the AI will respect them. I use this formula to regularly get good answers.

<Pre-Prompt>
<Response-Format>
<Data>

Here is an example of what this may look like. This is broken out by system and user prompt so it can be used with the gpt-3.5-turbo model.

<System Prompt>
You are a lead scoring expert that scores leads from 0-100
based on how likely they are to convert to paying customers. You score
each lead with a implicit, explicit, behavior, demographics, and
overall score.

You should only repond in this format for each score:
Implicit Score:<implicit_score>,Reason:<implicit_score_reason>
Explicit Score:<explicit_score>,Reason:<explicit_score_reason>
Behavior Score:<behavior_score>,Reason:<behavior_score_reason>
Demographic Score:<demographic_score>,Reason:<domographic_score_reason>
Overall Score:<overall_score>, Reason:<overall_score_reason>

<User>
Please score this lead using the following data.
Lead Data:
firstName: David
lastName: Richards
websiteVisits: 10
leadSource: Facebook Ad
email: david.richards.tech@corp.com

One benefit of ChatGPT lead scoring is its ability to provide more transparency into the decision-making process. Traditional lead scoring methods are often black-box models, meaning that it is difficult to understand how the final score is calculated. However, with ChatGPT, businesses can track and analyze each data point in real-time, providing insights into which factors are most influential in predicting a lead’s likelihood to convert.

The Code

In this section I will walk through the NodeJS code for getting lead data from HubSpot API and making a request to OpenAI API to get a lead score. Once we have the lead score, we will write that back to HubSpot.

Getting a Lead from HubSpot API. In HubSpot Leads are a type of Contact in the system so we will actually be getting a Contact of type Lead.

const hubspot = require('@hubspot/api-client')
const hubspotClient = new hubspot.Client({ accessKey: 'XXXX' })

const getContactProperites = async () => {
const apiResponse = await hubspotClient.crm.properties.coreApi.getAll('contact', false)
return apiResponse.results.map(x => x.name)
}

const getHubSpotContact = async (contactId) => {
const properties = await getContactProperites()
return hubspotClient.crm.contacts.basicApi.getById(contactId, properties)
}

Now that we have the Contact data we can send it OpenAI API to get a score for the lead data.


const formatScores = (lines) => {
var scoreMap = {}
for (let i = 0; i < lines.length; i++) {
try {
const line = lines[i]
const colonSplit = line.split(':')
const scoreType = colonSplit[0].trim()
const score = colonSplit[1].split(',')[0].trim()
const reason = colonSplit[2].trim()
scoreMap[scoreType] = { score: parseInt(score), reason: reason }
} catch (e) {
console.log('Failed to parse score')
scoreMap = undefined
}
}
return scoreMap
}

const scoreContact = async (contact) => {
var systemPrompt = 'You are a lead scoring genius that scores leads 0-100 based on how likely they are to convert to paying customers. You score each lead with a implicit, explicit, behavior, demographics, and overall score.
You only repond in this format for each score:'

systemPrompt += '\nImplicit Score:<implicit_score>,Reason:<implicit_score_reason>'
systemPrompt += '\nExplicit Score:<explicit_score>,Reason:<explicit_score_reason>'
systemPrompt += '\nBehavior Score:<behavior_score>,Reason:<behavior_score_reason>'
systemPrompt += '\nDemographic Score:<demographic_score>,Reason:<domographic_score_reason>'
systemPrompt += '\nOverall Score:<overall_score>, Reason:<overall_score_reason>'

var prompt = 'Please score this lead using the following data.'
prompt += '\n\nLead Data:\n'
Object.keys(contact.properties).forEach(key => {
if (contact.properties[key] === null) return
// Do not include previous lead scores in the request
if (key in skipProperites) return
prompt += '- ' + key + ': ' + contact.properties[key] + '\n'
})

const aiRes = await openai.createChatCompletion({
model: 'gpt-3.5-turbo',
messages: [
{role: 'system', content: systemPrompt},
{role: 'user', content: prompt}
],
n: 1,
temperature: 0
})
const lines = aiRes.data.choices[0].message.content.trim().split('\n')
return formatScores(lines)
}

With this formatted score we can now print or write the score back to the Lead. In HubSpot we can create custom properties to hold the different scores and score reasons. First lets walk through the code to generate new properties in HubSpot.

const createProperites = async (hubspotClient) => {
const promises = []

scorePropertyList.forEach(p => {
const propReq = createProperitesReq(p['name'], p['label'], p['type'], p['fieldType'])
promises.push(hubspotClient.crm.properties.coreApi.create('contacts', propReq))
})

scoreReasonPropertyList.forEach(p => {
const propReq = createProperitesReq(p['name'], p['label'], p['type'], p['fieldType'])
promises.push(hubspotClient.crm.properties.coreApi.create('contacts', propReq))
})

return await Promise.all(promises)
}

const scorePropertyList = [
{
key: 'Implicit Score',
name: 'implicit_gpt_lead_score',
label: 'Implicit GPT Lead Score',
type: 'number',
fieldType: 'number'
},
{
key: 'Explicit Score',
name: 'explicit_gpt_lead_score',
label: 'Explicit GPT Lead Score',
type: 'number',
fieldType: 'number'
},
{
key: 'Behavior Score',
name: 'behavior_gpt_lead_score',
label: 'Behavior GPT Lead Score',
type: 'number',
fieldType: 'number'
},
{
key: 'Demographic Score',
name: 'demographic_gpt_lead_score',
label: 'Demographic GPT Lead Score',
type: 'number',
fieldType: 'number'
},
{
key: 'Overall Score',
name: 'overall_gpt_lead_score',
label: 'Overall GPT Lead Score',
type: 'number',
fieldType: 'number'
}
]
const scoreReasonPropertyList = [
{
key: 'Implicit Score',
name: 'implicit_gpt_lead_score_reason',
label: 'Implicit GPT Lead Score Reason',
type: 'string',
fieldType: 'text'
},
{
key: 'Explicit Score',
name: 'explicit_gpt_lead_score_reason',
label: 'Explicit GPT Lead Score Reason',
type: 'string',
fieldType: 'text'
},
{
key: 'Behavior Score',
name: 'behavior_gpt_lead_score_reason',
label: 'Behavior GPT Lead Score Reason',
type: 'string',
fieldType: 'text'
},
{
key: 'Demographic Score',
name: 'demographic_gpt_lead_score_reason',
label: 'Demographic GPT Lead Score Reason',
type: 'string',
fieldType: 'text'
},
{
key: 'Overall Score',
name: 'overall_gpt_lead_score_reason',
label: 'Overall GPT Lead Score Reason',
type: 'string',
fieldType: 'text'
}
]

Now that we have our properties generated we can complete the process of generating a score and displaying in our CRM.

const = async (scoreRes) => {
const properties = {}
scorePropertyList.forEach(p => {
properties[p['name']] = scoreRes['score'][p['key']]['score']
})
scoreReasonPropertyList.forEach(p => {
properties[p['name']] = scoreRes['score'][p['key']]['reason']
})
return hubspotClient.crm.contacts.basicApi.update(scoreRes.id, { properties })
}

Now we can run all of our leads through the system to generate unique lead scores for each. Below is a screenshot of the testing data scores.

Thank you for reading! Stay tuned for more.

Contact

Open for contract projects as a Project Leader or Individual Contributor. Let’s chat!

LinkedIn: https://www.linkedin.com/in/davidrichards5/
Email: david.richards.tech (@) gmail.com