Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save dayhaysoos/f328c59629b68f836ede365f74292f9d to your computer and use it in GitHub Desktop.
Save dayhaysoos/f328c59629b68f836ede365f74292f9d to your computer and use it in GitHub Desktop.
lambderp.js
/* Amplify Params - DO NOT EDIT
API_BTPAMPLIFY_GRAPHQLAPIENDPOINTOUTPUT
API_BTPAMPLIFY_GRAPHQLAPIIDOUTPUT
API_BTPAMPLIFY_GRAPHQLAPIKEYOUTPUT
API_BTPAMPLIFY_INTRODUCTIONREQUESTTABLE_ARN
API_BTPAMPLIFY_INTRODUCTIONREQUESTTABLE_NAME
AUTH_BTPAMPLIFYF619BFF1_USERPOOLID
ENV
REGION
Amplify Params - DO NOT EDIT */
//everything above is all environment variables
// require the aws sdk and make a const for needed services
const aws = require('aws-sdk')
const ses = new aws.SES()
const cognito = new aws.CognitoIdentityServiceProvider()
const docClient = new aws.DynamoDB.DocumentClient()
async function getCandidate(id) {
// id = the user id
// params object, typical to dynamodb (should prob learn more about the param syntax)
var params = {
TableName: 'DYNAMO-DB-TABLENAME-HERE',
Key: { id },
KeyConditionExpression: '#id = :value',
ExpressionAttributeValues: { ':value': id },
ExpressionAttributeNames: { '#id': 'id' }
}
try {
// querying the user data from docClient
const data = await docClient.query(params).promise()
return data
} catch (err) {
return err
}
}
//similar to above but for updating
async function updateStatus(id) {
var params = {
TableName: 'IntroductionRequest-cv22rvwkqzcjxbeogugwgn23sq-dev',
Key: { id },
UpdateExpression: 'set request_status = :value',
ExpressionAttributeValues: { ':value': 'pending' },
ReturnValues: 'UPDATED_NEW'
}
try {
const data = await docClient.update(params).promise()
console.log('Successfully updated status')
return data
} catch (err) {
console.log('Error:', err)
return err
}
}
// fetching user attributes from cognito
async function getUser(params) {
try {
const result = await cognito.adminGetUser(params).promise()
return result
} catch (error) {
console.log('Error', error)
}
}
// ignore this garbage
function formatRoles(roles) {
let formattedRoles = {}
roles.forEach((roleObject, i) =>
Object.keys(roleObject.M).forEach((roleKey) => {
formattedRoles[`Role${i}`] = {
...formattedRoles[`Role${i}`],
[roleKey]: roleObject.M[roleKey].S
}
})
)
return formattedRoles
}
// ignore this garbage also
function formatForEmail(formattedRoles) {
let result = ``
Object.keys(formattedRoles).forEach((role) => {
result =
result +
`
<div>
<strong>Title</strong>: ${formattedRoles[role].title}
</div>
<div>
<strong>Location:</strong> ${formattedRoles[role].location}
</div>
<div>
<strong>Starting:</strong> ${formattedRoles[role].starting_salary}
</div>
<div>
<strong>Type:</strong> ${formattedRoles[role].type}
</div>
<div>
<strong>Role URL:</strong> ${formattedRoles[role].role_url}
</div>
<hr/>
`
})
return result
}
// This is where the lambda begins
exports.handler = async (event) => {
// checking event name returning done early here
if (
event.Records[0].eventName === 'REMOVE' ||
!event.Records[0].dynamodb.NewImage.candidateId
) {
return { status: 'done' }
}
// always good to leave logs for cloudwatch to pick up
console.log(JSON.stringify(event, null, 2))
// getting a bunch of variables
const introductionRequestId = event.Records[0].dynamodb.NewImage.id.S
const candidateId = event.Records[0].dynamodb.NewImage.candidateId.S
const candidateData = await getCandidate(candidateId)
const candidateEmail = candidateData.Items[0].email
const candidateName = candidateData.Items[0].first_name
const candidateLastName = candidateData.Items[0].last_name
const { bucket, key } = candidateData.Items[0].resume
const candidateResumeURL = `https://${bucket}.s3.amazonaws.com/public/${key}`
const employerId = event.Records[0].dynamodb.NewImage.employerId.S
let employer
try {
const result = await getUser({
Username: employerId,
UserPoolId: process.env.BTP_USER_POOL_ID
})
employer = result
} catch (error) {
console.log('Error', error)
}
const employerEmail = event.Records[0].dynamodb.NewImage.employerEmail.S
const employerFirstName =
event.Records[0].dynamodb.NewImage?.employerFirstName?.S || ''
const employerRoles = event.Records[0].dynamodb.NewImage.roles.L
const formattedRoles = formatRoles(employerRoles)
const roleContent = formatForEmail(formattedRoles)
// sending email if the event status name is "MODIFY"
if (event.Records[0].eventName === 'MODIFY' && employerEmail) {
const answer = event.Records[0].dynamodb.NewImage.request_status.S
if (answer === 'accept') {
await ses
.sendEmail({
Destination: {
ToAddresses: [employerEmail]
},
Source: process.env.SES_EMAIL,
Message: {
Subject: {
Data: `A candidate accepted your request for an Introduction!`
},
Body: {
Html: {
Charset: 'UTF-8',
Data: `
<p>Hey ${employerFirstName},</p>
<p>A candidate is interested in learning more about the role(s) you sent them.</p>
<p>Their name is <strong>${candidateName} ${candidateLastName}</strong> and their email is <strong>${candidateEmail}</strong>.</p>
<p>Here are the roles you sent them:</p>
<div>
${roleContent}
</div>
<p>Click <a href=${candidateResumeURL}>here</a> to see their resume.</p>
`
}
}
}
})
.promise()
}
if (answer === 'reject') {
await ses
.sendEmail({
Destination: {
ToAddresses: [employerEmail]
},
Source: process.env.SES_EMAIL,
Message: {
Subject: {
Data: `Candidate ${
candidateId.split('-')[0]
} has declined your request to interview.`
},
Body: {
Html: {
Charset: 'UTF-8',
Data: `
<p>Hey ${employerFirstName},</p>
<p>The candidate:
${
candidateId.split('-')[0]
} has turned down your request to reach out at this time. </p>
`
}
}
}
})
.promise()
}
return { status: 'done' }
}
if (event.Records[0].eventName === 'INSERT') {
const employerWebsite = employer.UserAttributes.filter(
(attr) => attr.Name === 'custom:company_website'
)[0].Value
const companyName = employer.UserAttributes.filter(
(attr) => attr.Name === 'custom:company_name'
)[0].Value
const answerBase = `https://k0lb4gmty4.execute-api.us-east-1.amazonaws.com/default/btpacceptrequest-dev?introductionRequestId=${introductionRequestId}`
const acceptLink = `${answerBase}&answer=accept`
const rejectLink = `${answerBase}&answer=reject`
await ses
.sendEmail({
Destination: {
ToAddresses: [candidateEmail]
},
Source: process.env.SES_EMAIL,
Message: {
Subject: {
Data: `${companyName} is interested in interviewing you!`
},
Body: {
Html: {
Charset: 'UTF-8',
Data: `
<html>
<body>
<h2>Hey ${candidateName},</h2>
<p style="margin: 0; font-size: 14px">
${companyName} thinks you'd be a great fit for the following role(s):
</p>
<div>
${roleContent}
</div>
You can check out their website <a href=${employerWebsite}>here.</a>
<p>
<a href=${acceptLink}>Click here if you'd like someone from ${companyName} to reach out to you.</a>
</p>
<p>By clicking the above link, someone at ${companyName} will receive a notification sharing your name, email, and a link to your resume.</p>
<p>
<a href=${rejectLink}>Click here if you're not interested in these roles at this time.</a>
</p>
</body>
</html>
`
}
}
}
})
.promise()
try {
await updateStatus(introductionRequestId)
} catch (error) {
console.log('Error:', error)
}
return { status: 'done' }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment