feat: adds enterprise and partner contacts directly into hubspot

This commit is contained in:
Alaister Young committed 2022-05-09 22:08:57 +10:00
1 parent 2bea318cca
commit 63645331db
2 files changed
+208 -12

No files matched your search

+31 -12
View File
@@ -5,7 +5,8 @@ import supabase from '~/lib/supabase'
const INITIAL_VALUES = {
companyName: '',
contactName: '',
contactFirstName: '',
contactLastName: '',
contactEmail: '',
contactPhone: '',
companySize: '',
@@ -20,8 +21,12 @@ const validate = (values: any) => {
errors.companyName = 'Required'
}
if (!values.contactName) {
errors.contactName = 'Required'
if (!values.contactFirstName) {
errors.contactFirstName = 'Required'
}
if (!values.contactLastName) {
errors.contactLastName = 'Required'
}
if (!values.contactEmail) {
@@ -41,7 +46,9 @@ const EnterpriseContactForm = () => {
[
{
company_name: values.companyName,
contact_name: values.contactName,
contact_name: `${values.contactFirstName} ${values.contactLastName}`,
contact_first_name: values.contactFirstName,
contact_last_name: values.contactLastName,
contact_email: values.contactEmail,
contact_phone: values.contactPhone,
company_size: values.companySize,
@@ -76,14 +83,26 @@ const EnterpriseContactForm = () => {
/>
</div>
<div>
<Input
label="Your Name *"
id="contactName"
name="contactName"
layout="vertical"
placeholder="Jane Doe"
/>
<div className="flex space-x-4">
<div className="flex-1">
<Input
label="Your First Name *"
id="contactFirstName"
name="contactFirstName"
layout="vertical"
placeholder="Jane"
/>
</div>
<div className="flex-1">
<Input
label="Your Last Name *"
id="contactLastName"
name="contactLastName"
layout="vertical"
placeholder="Doe"
/>
</div>
</div>
<div>
@@ -0,0 +1,177 @@
import { serve } from 'https://deno.land/std@0.131.0/http/server.ts'
const FUNCTION_SECRET = Deno.env.get('FUNCTION_SECRET')
const HUBSPOT_API_KEY = Deno.env.get('HUBSPOT_API_KEY')
const OWNER_ID = Deno.env.get('OWNER_ID')
const ENTERPRISE_PIPELINE = Deno.env.get('ENTERPRISE_PIPELINE')
const PARTNERS_PIPELINE = Deno.env.get('PARTNERS_PIPELINE')
const ENTERPRISE_DEAL_STAGE = Deno.env.get('ENTERPRISE_DEAL_STAGE')
const PARTNERS_DEAL_STAGE = Deno.env.get('PARTNERS_DEAL_STAGE')
serve(async (req) => {
const requestSecret = req.headers.get('x-function-secret')
if (FUNCTION_SECRET !== requestSecret) {
return new Response('Unauthorized', { status: 401 })
}
const input = await req.json()
const firstName = input.record.contact_first_name || input.record.first
const lastName = input.record.contact_last_name || input.record.last
const company = input.record.company_name || input.record.company
const email = input.record.contact_email || input.record.email
const phone = input.record.contact_phone || input.record.phone
const contactResponse = await fetch(
`https://api.hubapi.com/crm/v3/objects/contacts?hapikey=${HUBSPOT_API_KEY}`,
{
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
properties: {
company,
email,
firstname: firstName,
lastname: lastName,
phone,
},
}),
}
)
const body = await contactResponse.json()
let contactId: string | null = null
if (contactResponse.ok) {
contactId = body.id
} else {
if (body.status === 'error' && body.category === 'CONFLICT') {
// fetch existing contact
const contactAssociateResponse = await fetch(
`https://api.hubapi.com/crm/v3/objects/contacts/${email}?idProperty=email&hapikey=${HUBSPOT_API_KEY}`
)
const body = await contactAssociateResponse.json()
if (contactAssociateResponse.ok) {
contactId = body.id
} else {
console.log(`Failed to fetch contact`, body)
return new Response(`Failed to fetch contact`, { status: 500 })
}
} else {
console.log(`Failed to create contact`, body)
return new Response(`Failed to create contact`, { status: 500 })
}
}
const noteContent = Object.entries(input.record).reduce(
(acc, [key, value]) => acc + `${key}: ${value || 'NOT_PROVIDED'}<br />`,
''
)
// Add note
const noteResponse = await fetch(
`https://api.hubapi.com/crm/v3/objects/notes?hapikey=${HUBSPOT_API_KEY}`,
{
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
properties: {
hs_timestamp: Date.now(),
hs_note_body: noteContent,
hubspot_owner_id: OWNER_ID,
},
}),
}
)
const noteBody = await noteResponse.json()
if (!noteResponse.ok) {
console.log(`Failed to add note`, noteBody)
return new Response(`Failed to add note`, { status: 500 })
}
const noteId = noteBody.id
// Associate note with contact
const noteAssociateResponse = await fetch(
`https://api.hubapi.com/crm/v3/objects/notes/${noteId}/associations/contacts/${contactId}/note_to_contact?hapikey=${HUBSPOT_API_KEY}`,
{
method: 'PUT',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
}
)
if (!noteAssociateResponse.ok) {
console.log(`Failed to associate note`, await noteAssociateResponse.json())
return new Response(`Failed to associate note`, { status: 500 })
}
// Create deal
const dealCloseDate = new Date()
dealCloseDate.setDate(dealCloseDate.getDate() + 28) // 28 days
const dealResponse = await fetch(
`https://api.hubapi.com/crm/v3/objects/deals?hapikey=${HUBSPOT_API_KEY}`,
{
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
properties: {
closedate: dealCloseDate.toISOString(),
dealname: company || `${firstName} ${lastName}`,
dealstage:
input.table === 'enterprise_contacts' ? ENTERPRISE_DEAL_STAGE : PARTNERS_DEAL_STAGE,
hubspot_owner_id: OWNER_ID,
pipeline: input.table === 'enterprise_contacts' ? ENTERPRISE_PIPELINE : PARTNERS_PIPELINE,
},
}),
}
)
const dealBody = await dealResponse.json()
if (!dealResponse.ok) {
console.log(`Failed to create deal`, dealBody)
return new Response(`Failed to create deal: ` + dealBody.message, { status: 500 })
}
const dealId = dealBody.id
// Associate contact with a deal
const dealAssociateResponse = await fetch(
`https://api.hubapi.com/crm/v3/objects/contacts/${contactId}/associations/deals/${dealId}/contact_to_deal?hapikey=${HUBSPOT_API_KEY}`,
{
method: 'PUT',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
}
)
if (!dealAssociateResponse.ok) {
console.log(`Failed to associate contact with deal`, await dealAssociateResponse.json())
return new Response(`Failed to associate contact with deal`, { status: 500 })
}
return new Response(JSON.stringify({ done: true }), {
headers: { 'Content-Type': 'application/json' },
})
})