Building a HubSpot App: Start to Finish. A Masterclass series with A8 Labs | Session 2

Tyrone Paulson, CTO of Aptitude 8, walks through building a HubSpot app from scratch. The session covers OAuth authentication, token management, API integration, and embedding apps in HubSpot's CRM. A Q&A addresses scalability and career paths for developers.
Hey everyone, I'm going to see about get a. Can you get the deck shown? Whoever is sharing the deck. There we go. All righty. Welcome everyone to our second masterclass. This one is basically around building an app. If you were around the last time around, it was really about the considerations that you need to be thinking about when it comes to making a HubSpot app. What a HubSpot app actually is and some of the considerations, whether it's a large app or small app and team considerations and things of that nature. Today is much more hands on where it's going to be just building. I am Tyrone Paulson. I am the CTO of Aptitude 8 where we pretty much stake our lives on the HubSpot because we absolutely love the platform and I pretty much lead our product development and a lot of our kind of just IT engineering as well.
I am Dax. I run the aid labs portion of our business. So we create apps for HubSpot and the HubSpot ecosystem strictly. So apps and integrations are what we do all day. We like to fill the holes that HubSpot has, but there's not that many of them so we're always looking. Yes, there is something along but this is going to be a great. Really excited to present today the actual nitty gritty in the weeds of developing apps by applications. Not a lot of content out there for it. It's going to be one of the first. So we're super excited to be able to land this out.
All right, so today we're going to be discussing, as you see right here on the screen, we're going to be creating an app in HubSpot. And by creating that we basically means hey HubSpot, we're creating an app. Give me an app ID. Essentially we're registering our app with HubSpot. We'll talk about the install flow with OAuth and if you watched our last video, you would know that there are three different ways you can basically access HubSpot. But we're going to talk about the OAuth method because that is the method you are going to be using if you are making apps for the public. The other ways are using API keys, which is a depreciated way, and private apps. And private apps work great if you're making an app for yourself or maybe for your company. But we're really kind of talking about more public consumption here. Next we're going to be. I've already developed a very small app that is going to be the middleware that is ultimately going to connect to HubSpot and then number four is creating the CRM card. This is basically how you would take your middleware and how you would integrate it into HubSpot into the HubSpot UI. And then after that we will take a few questions. Side note, we definitely want to hear from you as we're kind of progressing through this presentation. Please feel free to add questions to the, to the comment section here. So we're going to ultimately come to a point where we're just doing Q and A and it'd be really great if we had a bunch of questions kind of lined up and I think we kind of knock them on down when we get to that particular part. Don't be shy to ask any questions whatsoever, please. Fire away. Okay, kind of getting back to the slide here. Primary goal here is we really are going to build. We're going to go through the steps of building a really simple app. So that starts with having a HubSpot account. And to recap, a HubSpot account is you. You need it, like period. You cannot get away with it. Even if you're not going to be tracking contacts and deals and things of that nature, you simply still need a HubSpot app. Really easy to set up, takes you all of two minutes and then, boom, you're ready to go. Once you have your HubSpot app, then you can create a developer account. And a developer account is essentially you telling HubSpot, Hey, I'm a developer. And it is where all of your apps will be registered at. It is where your apps will be registered. And it is also the starting point of when you go to put your app into the eco place. It'll pretty much start with your developer account. Your developer account is also where you will get your developer API key when you need it. So everything HubSpot dev related starts there. What you will need, if you are attempting to follow and or MIT, a HubSpot app is you will need a web server and an application server and in our case, you also need a database server. The technology here that you use is totally up to you. The middleware, if you remember from the last session, it exists wherever you host it. So it is not a traditional app in the sense of, hey, I'm going to put a bunch of files together and then it's going to run on hardware like a phone or something. It is much more like it's a website that I built somewhere on the Internet and it's publicly accessible to HubSpot and we're going to use that accessibility to bring things from my middleware into HubSpot. In this case, we are using a Windows box which is using Internet information system, so IIS 10. We're also using a open source form of ColdFusion called Lucy and we're using MySQL for the data store. Next slide. All right, connecting your app to HubSpot. So as I kind of said beforehand, just kind of beat this with a dead horse or like a dead horse. Apologies. There are multiple ways and I just want to touch on this real quick. Every HubSpot instance has an API key. And if you are building apps for the public, you ultimately can get an API key. But you do not want to get an API key because it does indeed give you guide access to the person's HubSpot. And if something goes wrong, it's going to be really easy to point a finger in your direction. So to make sure you eliminate that risk, you either want to go down the private app or the OAuth route. We are going to go down the OAuth route because in this example, we are making an app for the public, private app makes a lot more sense if you're making an app maybe for yourself and or maybe for your company. But we are going down the OAuth route because we are going to make the assumption that anyone can sign up for an app and it needs to be pretty general. And we want to be able to protect ourselves with some of the things that come with OAuth, like setting permissions and the token expiry. So those two things will help prevent you from accessing things you don't want and more importantly, your customer yielding access to things that they don't want you to have and in addition to only doing it for a limited set of time. So those OAuth tokens expire after 30 minutes, and after 30 minutes you then have to refresh the token. So you could easily say, hey guys, tell your customers, guys, listen, you know, after 30 minutes, if you don't want us to have any access to your app, you don't have to do anything. You don't even have to uninstall. We just simply will not refresh the tokens. Or you can, or they can uninstall your app, it'll be the exact same thing. The developer API key, just to kind of hammer home on that is a very niche like credential, as far as I can tell, is only used when it comes to managing parts of your app that have to that directly use workflows and the HubSpot workflow UI outside of that, not a whole lot of uses for it, but just want to drive that point home. Next slide. All right, so I'm going to start sharing my screen here and we are going to do step one, which is registering the app. So let me get my screen going here. Okay, so this is the, the. The Alchemist where before we were acquired by a. This is our developer account. So just kind of real quickly I'll show you this. We have a long list of apps. I've created an app down here for the master, just for the sake of this demo. It's called masterclass Demo. When you come in here, you're basically going to add your, the name of your app. You want to give it something descriptive. You always want to add the description because a lot of times you may have apps that operate in different environments. Maybe you have one for production and staging and development. So you want to make sure that your description is very descriptive of what's kind of going on. And then you're going to come over here to the off part. The auth part is what essentially really helps delineate your app from other people's. So when you submit your app, and by submitting I mean you basically just want to fill out this app ID form. If you were to come over here, you get the save option and then once you get the save option, this auth part is going to then populate. So you'll get an app id, you'll get a client id, you'll get a client secret. And then what you will have to do as part of the authorization, as far as the OAuth process is you need to specify somewhere on the Internet, somewhere that you're familiar up, where you can Basically take the OAuth code that's given to you and swap that out for access and refresh tokens and we'll come across again that come across that in just a little bit. Once you've added in your redirect URL, you want to come down here and you want to basically set the permissions for your app. And what this means is these are the objects or the object structures that you are saying you want to be able to manipulate. So if it's for example, companies or contacts, for, for this example, I want read and write access to contacts. See the schemas means your ability to alter contacts. So maybe add a new field, drop a field, change the name of a field. It's the schema, it's the structure of the object. So read and write you will definitely, definitely want to only pick the ones that you really need as you go as your. If your app becomes really popular and you go to get your app certified, HubSpot certification team will definitely look at your permissions and look at the app's usage and determine if the scopes, if the permission scopes that you've chosen really are in usage or not and would suggest maybe you remove some. So you want to make sure that again, to reduce your risk and other long term things, you want to make sure that you only use the scopes that you really need. You also notice that CRM and then there's legacy. This is essentially new to HubSpot. So before maybe, maybe three or four months ago there used to only be this all the way down and it's definitely a longer list and it's a little confusing. But HubSpot has really been trying hard to kind of revamp their permissions to make it a lot more granular and to also just, just make it make more sense. More than likely you are going to be picking some combination of these, the CRM scopes. And again this section is new and probably something from Legacy. Again, only pick the ones that you need for the sake of this demo. We're only going for contacts. So as you pick your, the scopes that you need, you'll see that the install preview changes on the right hand side. This area here is what your customers are going to see as they are about to start signing up for their app. It basically says, hey, you're going to sign, you're going to let, you're going to sign up for these people's app and here's what they're going to be manipulating inside of your, inside of your HubSpot instance and they need to be okay with that. Again, we're only going for contacts. So as you pick these, you can actually see up here that these bad boys are changing. This is pretty much your list. And once you have selected the ones that you want, we'll just take a pause here. This area right here, your install oauth is going to be populated. So if we kind of look at this, it is basically the redirect URL in addition to its scopes that you specify. Now I want to add this in here. The scopes that you specify here, these are the required scopes. These are the, these are the scopes that you are saying, hey, my app will simply not work without it. There are other scopes that you can use and, and you will actually have to add them manually. And to do that, you'll have to add the ampersand. You'll have to say optional, and then you'll have to add the scopes that you want. For example, if you say you wanted, I don't know, custom schema dot, then whatever the name of some custom object is, you'd have to actually add that in manually yourself. So that's a caveat that a lot of people don't necessarily know about. Now, you know, definitely take that back to work with you. Again, for the sake of this demo, we're only doing contacts. This OAuth URL is ultimately what you are going to hand to your customers so that they can begin installing your app. Okay, now that we have that established, and now that we have actually specified a location of where HubSpot is going to, and actually back this up here. When you give someone this oauth, this oauth link, they're going to take this bad boy, they're going to put it in their browser, and it's going to hold on, set live demos, always painful, all right? And it's going to bring them here. So this is what installing an app action looks like. And then you would want to pretty much cycle through whichever HubSpot instance you want it on, and you got to choose account. Now, once I hit the choose account button, it is going to then redirect me to this location right here. And appended to this location is going to be something like this code equal, blah, blah, blah, blah, blah. It's going to be the, the, the authorization code. So if we kind of go back here, we choose account. It's basically going to say, hey, are you absolutely sure that you want to do that by default? I actually had already installed this app for the sake of the demo, and so now it is redirecting me here to my redirect URL. So let's take a look at this. This is the masterclass app. Give us IO this is publicly available. If you guys want to go to it, feel free. But you can see that this is the redirect URL that I specified. And then HubSpot themselves automatically appended the authorization code. Great. So now that we see that HubSpot has already appended the authorization code, let's take a look at this. Install that CFM script to see what's going on there. Okay, so in the script, if you're not familiar with codefusion, I'll kind of quickly walk you through it. But we're looking for a query string key URL code in codefusion URL is the. The. The global scope for everything that's in the query string as part of a page request. And we're taking that code and then we're specifying the client id, the client secret and the app redirect URL. These three variables are something that is stored in. In our database that we pull out just for the sake of making this request to actually swap out the the code for. For access and refresh tokens. I also have a wrapper class here called HubSpot API. If we take a look here. Let's see. And again, this entire application is actually on GitHub. In fact, let me go ahead and throw the GitHub link in the. In the chat there. If you download that, that this repo. There's actually another branch here called Master and that's where all the goody goods are going. Back to our example though, we are have a wrapper class called HubSpot API. Again, this is my wrapper class. There's a bunch of methods in here that basically just call Cold Fusion, sorry, that calls HubSpot API locations. Definitely feel free to use this bad boy. A lot of the work is kind of done for you. This is all written in ECMAScript, so if you're using JavaScript or PHP, this is actually not far from a copy paste for you. But if we look at our request tokens using code. Let's take a look at this. So here we're basically calling the OAuth v1 token URL. We are specifying the grant type as authorization code. We are passing in as form fields, the client id, the client secret and the redirect uri. These values right here directly come from our app, our client id, our client secret and then our redirect URL. So that's what those values are. And then you want to make sure that you have the header here involved. This header is actually optional, but this application form URL code, this is mandatory. This is what you need to make the call. And then lastly we're actually passing in the code that came from the URL as another form field that's part of our request. The result of that request is an object. This is going to be a JSON object. And I pretty much just dumped it out here to this screen for the, for the sake of the demo. But you can see it was successful. And HubSpot returned to us the token type. It returns us a refresh token. We'll need this later when we go to refresh our access tokens because remember, they only last for 30 minutes. Here's the actual access token itself and they give you another property that says expires it. So basically how long do I have until I have to refresh this bad boy? When does this access token expire? When am I going to have to refresh? That's what this value is. And this value is in seconds. Okay, so if we go back and we look at our install script or making our API call to get the token, the value, or put the response in this token response object, and then we're basically saving it to the database. We have a table called config and we're basically saving this config to the config table. Just a heads up, the database that we're using here, if you're in the repo, it is actually here in the masterclass underscore demo that SQL file. So the entire database definition, everything you need is actually here. And if we want to take a quick look at what that table looks like, here it is. So here's our, is our master class, here's our table called config, here's the access token and stuff like that. Everything that we need that we'll be using later on. Okay, so now that we have a flow to install, to go through the install, we need another one that will simply refresh our tokens because they do expire every 30 minutes. Just want to beat that with a dead horse. And I do have a script already in place for that. It is Refresh cfm and let's take a quick spin through that real fast. This script basically does a few things. One, it grabs the access token and the refresh token for our database and then calls. We're going to make another instance of our HubSpot API wrapper and then we're going to call the refresh token. So if we take a quick look at the refresh token method, very, very similar to our initial token API call, we're going to pass the grant type again. Except this instead of being authorization code, this time it's a refresh token again, we're going to pass our client id, our client secret, our redirect URL and the actual refresh token. So when you go to refresh the token, you don't pass the access token, you pass the refresh token. And the refresh token was something that we initially got here. Okay. We're looking back at our original request for token data. Okay. So now what we would really want is you would want to be able to call your Refresh CFM page every 30 minutes to make sure that you were indeed getting new, fresh token data at all times. Because you never know when your client ultimately is going to be needing to make API calls. If we go back and we look at our refresh page, our script again, once we get that refresh token data back, we're just saving it back to the database. Really simple, really straightforward. Okay, so now that we actually have access to someone's HubSpot, now, this is essentially where the meat of the app really begins. And in this particular app, the only thing we've done is we have a login script. So what we want to do here is we want to say, hey, here's a login page. And when someone puts info into this page, they're going to put in an email address. I need to be able to reach out to someone's HubSpot, and I need to see if the person with this email address actually exists. And if they do, then I need to check on their password. Okay, so this page, Appimismasterclass Optimus IE login goes directly to this page, right? Oh, gosh, where is it? Here, it's right here, login. And if we scroll to the bottom, we'll see that there's a form, this chunk of the, of the script. Lines 84 to 129 directly correlate to this form that you're seeing here. And then the rest of the script here is actually going to handle the flow of when someone actually submits the form. So let's, let's walk through this. You can see what's going on. I think everyone knows how form works, but let's see what happens first. Our logic says that if form email, that is when you submit a form of cold fusion, just like there was a URL scope, there's the form scope, and the form scope basically is a structure that contains everything about the form that was just submitted. So in this case, there's a. There's a form field called email. If we look down here in this form, we'll see. We got a. We'll see. You have an input name is email. That's where that kind of comes from. So we're looking to see if it's empty. If it's not empty, we're like, hey, I think we got something. First thing we need to do, let's go grab the access token from the database. Next thing we need to do, let's create an. Let's create an instance of our wrapper class and let's pass the access token to that wrapper class, our wrapper class actually has a little bit of logic in it that will take the access token and then send it as, as a header for all of our API calls. So if we were to simply look at. Let's take a, let's take a sample right here. I'm trying to look for a simple one. Here we go. If we're looking to get someone's custom objects, here's the authorization header, for example. So you would part of your HTTP call, as part of your API call, you want to have a header called authorization and you want to pass in the word bearer and then the value of the access token that we just got and refreshed earlier. So that is this, this, this, this header part is like dead necessary for any API calls that you're going to make that use an access token, you absolutely gotta have it. Other and then next is the content type application JSON. You absolutely need these two. If you do not pass in these two headers in, you will get two very irritating messages. One is going to say no authorization data found. The second one is going to say media unsupported. And the media unsupported one, I kid you not, will send you howling to the nuthouse. So make sure that you have application JSON and the content type header specified as part of your API policy. Okay, now that we got that right, going back to our login flow. Yeah, we're creating an instance of our API class. Next thing we do is we're actually going to make an API request to find a contact by email address. So part of that, part of this form that we're looking at, I'm going to put in here emailomain.com I'm going to submit the form, we're going to do an API call, and if we look at the API call request, kind of go back to our raffle class here. Instead of doing a post, we're doing a git. Here's the URL that's being generated. We're basically making a call to the context API. We're passing in the email address as part of the URL because that's what's specified in the API documentation. We're asking for a few other fields to be returned to us, like first name, last name, email, phone, and then we're basically making our API call. Okay, so once we make our API call, we're going to dump this out to the screen and let's see what happens. I'm going to put in some glib gloss and I'm going to hit login. Okay, great. So what's our response here? This is the direct response that HubSpot gave us. Basically, contact does not exist ultimately. And what we did was we took the error message here and we threw it right here. Just in case something bad has happened. We want to let the user know. But this is what it is. We stored the results of the API contact of the API call to the contact results object. We basically said, hey, if there's a property on this object, on this response object that says status, something has gone wrong, right? Something just not right. And then we want to dump it out to the screen. So that's what we're looking at. But what if someone is is there, right? What if the person is there? And so let's see Aptitude8.com gotta give Libby gloss for a password. I'm gonna hit the login button. Okay. Ah, so this time it's very different. The response we got this time is because HubSpot actually found a person with that email address. And you can see part of the response is we get the id, we will actually. This response will actually tell you if this contact's ever been merged with another contact, the portal that it belongs to. And then the meat, yeah, glibly glob is real work. The meat of the response here, which is first name, last name, email address and last date, not modified. When you're looking at this data, for example, under the property's first name, you'll see that the value is Tyron. That's me. And then you can see the, the, the field history. So Tyron was only added to its contact once. If I had changed it from Tyron to Steve to Jacob to Dax, the versions here would be a very deeply populated array. And HubSpot will actually give you the history of any field 20 iterations back and 20 max. So just a heads up on that for the example here, you can see that we actually found a contact named tyron. And then HubSpot returned us some data. And so if we look back through our code, this time we don't see a property name status. So let's go to our else logic. Now that we found a contact, now we actually need to see if the email address and that password actually matches someone who's in our database. This is how we know we have a legit user. And in most cases, if you are building a login, you do not want to store that password on HubSpot, you want to store that password yourself. You have no idea who has access to that password, HubSpot. So to limit any damage and to reduce any risk, you would always want to keep that password in your own data store. As you can see here, I've got a query and if you're familiar with ColdFusion in my style, I generally like to do multiple queries in one query block just to hit the database, hit it hard, get what I need, get out. I'm doing a search for that person based on email and password. I'm putting the row count into a variable called Found Users and then I'm saving the results of this login attempt to a table called login history. And then I'm also saving the IP address of the person who just tried it, as well as how many rows I found from my initial query up here. After that I am returning the results of my found user and then I'm using that in codefusion to set a message that appears in my form. So if the number of users found was, which in theory should be one, if it is a one, congrats, your credentials were found successful. Check the law table for details. If it was not, we're saying no user could be found with those credentials because really we're only looking for one person. And this form message will optionally appear here down in our form based on if there's actually something to show. So we've kind of looked beforehand. Right now we found a user in HubSpot, but we didn't really, couldn't really determine if the credentials match because the password was pretty much garbage. I just wanted to show what happens when I for a negative outcome. If I look in here in my credential history, I do have a tyront2.8 user and then I am going to now add in a legit password and let's see what happens. Okay, so HubSpot returned the user and whoa, congrats, your credentials were successfully found. Okay, so part of this demo is that we are always saving these attempts to our database. We actually have a database table called login history. And you can see right here, we had an unsuccessful attempt. We tried again with the right password. We got a successful attempt. Okay, great. So now that we have a baby app, now the question is, how do we get this into HubSpot? This is, this is the million dollar question. I got this app, how do I get it in there? Okay, we're going to go back to our app. We are then going to go to CRM Card. Got to discard any changes because we're just kind of fiddling around and I've created a CRM call CRM card called login History. Now where do we want the CRM card to appear? We want it to appear on the contacts record. So what this means is that Every single a HubSpot contact page is opened. HubSpot says please give me. I want to create the CRM card for you, but give me some direction. I need some data to know what to show on the CRM card. Point me to someplace public on the Internet where I can go to, that I can think about. Hey, I want to. He wants me to show this about the user, he wants me to show that about the contact. Where should I go? That is what this data fetch URL is ultimately. And when you, when you specify this in, you can actually say hey, as part of your request to this URL, I want to add a bunch of crap in here. The object id, the first name, the last name, the email, all these things will become query string attributes to this location. Okay? And if you are curious what is coming out of this, you can always go to monitor, we'll go to discard real quick CRM extensions and you can actually see what HubSpot is requesting. This is, this will help you debug and find out what the heck is going on. Right. Okay, so if we go back to my tyron and aptitude that a user, I have a contact in here already. I tried to log in with him two times as we saw previously. One time unsuccessful, second time successfully. I have a CRM card that I have generated and this is what's being generated. Now your question might be hey, where in the world did all that crap just come from? Fantastic question. I said let's find out. Okay, so this is ultimately, if you look here in the URL, we have CRM-card JSON that directly goes to this CRM card that I just made. So what happens is the. Tyrone Faustin. I'm just going to load this page up again. Part of what takes the contact part so long to load up and you see all this stuff here on the right hand side all loaded up is that HubSpot is making like a crap ton of HTTP calls in the background specifically to wherever you specify. And if we look right here, you can see that we have our CRM card that is loaded. It has master class contact summary. It's got a little bit of data that I specified. It's got a, it's got a little button here and there's login history. Great, great, great. Show me where this got generated at again. If we go to our monitoring, we go under CRM extensions. This is it right here. And in fact, as you, as you look at the details, this is the exact URL that was actually being called. So if we copy this, we put it in the browser. This is the JSON that was generated that built this CRM card. So if we, let's, let's look at this JSON and let's pretty up fight, if that is the word, let's throw it here in our bit and we can kind of take a look at it. Okay, so this CRM card came from this JSON code. You'll see the title is masterclass Contact Login Summary, which directly correlates to this title here, Login success. And then you'll see a few other lines, Successful login percentage and total IPs. Now if you look at these, these are properties of the CRM card. For each property that you want to show, you actually do have to specify the data type and whatever data is that you want to show. And then the label. Okay. Also part of that, if you notice, there's a actions dropdown button and a login history. That login history comes from right here. Here you see the actions and then the actions is an array. And just like you saw login history, you'll see login history here. So this directly correlates to that. And then this is going to. Ultimately, when I click on this login history is going to pop up as an iframe. And the dimension of that iframe is specified here and here. Now if you look at this CRM, if you look at this, the page that generates the CRM card, it's CRM card JSON that directly correlates to this script right here in the repo. So here I'm actually going to the URL scope. I'm looking for the HS object id, which we know got passed over. I'm looking right here in our login history. So I'm basically just doing a database search and then I'm dumping that out to make my JSON response. So I've got a, I've got a very generic object. I'm populating it with the title like we saw beforehand, the description like we saw beforehand. I'm populating my properties array like we just saw beforehand. I'm populating my actions array like we just saw beforehand. All this is a direct correlation. And then I'm dumping all that JSON to the screen. And the result of that is this content right here. Okay, so now that we have the ability. We have an app, we are able to output. We were able to create a CRM card. We're able to generate content for that CRM card. We can actually see that CRM card on the contact. Let's go ahead and hit our login history button. And it's an iframe in of a page that we are in control with. So the page what just got iframed in is this bad boy right here. So actually for better visuals is this bad boy right here. We just iframed in this page. And remember, we are in control of this page. This page Here is CRNCard CFM, which directly correlates to this page right here. Only thing I'm doing here, looking at the URL contact id, going to the database and then looping over the database rows and dumping it to a table. That's what this page is right here. So it looks, it's in the HubSpot UI, looks like it's coming from HubSpot. But actually this comes from the middleware that we built. This is how you get your data, your content, your middleware, your app ultimately into HubSpot so that users have one place where they can go and do everything. Normally what you would want to do is you would maybe want to do some additional contact management Here you can have a form here you can have everything. You are in complete control of this page because it's iframed in from some location that you specified. The only true caveats with having your iframe in is that it has to use HTTPs. There's no way around that. HubSpot will simply not load it, but which really should not be a deal. Honestly, we should be worried about security from every standpoint possible. So trying to think. I think that may cover most of everything that we want to do. So from end to end, we've pretty much built an app. We've got it into HubSpot. We created our CRM card. We're showing the CRM card inside of HubSpot. We've talked about assets, tokens, we've talked about refresh tokens. Again, the git repo is publicly accessible. It also has the wrapper class in here, which I would definitely tell you guys to leverage. It also has the database definition in here as well. And so with that, I would like to take a quick pause and let's go about answering any questions you guys might have.
First of all, I want to say, Tyrone, that's some great content. Also, I'm allowing you to turn on your video I apologize. That was my fault. And go ahead. Hey, there you are, friend.
There I am. It was just a talking. A talking head all this time.
Yes, yes. Ton of information here guys. So I can understand it if this is a little overwhelming. But yeah, we're here for any Q and A. If you can't think of it right now, which I totally understand, you probably want to go re watch that content about 3,000 times. There is the issues in that GitHub repository that go ahead and submit them there and we'll make sure we get to them from there as well.
Yeah, for sure. I would add them there. If anyone wants to talk about just application development in general, very welcome to reach out or grab some time on a calendar. I definitely will give you a few minutes and answer any questions you have, especially around business decisions and or security. I always like to specify that developing an app on the HubSpot is actually really easy because it's just developing your own app. The number one question we get is how in the world do you get it in there? And that ultimately is the part that we really just kind of talked about. And I think that's where you know, this, this meeting hopefully really helps. And you know, each one teach one.
I think one of the common ones too is for the, for the no coders out there that are using platforms such as Bubble IO and tons of other awesome no code platforms. Because the idea, Tyrone, if you could speak on this. I know we don't use no code because you code, but the idea is that if you're able to accomplish these simple steps such as authentication token refreshing, building a JSON file right, based upon whatever, you could be able to utilize a no code platform. Do you want to speak a little bit on that?
You know, I generally take the approach of Bio Rebuild. So if there is a way to do something with low code or maybe with an existing service, assuming you know this isn't like something kind of blow up your budget, I would do it. The rationale there is every line of code ultimately cost something either initially or down the line for maintenance. And so you know, if you, if you can find some kind of, some kind of middleware that would definitely do that for you, 100% would recommend leveraging that.
Then we had a question from David Roma about passing the server piece to a serverless solution like Google Cloud functions or aws. I know you can talk about that for another hour if you want about the involvement of aws, but if you want to touch on a little bit how potentially how associate Works with the utilization of lambdas and the messages. That would be kind of helpful.
Yeah. David, feel free to update your question here. I want to. I'm going to take a stab at it. One thing that you may want to consider is the CRM card gets loaded every single time someone opens up a contact record. In this particular example, a lot of times you may have it where the CRM card opens up on tickets and deals and contacts and companies. Right. And you're talking about a lot of page requests that HubSpot is making to get contents to ultimately build your CRM card. A easy recommendation there is actually, if you're thinking about scalability and you're thinking about load, is to use maybe an AWS lambda to actually handle those requests. The, the, the. Obviously the thing is, you don't necessarily know when spikes are going to occur, and you want to make sure the CRM card is always available. So it's very easy to recommend that you put the logic that generates that JSON into an AWS lambda or some other kind of compute that spins up and spins down. And, and maybe it's not an AWS lambda. Maybe it's just a EC2 instance or compute instance that you keep warm. It can handle the scaling with a scaling group, but it is something that you will want to be concerned about, especially if you see page loads. If you see a lot of requests kind of coming down the pipeline, I hope that answers your question. If not, feel free to ask again. I'll take another step at. Any other thoughts? There's no, no such thing as a bad question and definitely very happy to help.
Just out of curiosity, how, how often are you checking your rate limits? I mean, what's, what's your process for that? You just said, like going back and forth, hitting that CRM card every time you're loading data. Do you ever have issues with that? I mean, you have a lot of service.
Yeah, so we, for example, we have an app called Associate, which handles a lot of things that come out of the HubSpot workflow engine, which we actually check every day. We have alerts set up that basically kind of let us know what's going on. So as far as the CRM card, we actually have a couple of servers involved with a load balancer and a scaling group because we handle millions of requests per month from people opening everything, right? So we have CRM cards on contacts, tickets, deals, you name it. And so ultimately we have millions of requests. And so it's usually very important that the CRM card is Readily available because the apps that we build, people are expecting a CRM card to be there every day, all day. Now, the good thing is if it bombs, maybe the first time, maybe we refresh on the second time, terrible thing to know, but definitely does happen. And that's an architectural issue. You could definitely talk about another day. But you want to make sure that as your app grows, especially if you use an OAuth and expecting a lot of people, that is something that is going to get hit a lot. Cool.
I think that's good. Once again, I just want to put it out there. If you got questions, seriously put in that GitHub repo. You know, there's an issues section to add there. These guys are freaking smart. So take advantage while you can, because why not, right? You will have questions, go out there, play with this. Because you're going to learn a lot. Just, you know, one thing is watching someone do it. The other, when you do it yourself, you're going to hit issues, you're going to hit roadblocks and you want these people here to be able to help you out. So yeah, submit those issues.
Yeah. And just actually wanted to think about David Roma there. Again, part of the things you may want to kind of consider is if you have an AWS lambda that handles a lot of your CRM card requests, because that thing will get beat up. It's great to have a lambda because AWS will handle the scaling for you. In addition to, you will also want to use an RDS processing if your lambda connects to your database. That will protect your lambda from blowing up the number of connections that go to your database. You may also want to kind of consider caching because lambdas can get spun up. You can have a thousand lambdas spin up and they will all descend on your data stores like no man beforehand and your database can choke. So you may want to consider some caching or if you go into the database, an RDS proxy or something of the like is definitely going to be needed. So just wanted as I was just kind of brainstorming in my head there. Cool.
I apologize. I'm going to butcher your name. I apologize for this. Ciara or Chiara asked. I think a pretty legitimate question here, but at level, at level in one's tech career, at what level in one's tech career would this be something that one would understand and utilize?
So the expectation is to build an app like we just built. This is a junior level could do this. That is just simply building the app, getting it ready. A lot of the stuff that I talked about that maybe spoke to David's question are definitely more advanced. But to build the app that we just talked about in terms of like, hey, I've got an application server, I've got a web server, I've got a database. So that is definitely junior dev would be able to handle that. So I like to think that from a skill sets perspective or from a senior rich perspective, HubSpot apps can be done from the very bottom all the way to the very top. The only thing you really need is ultimately a good plan.
Yep, just get in there and do it. That's what I'd say. You know, like, I remember the first time I looked at APIs, I was scared as all get up and now, you know, I feel pretty good about it. So just do it.
Yep. Agreement. I tend to think that the HubSpot community is actually really, really, really kind really, really there. We really just want to. Part of this is to make more video content, to just make it just easy, even, even easier when it comes to accessibility because we have a lot of people who are getting into HubSpot development and unfortunately developers, a lot of times we like to go into a closet and we don't really share our info with anybody. And you know, while the community is there, the community is all working. They're all, they're all busy building their own app too. And so it's, it's good if you can, you know, jump on a stack overflow where you can hop on a masterclass video and kind of spend a few minutes following along and you know, pick up, pick up a. Hopefully solve a problem that you just had and we solved for you.
That's right. And this content is going to be on our YouTube developer channel, so you can check it out there. As you can see in that readme on the GitHub repo, I've added links to the first one. I forgot to put the presentation, the deck in there. So I'll make sure to fix that soon. And someone mentioned that the code's not actually in the repo yet, but we'll make sure we get that fixed.
Yeah, there's another branch called master branch. Ask me to go to that. I will clean that up sometime over the next day or two. Perfect. But I think it is all there.
All right, so join us next week. I think Dax is going to be talking quite a bit next week, so same bet time as I said last time and once again, if you want to come to the Q A session, which is two weeks from now, please sign up that registration form. It's a different registration. I just don't want you to miss it. Oh, I'm sorry. One last question, if you guys don't mind. Wait, did it go to the left? Never mind, it's gone. All right, so have a great time, guys. Let's. We'll see you again next week and enjoy the rest of your week. Okay?
See everyone. Night.
Thank you.










