diff --git a/README.md b/README.md index 76d6d581..5d88857e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This repository is for the Integrating With HubSpot I: Foundations course. This To read the full directions, please go to the [practicum instructions](https://app.hubspot.com/academy/l/tracks/1092124/1093824/5493?language=en). -**Put your HubSpot developer test account custom objects URL link here:** https://app.hubspot.com/contacts/l/objects/${custom-obj-number}/views/all/list +**Put your HubSpot developer test account custom objects URL link here:** https://app-na2.hubspot.com/contacts/242700234/objects/2-169450890/views/all/list ___ ## Tips: diff --git a/index.js b/index.js index f337a32d..783bd845 100644 --- a/index.js +++ b/index.js @@ -1,71 +1,75 @@ +require('dotenv').config() const express = require('express'); const axios = require('axios'); +const path = require('path'); const app = express(); app.set('view engine', 'pug'); -app.use(express.static(__dirname + '/public')); +app.set('views', path.join(__dirname, 'views')); + +app.use(express.static(path.join(__dirname, 'public'))); app.use(express.urlencoded({ extended: true })); app.use(express.json()); // * Please DO NOT INCLUDE the private app access token in your repo. Don't do this practicum in your normal account. -const PRIVATE_APP_ACCESS = ''; +const PRIVATE_APP_ACCESS = process.env.HUBSPOT_ACCESS_TOKEN; +const CUSTOM_OBJECT_TYPE = process.env.CUSTOM_OBJECT_TYPE; // TODO: ROUTE 1 - Create a new app.get route for the homepage to call your custom object data. Pass this data along to the front-end and create a new pug template in the views folder. -// * Code for Route 1 goes here - -// TODO: ROUTE 2 - Create a new app.get route for the form to create or update new custom object data. Send this data along in the next route. - -// * Code for Route 2 goes here - -// TODO: ROUTE 3 - Create a new app.post route for the custom objects form to create or update your custom object data. Once executed, redirect the user to the homepage. - -// * Code for Route 3 goes here - -/** -* * This is sample code to give you a reference for how you should structure your calls. - -* * App.get sample -app.get('/contacts', async (req, res) => { - const contacts = 'https://api.hubspot.com/crm/v3/objects/contacts'; +app.get('/', async (req, res) => { + const url = `https://api.hubapi.com/crm/v3/objects/${CUSTOM_OBJECT_TYPE}?properties=asset_name,serial_number,asset_status`; const headers = { Authorization: `Bearer ${PRIVATE_APP_ACCESS}`, 'Content-Type': 'application/json' - } + }; + try { - const resp = await axios.get(contacts, { headers }); - const data = resp.data.results; - res.render('contacts', { title: 'Contacts | HubSpot APIs', data }); + const response = await axios.get(url, { headers }); + const records = response.data.results; + res.render('homepage', { title: 'Homepage | Custom Object Records', records }); } catch (error) { - console.error(error); + console.error('Error fetching records:', error.response?.data || error.message); + res.status(500).send('Failed to fetch records'); } }); -* * App.post sample -app.post('/update', async (req, res) => { - const update = { +// TODO: ROUTE 2 - Create a new app.get route for the form to create or update new custom object data. Send this data along in the next route. + +app.get('/update-cobj', (req, res) => { + res.render('updates', { title: 'Update Custom Object Form | Integrating With HubSpot I Practicum' }); +}); + +// TODO: ROUTE 3 - Create a new app.post route for the custom objects form to create or update your custom object data. Once executed, redirect the user to the homepage. + +app.post('/update-cobj', async (req, res) => { + const { asset_name, serial_number, asset_status } = req.body; + + const data = { properties: { - "favorite_book": req.body.newVal + asset_name, + serial_number, + asset_status } - } + }; - const email = req.query.email; - const updateContact = `https://api.hubapi.com/crm/v3/objects/contacts/${email}?idProperty=email`; + const url = `https://api.hubapi.com/crm/v3/objects/${CUSTOM_OBJECT_TYPE}`; const headers = { Authorization: `Bearer ${PRIVATE_APP_ACCESS}`, 'Content-Type': 'application/json' }; - try { - await axios.patch(updateContact, update, { headers } ); - res.redirect('back'); - } catch(err) { - console.error(err); + try { + await axios.post(url, data, { headers }); + res.redirect('/'); + } catch (error) { + console.error('Error creating record:', error.response?.data || error.message); + res.status(500).send('Failed to create record'); } - }); -*/ + // * Localhost -app.listen(3000, () => console.log('Listening on http://localhost:3000')); \ No newline at end of file +app.listen(3000, () => console.log('Listening on http://localhost:3000')); + diff --git a/views/contacts.pug b/views/contacts.pug deleted file mode 100644 index c600ca01..00000000 --- a/views/contacts.pug +++ /dev/null @@ -1,15 +0,0 @@ -//- ** This is a sample of a pug template and how it uses the data passed to it from index.js. - -//- doctype html -//- html -//- head -//- title= `${title}` -//- meta(name="viewport" content="width=device-width, initial-scale=1") -//- link(rel="stylesheet", href="/css/style.css") -//- body -//- h1 Contacts -//- .cards -//- each contact in data -//- .card -//- h2.card__name #{contact.properties.firstname} #{contact.properties.lastname} -//- p.card__email #{contact.properties.email} \ No newline at end of file diff --git a/views/homepage.pug b/views/homepage.pug new file mode 100644 index 00000000..3e1b7b8c --- /dev/null +++ b/views/homepage.pug @@ -0,0 +1,25 @@ +doctype html +html + head + title= title + link(rel="stylesheet", href="/css/style.css") + body + h1 Custom Object Table + a(href="/update-cobj") Add to this table + br + br + if records.length + table(border="1") + thead + tr + th Asset Name + th Serial Number + th Asset Status + tbody + each record in records + tr + td= record.properties.asset_name + td= record.properties.serial_number + td= record.properties.asset_status + else + p No records found. \ No newline at end of file diff --git a/views/updates.pug b/views/updates.pug new file mode 100644 index 00000000..26a4aede --- /dev/null +++ b/views/updates.pug @@ -0,0 +1,21 @@ +doctype html +html + head + title= title + link(rel="stylesheet", href="/css/style.css") + body + h1 Update Custom Object Form | Integrating With HubSpot I Practicum + form(action="/update-cobj", method="POST") + div + label(for="asset_name") Asset Name: + input(type="text", name="asset_name", required=true) + div + label(for="serial_number") Serial Number: + input(type="number", name="serial_number", required=true) + div + label(for="asset_status") Asset Status: + input(type="text", name="asset_status", required=true) + div + button(type="submit") Submit + br + a(href="/") Return to the homepage \ No newline at end of file