From c15fef39c52fe99e02f7d4a741883ac3c3e9483b Mon Sep 17 00:00:00 2001 From: Brian-Automation-Guru Date: Mon, 16 Jun 2025 18:36:17 +0000 Subject: [PATCH 01/13] addedd change --- index.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index f337a32d..cb0847bd 100644 --- a/index.js +++ b/index.js @@ -8,11 +8,24 @@ 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 = ''; // 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 +app.get('/contacts', async (req, res) => { + const contacts = 'https://api.hubspot.com/crm/v3/objects/contacts'; + const headers = { + Authorization: `Bearer ${process.env.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 }); + } catch (error) { + console.error(error); + } +}); + // 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. From f922707da3685c6d08f90d263f610160a06c4642 Mon Sep 17 00:00:00 2001 From: Brian-Automation-Guru Date: Mon, 16 Jun 2025 18:46:18 +0000 Subject: [PATCH 02/13] added PORT --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index cb0847bd..bf75fa9b 100644 --- a/index.js +++ b/index.js @@ -8,7 +8,7 @@ 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 PORT = process.env.PORT || 3000; // 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. app.get('/contacts', async (req, res) => { From e048bab1373f6d957dcd53b0a042c7c6807f0e21 Mon Sep 17 00:00:00 2001 From: Brian-Automation-Guru Date: Mon, 16 Jun 2025 18:49:19 +0000 Subject: [PATCH 03/13] added index --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index bf75fa9b..cee0b3d6 100644 --- a/index.js +++ b/index.js @@ -25,6 +25,7 @@ app.get('/contacts', async (req, res) => { console.error(error); } }); +app.listen(3000, () => console.log('Listening on http://localhost:3000')); // 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. @@ -81,4 +82,3 @@ app.post('/update', async (req, res) => { // * Localhost -app.listen(3000, () => console.log('Listening on http://localhost:3000')); \ No newline at end of file From cf484fc61b8c2950ccc20a138efa5ad25f1eed7e Mon Sep 17 00:00:00 2001 From: Brian-Automation-Guru Date: Thu, 19 Jun 2025 18:04:46 +0000 Subject: [PATCH 04/13] First commit intergrating with HubSpot I: Foundations practicum repository. --- README.md | 2 +- index.js | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 76d6d581..d55b3982 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.hubspot.com/contacts/146392072/objects/2-143983893/views/all/list ___ ## Tips: diff --git a/index.js b/index.js index cee0b3d6..9b5073ed 100644 --- a/index.js +++ b/index.js @@ -1,20 +1,20 @@ const express = require('express'); const axios = require('axios'); const app = express(); +require('dotenv').config(); + app.set('view engine', 'pug'); app.use(express.static(__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 PORT = process.env.PORT || 3000; -// 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. +const accessToken = process.env.TOKEN; -app.get('/contacts', async (req, res) => { - const contacts = 'https://api.hubspot.com/crm/v3/objects/contacts'; +app.get('/', async (req, res) => { + const AirDefSystems = 'https://api.hubspot.com/crm/v3/objects/'; const headers = { - Authorization: `Bearer ${process.env.PRIVATE_APP_ACCESS}`, + Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json' } try { From d30c8e6331cddfa7443faaf9cb541c9d65c4063b Mon Sep 17 00:00:00 2001 From: Brian-Automation-Guru Date: Thu, 19 Jun 2025 18:55:00 +0000 Subject: [PATCH 05/13] added airDefSystems --- index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 9b5073ed..fc53996a 100644 --- a/index.js +++ b/index.js @@ -12,15 +12,15 @@ app.use(express.json()); const accessToken = process.env.TOKEN; app.get('/', async (req, res) => { - const AirDefSystems = 'https://api.hubspot.com/crm/v3/objects/'; + const airDefSystems = 'https://api.hubspot.com/crm/v3/objects/air_defense_systems/?limit=10&properties=name,range,description&archived=false'; const headers = { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json' } try { - const resp = await axios.get(contacts, { headers }); + const resp = await axios.get(airDefSystems, { headers }); const data = resp.data.results; - res.render('contacts', { title: 'Contacts | HubSpot APIs', data }); + res.render('homepage', { title: 'Air Defense Systems | HubSpot APIs', data }); } catch (error) { console.error(error); } From 7bdcc1a5d0bc20570c7331b7d75cbb340ebcd35d Mon Sep 17 00:00:00 2001 From: Brian-Automation-Guru Date: Thu, 19 Jun 2025 19:13:23 +0000 Subject: [PATCH 06/13] added homepage.pug --- package.json | 2 +- views/contacts.pug | 15 --------------- views/homepage.pug | 22 ++++++++++++++++++++++ 3 files changed, 23 insertions(+), 16 deletions(-) delete mode 100644 views/contacts.pug create mode 100644 views/homepage.pug diff --git a/package.json b/package.json index 62db37aa..53991de7 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,6 @@ "dependencies": { "axios": "^1.3.5", "express": "^4.18.2", - "pug": "^3.0.2" + "pug": "^3.0.3" } } 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..a7eb30cf --- /dev/null +++ b/views/homepage.pug @@ -0,0 +1,22 @@ +//- ** 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 Custom Object Table + a(href="/update-cobj") Add to this table + table(style='width:100%', border='1') + tr + th Name + th Range + th Description + each AirDefenseSystems in data + tr + td #{air_defense_systems.properties.name} + td #{air_defense_systems.properties.range} + td #{air_defense_systems.properties.description} + \ No newline at end of file From 4da25fbf7b35a5f446ca5cc9d6b2ee8ce4446162 Mon Sep 17 00:00:00 2001 From: Brian-Automation-Guru Date: Thu, 19 Jun 2025 19:20:37 +0000 Subject: [PATCH 07/13] added update.pug --- views/updates.pug | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 views/updates.pug diff --git a/views/updates.pug b/views/updates.pug new file mode 100644 index 00000000..638d2b8d --- /dev/null +++ b/views/updates.pug @@ -0,0 +1,21 @@ +doctype html +html(lang="en") + head + title= title + link(rel="stylesheet", href="/css/style.css") + body + .form-wrapper + p Air Defense Systems: + form(method="POST") + label(for="newName") New name + input(type="text", name="newName", id="newName", required) + + label(for="newRange") New range + input(type="number", name="newRange", id="newRange", required) + + label(for="newDescription") New description + input(type="text", name="newDescription", id="newDescription", required) + + input(type="submit", value="Submit") + + a(href="/") Return to the homepage From 9da38e1f1e291e8c32caa763fb8f5852e260453b Mon Sep 17 00:00:00 2001 From: Brian-Automation-Guru Date: Thu, 19 Jun 2025 19:22:54 +0000 Subject: [PATCH 08/13] added dotenv --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 53991de7..70a987ca 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "license": "ISC", "dependencies": { "axios": "^1.3.5", + "dotenv": "^16.5.0", "express": "^4.18.2", "pug": "^3.0.3" } From 3f2bc7eab6dd0332f20904dedee218f18833a773 Mon Sep 17 00:00:00 2001 From: Brian-Automation-Guru Date: Thu, 19 Jun 2025 19:28:22 +0000 Subject: [PATCH 09/13] added custom object path --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index fc53996a..a1db6ee8 100644 --- a/index.js +++ b/index.js @@ -12,7 +12,7 @@ app.use(express.json()); const accessToken = process.env.TOKEN; app.get('/', async (req, res) => { - const airDefSystems = 'https://api.hubspot.com/crm/v3/objects/air_defense_systems/?limit=10&properties=name,range,description&archived=false'; + const airDefSystems = 'https://api.hubspot.com/crm/v3/objects/air_defense_systems?limit=10&properties=name,range,description&archived=false'; const headers = { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json' From 243670660b5e58729c34d7e2880cb0a81aaea397 Mon Sep 17 00:00:00 2001 From: Brian-Automation-Guru Date: Thu, 19 Jun 2025 19:30:05 +0000 Subject: [PATCH 10/13] added custom path --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index a1db6ee8..09c26a98 100644 --- a/index.js +++ b/index.js @@ -12,7 +12,7 @@ app.use(express.json()); const accessToken = process.env.TOKEN; app.get('/', async (req, res) => { - const airDefSystems = 'https://api.hubspot.com/crm/v3/objects/air_defense_systems?limit=10&properties=name,range,description&archived=false'; + const airDefSystems = 'https://api.hubspot.com/crm/v3/objects/2-143983893?limit=10&properties=name,range,description&archived=false'; const headers = { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json' From aab2da2180bca1851370b26edebdd21b7934d451 Mon Sep 17 00:00:00 2001 From: Brian-Automation-Guru Date: Thu, 19 Jun 2025 19:34:24 +0000 Subject: [PATCH 11/13] updated pug --- views/homepage.pug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/homepage.pug b/views/homepage.pug index a7eb30cf..d163152b 100644 --- a/views/homepage.pug +++ b/views/homepage.pug @@ -14,7 +14,7 @@ html th Name th Range th Description - each AirDefenseSystems in data + each air_defense_systems in data tr td #{air_defense_systems.properties.name} td #{air_defense_systems.properties.range} From db0ab4bed60b832a9225c646fbf7ed0a888564c6 Mon Sep 17 00:00:00 2001 From: Brian-Automation-Guru Date: Thu, 19 Jun 2025 20:28:35 +0000 Subject: [PATCH 12/13] added post --- index.js | 65 ++++++++++++++++++++++---------------------------------- 1 file changed, 25 insertions(+), 40 deletions(-) diff --git a/index.js b/index.js index 09c26a98..fca30e46 100644 --- a/index.js +++ b/index.js @@ -10,7 +10,7 @@ app.use(express.urlencoded({ extended: true })); app.use(express.json()); const accessToken = process.env.TOKEN; - +//route 1: homepage app.get('/', async (req, res) => { const airDefSystems = 'https://api.hubspot.com/crm/v3/objects/2-143983893?limit=10&properties=name,range,description&archived=false'; const headers = { @@ -25,60 +25,45 @@ app.get('/', async (req, res) => { console.error(error); } }); -app.listen(3000, () => console.log('Listening on http://localhost:3000')); - - -// 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'; +//route 2: update form +app.get('/update-cobj', async (req, res) => { const headers = { - Authorization: `Bearer ${PRIVATE_APP_ACCESS}`, + Authorization: `Bearer ${accessToken}`, '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 }); - } catch (error) { - console.error(error); - } -}); + res.render('updates', {title: "Update Custom Object Form | Integrating With HubSpot I Practicum"}); + } catch(err) { + console.error(err); + } +}); + +//route 3: post +app.post('/update-cobj/', async (req, res) => { -* * App.post sample -app.post('/update', async (req, res) => { - const update = { + const postData = { properties: { - "favorite_book": req.body.newVal + "name": req.body.name, + "range": req.body.range, + "description": req.body.desc, } } - const email = req.query.email; - const updateContact = `https://api.hubapi.com/crm/v3/objects/contacts/${email}?idProperty=email`; + //const newCobj = `https://api.hubapi.com/crm/v3/objects/air-defense-systems/`; + const newCobj = `https://api.hubapi.com/crm/v3/objects/2-143983893/`; const headers = { - Authorization: `Bearer ${PRIVATE_APP_ACCESS}`, + Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json' - }; + } try { - await axios.patch(updateContact, update, { headers } ); - res.redirect('back'); + console.log('1'); + await axios.post(newCobj, postData, { headers } ); + res.redirect('/'); } catch(err) { console.error(err); } }); -*/ - - -// * Localhost +app.listen(3000, () => console.log('Listening on http://localhost:3000')); From dbe1a055ec1a24cc07cbf618db57e361833a14c5 Mon Sep 17 00:00:00 2001 From: Brian-Automation-Guru Date: Thu, 19 Jun 2025 20:40:39 +0000 Subject: [PATCH 13/13] added post properties --- index.js | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/index.js b/index.js index fca30e46..53df3a36 100644 --- a/index.js +++ b/index.js @@ -40,30 +40,30 @@ app.get('/update-cobj', async (req, res) => { }); //route 3: post -app.post('/update-cobj/', async (req, res) => { +app.post('/update-cobj', async (req, res) => { + const { newName, newRange, newDescription } = req.body; - const postData = { + const data = { properties: { - "name": req.body.name, - "range": req.body.range, - "description": req.body.desc, + name: newName, + range: newRange, + description: newDescription } - } + }; - //const newCobj = `https://api.hubapi.com/crm/v3/objects/air-defense-systems/`; - const newCobj = `https://api.hubapi.com/crm/v3/objects/2-143983893/`; + const url = 'https://api.hubapi.com/crm/v3/objects/2-143983893'; const headers = { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json' - } + }; - try { - console.log('1'); - await axios.post(newCobj, postData, { headers } ); + try { + await axios.post(url, data, { headers }); res.redirect('/'); - } catch(err) { - console.error(err); + } catch (error) { + console.error('Error creating object:', error.response?.data || error.message); + res.status(500).send("Failed to create custom object."); } - }); + app.listen(3000, () => console.log('Listening on http://localhost:3000'));