API Times out on Updating multiple contacts


#1

Hi,

I have a list of customers for my web app in MSSQL DB. I need to import them in Hubspot. So i have written an Api that checks if contact already exists, if so the contact’s phone number, company etc. is updated and if not then a new contact is added.

I am also adding the companies to Hubspot which are not in Hubspot but are there in MSSQL db and then associating contacts with them.

Now the issue is for some customers its running pretty well, but for some contacts its timing out. For example: https://api.hubapi.com/contacts/v1/contact/email/chinmmay@gmail.com/profile?hapikey={myapikey} is timing out. As most of the contacts are getting imported, so is there any specific reason why some of them are timing out.

Thanks.


#2

@Chinmay_Sharma I have had a similar result before. I received it when I was writing my calls in nodejs which would fire everything off asynchronously all at once. The timeout issue was ultimately because my code was running to fast. We have some safety measures in place to protect our servers from DDOS attacks. One way to solve this would be to have a delay loop in your code so you only fire off a couple per second instead of a 100 requests to our server for every second. Try and stay under 10 for starters and let me know how that works out. What language are you writing it in?


#3

I have coded it in .net + C# windows service. Though my service is synchronous but i’ll try putting a delay.


#4

@pmanca Just an update, that it fails even when i am debugging. So which makes it sure that its not the problem with delay.


#5

@Chinmay_Sharma Is there any sort of pattern to it? Or is it just randomly failing on you?


#6

@Chinmay_Sharma Does it fail on contacts that don’t exist? or both ones that do and don’t exist?


#7

@pmanca Atleast for now i haven’t noticed any pattern yet. Out of 7000 records, first two work perfectly problem starts from 3rd record onwards. But i am sure most of them will be in Hubspot.


#8

@Chinmay_Sharma are you pulling your list of customers from your database sequentially? Is it the same 3rd contact each time?


#9

@pmanca From my MSSQL Database i receive a dataset of contacts which i need to update also some fields which need some calculation and then set the custome fields in HubSpot.

And 3rd contact is always same.


#10

@Chinmay_Sharma Does that 3rd contact cause a timeout outside of your code? If you were to try the call in postman or a similar tool?


#11

@pmanca No, when i paste the URL in the browser it fetches me record instantly. The service timesout during the service call of “Search Contact by email” .


#12

@pmanca Here i am defining the steps for my code

Step1: Fetch all companies from HubSpot(Multiple API calls so added delay of 2 seconds between each call)
Step2: Fetch Contact details to be Sync from MSSQL Database
Step3: Iterate each contact from MSSQL database
a. Search for email address if already exists(Here the service gets timeout from the 3rd record)
- If no, then create the contact with the details and get the VID
- If yes, then update the contact with the details as per VID
b. If the VID doesn’t have associated company and Contact from MSSQL has a company then Search for company from list fetch in step 1.
- If match found, associate contact with that company
- If no match found, create the company the associate that contact with the company.
Step 4: Finish


#13

@Chinmay_Sharma Thanks for laying it out. Two questions for you. Does that 3rd contact exist? Does all your data come over in the same format? I am assuming in your loop is just a variable so when the 3rd contact comes around and the value gets assigned to that variable does it break the call? I ask under the assumption when you tested it out in your browser you had manually typed it in yourself.


#14

@pmanca Yes that contact exists. No, i didn’t put any additional characters. Just copy the value from URL variable and pasted it in the Browser.


#15

@Chinmay_Sharma Can you post the exact error response you are getting from the server?


#16

@pmanca

Request URL: https://api.hubapi.com/contacts/v1/contact/email/gustav@argus-revisjon.no/profile?hapikey={myapikey}

Response is null

Exception: Operation is Timeout
System.Net.WebException was caught
HResult=-2146233079
Message=The operation has timed out
Source=System
StackTrace:
at System.Net.HttpWebRequest.GetResponse()
at HubspotAPIWrapper.WindowsWebClient.UploadString(String uri, String method, String contentType, String data) in g:\SOKOWindowsService\SOKOWindowsService\SokoWindowsService\HubSpot\WindowsWebClient.cs:line 27
InnerException:


#17

@Chinmay_Sharma what is the domain tied to your portal so I can look it up? It is tough to debug this from afar. If we can reach the contacts via a normal API call then I am not positive why you are seeing issues with the results from your code.


#18

The domain is autogear.no


#19

@Chinmay_Sharma Any chance I can see the function that cycles through the contacts? I would like to try and reset up something on my end. I as well can get that one contact with out a problem through the browser. I would like to try and automate it as well with 4 or 5 contacts.


#20

Below are all major functions used in my call:

//Main Function 
public void HubSpotImport()
        {
            try
            {
                
                using (AutogearEntities db = new AutogearEntities())
                {
                    int CountTripsNeedtoMove = 0;
                    var dt = db.HubSpotUserIntegration();
                    var UsersNeedtoMove = dt.ToList();
                    CountTripsNeedtoMove = UsersNeedtoMove.Count();
                    int CountNew = 0, Existing = 0;

                    List<HubSpotCompany> AllCompanies = GetAllCompaniesFromHubSpot();
                    HubspotAPIWrapper.Contacts contact = new HubspotAPIWrapper.Contacts();
                    HubspotAPIWrapper.Companies companies = new HubspotAPIWrapper.Companies();

                    string ResponseMessage = "";
                    string HubSpotcompanyId = "";
                    Log("HubSpotIntegration service HubSpotImport");
                    
                    bool IsCompnayExist = false;
                    string LifeCycleStage = "", LeadStatus = "";
                    if (UsersNeedtoMove.Count > 0)
                    {
                        foreach (var i in UsersNeedtoMove)
                        {
                            int milliseconds = 1000;
                            Thread.Sleep(milliseconds);
                            int ActiveSubscriptionCount = (int)i.ActiveAirCount + (int)i.ActiveConnectCount + (int)i.ActiveFreeCount;
                            int ChurnedSubscriptionCount = (int)i.ChurnedAirCount + (int)i.ChurnedConnectCount + (int)i.ChurnedFreeCount;
                            int TotalSubscriptions = ActiveSubscriptionCount + ChurnedSubscriptionCount;
                            try
                            {
                                string HubSpotvid = "";
                                //Write code to find user by email

                                IsCompnayExist = false;
                                if (TotalSubscriptions == 0)
                                {
                                    LifeCycleStage = "other";
                                    LeadStatus = "REGISTERED ONLY";
                                }
                                else
                                {
                                    if (ActiveSubscriptionCount != 0)
                                    {
                                        LifeCycleStage = "customer";
                                        if (((int)i.ActiveAirCount + (int)i.ActiveConnectCount) > 0)
                                        {
                                            LeadStatus = "ACTIVE CUSTOMER";
                                        }
                                        else
                                        {
                                            LeadStatus = "Active free customer";
                                        }
                                    }
                                    else
                                    {
                                        LifeCycleStage = "other";
                                        LeadStatus = "CHURNED";
                                    }
                                }
                                var GetContactByEmail = contact.GetContactByEmailAddress(i.Email.Trim());
                                if (GetContactByEmail.ToString().Contains("contact does not exist"))
                                {
                                    string CreateContactJSON = "";
                                    if (i.Phone.Trim() != "")
                                    {
                                        CreateContactJSON = "{\"properties\":[{\"property\":\"email\",\"value\":\"" + i.Email + "\"},{\"property\":\"firstname\",\"value\":\"" + i.FirstName + "\"},{\"property\":\"lastname\",\"value\":\"" + i.LastName + "\"},{\"property\":\"phone\",\"value\":\"" + i.Phone.Trim() + "\"},{\"property\":\"lifecyclestage\",\"value\":\"" + LifeCycleStage + "\"},{\"property\":\"hs_lead_status\",\"value\":\"" + LeadStatus + "\"},{\"property\":\"free_subscription_count\",\"value\":\"" + i.ActiveFreeCount + "\"},{\"property\":\"connect_devices_count\",\"value\":\"" + i.ActiveConnectCount + "\"},{\"property\":\"air_devices_count\",\"value\":\"" + i.ActiveAirCount + "\"},{\"property\":\"churned_free_subscriptions\",\"value\":\"" + i.ChurnedFreeCount + "\"},{\"property\":\"churned_connect_subscriptions\",\"value\":\"" + i.ChurnedConnectCount + "\"},{\"property\":\"churned_air_subscriptions\",\"value\":\"" + i.ChurnedAirCount + "\"}]}";
                                    }
                                    else
                                    {
                                        CreateContactJSON = "{\"properties\":[{\"property\":\"email\",\"value\":\"" + i.Email + "\"},{\"property\":\"firstname\",\"value\":\"" + i.FirstName + "\"},{\"property\":\"lastname\",\"value\":\"" + i.LastName + "\"},{\"property\":\"lifecyclestage\",\"value\":\"" + LifeCycleStage + "\"},{\"property\":\"hs_lead_status\",\"value\":\"" + LeadStatus + "\"},{\"property\":\"free_subscription_count\",\"value\":\"" + i.ActiveFreeCount + "\"},{\"property\":\"connect_devices_count\",\"value\":\"" + i.ActiveConnectCount + "\"},{\"property\":\"air_devices_count\",\"value\":\"" + i.ActiveAirCount + "\"},{\"property\":\"churned_free_subscriptions\",\"value\":\"" + i.ChurnedFreeCount + "\"},{\"property\":\"churned_connect_subscriptions\",\"value\":\"" + i.ChurnedConnectCount + "\"},{\"property\":\"churned_air_subscriptions\",\"value\":\"" + i.ChurnedAirCount + "\"}]}";
                                    }
                                    JObject AddContactResponse = contact.CreateNewContact(CreateContactJSON);
                                    if (AddContactResponse["status"] != null)
                                    {
                                        string ResponseStatus = AddContactResponse.SelectToken(@"status").Value<string>();
                                        if (ResponseStatus == "error")
                                        {
                                            ResponseMessage = AddContactResponse.SelectToken(@"message").Value<string>();
                                            if (ResponseMessage == "Contact already exists")
                                            {
                                                Existing++;
                                                HubSpotvid = AddContactResponse.SelectToken(@"identityProfile.vid").Value<string>();
                                                string UpdateContactJSON = "";
                                                if (i.Phone.Trim()!="")
                                                {
                                                    UpdateContactJSON = "{\"properties\":[{\"property\":\"phone\",\"value\":\"" + i.Phone.Trim() + "\"},{\"property\":\"lifecyclestage\",\"value\":\"" + LifeCycleStage + "\"},{\"property\":\"hs_lead_status\",\"value\":\"" + LeadStatus + "\"},{\"property\":\"free_subscription_count\",\"value\":\"" + i.ActiveFreeCount + "\"},{\"property\":\"connect_devices_count\",\"value\":\"" + i.ActiveConnectCount + "\"},{\"property\":\"air_devices_count\",\"value\":\"" + i.ActiveAirCount + "\"},{\"property\":\"churned_free_subscriptions\",\"value\":\"" + i.ChurnedFreeCount + "\"},{\"property\":\"churned_connect_subscriptions\",\"value\":\"" + i.ChurnedConnectCount + "\"},{\"property\":\"churned_air_subscriptions\",\"value\":\"" + i.ChurnedAirCount + "\"}]}";
                                                }
                                                else
                                                {
                                                    UpdateContactJSON = "{\"properties\":[{\"property\":\"lifecyclestage\",\"value\":\"" + LifeCycleStage + "\"},{\"property\":\"hs_lead_status\",\"value\":\"" + LeadStatus + "\"},{\"property\":\"free_subscription_count\",\"value\":\"" + i.ActiveFreeCount + "\"},{\"property\":\"connect_devices_count\",\"value\":\"" + i.ActiveConnectCount + "\"},{\"property\":\"air_devices_count\",\"value\":\"" + i.ActiveAirCount + "\"},{\"property\":\"churned_free_subscriptions\",\"value\":\"" + i.ChurnedFreeCount + "\"},{\"property\":\"churned_connect_subscriptions\",\"value\":\"" + i.ChurnedConnectCount + "\"},{\"property\":\"churned_air_subscriptions\",\"value\":\"" + i.ChurnedAirCount + "\"}]}";
                                                }
                                                
                                                contact.UpdateExistingContact(HubSpotvid, UpdateContactJSON);
                                                if (i.Company.Trim() != "")
                                                {
                                                    HubspotAPIWrapper.ContactProperty contactsProp = new HubspotAPIWrapper.ContactProperty();
                                                    var ContactByIDResponse = contact.GetContactById(HubSpotvid);
                                                    var ContactByIDResult = HubspotAPIWrapper.ResponseClass.JsonDeserialize<HubspotAPIWrapper.ContactResult>(ContactByIDResponse.ToString());


                                                    if (ContactByIDResult.properties.associatedcompanyid != null)
                                                    {
                                                        IsCompnayExist = true;
                                                    }
                                                    else
                                                    {
                                                        IsCompnayExist = false;
                                                    }
                                                }
                                            }

                                        }
                                    }
                                    else
                                    {
                                        CountNew++;
                                        HubSpotvid = AddContactResponse.SelectToken(@"vid").Value<string>();
                                    }
                                }
                                else
                                {
                                    Existing++;
                                    HubSpotvid = GetContactByEmail.SelectToken(@"vid").Value<string>();
                                    string UpdateContactJSON = "";
                                    if (i.Phone.Trim() != "")
                                    {
                                        UpdateContactJSON = "{\"properties\":[{\"property\":\"phone\",\"value\":\"" + i.Phone.Trim() + "\"},{\"property\":\"lifecyclestage\",\"value\":\"" + LifeCycleStage + "\"},{\"property\":\"hs_lead_status\",\"value\":\"" + LeadStatus + "\"},{\"property\":\"free_subscription_count\",\"value\":\"" + i.ActiveFreeCount + "\"},{\"property\":\"connect_devices_count\",\"value\":\"" + i.ActiveConnectCount + "\"},{\"property\":\"air_devices_count\",\"value\":\"" + i.ActiveAirCount + "\"},{\"property\":\"churned_free_subscriptions\",\"value\":\"" + i.ChurnedFreeCount + "\"},{\"property\":\"churned_connect_subscriptions\",\"value\":\"" + i.ChurnedConnectCount + "\"},{\"property\":\"churned_air_subscriptions\",\"value\":\"" + i.ChurnedAirCount + "\"}]}";
                                    }
                                    else
                                    {
                                        UpdateContactJSON = "{\"properties\":[{\"property\":\"lifecyclestage\",\"value\":\"" + LifeCycleStage + "\"},{\"property\":\"hs_lead_status\",\"value\":\"" + LeadStatus + "\"},{\"property\":\"free_subscription_count\",\"value\":\"" + i.ActiveFreeCount + "\"},{\"property\":\"connect_devices_count\",\"value\":\"" + i.ActiveConnectCount + "\"},{\"property\":\"air_devices_count\",\"value\":\"" + i.ActiveAirCount + "\"},{\"property\":\"churned_free_subscriptions\",\"value\":\"" + i.ChurnedFreeCount + "\"},{\"property\":\"churned_connect_subscriptions\",\"value\":\"" + i.ChurnedConnectCount + "\"},{\"property\":\"churned_air_subscriptions\",\"value\":\"" + i.ChurnedAirCount + "\"}]}";
                                    }
                                    //string UpdateContactJSON = "{\"properties\":[{\"property\":\"lifecyclestage\",\"value\":\"" + LifeCycleStage + "\"},{\"property\":\"hs_lead_status\",\"value\":\"" + LeadStatus + "\"},{\"property\":\"free_subscription_count\",\"value\":\"" + i.ActiveFreeCount + "\"},{\"property\":\"connect_devices_count\",\"value\":\"" + i.ActiveConnectCount + "\"},{\"property\":\"air_devices_count\",\"value\":\"" + i.ActiveAirCount + "\"},{\"property\":\"churned_free_subscriptions\",\"value\":\"" + i.ChurnedFreeCount + "\"},{\"property\":\"churned_connect_subscriptions\",\"value\":\"" + i.ChurnedConnectCount + "\"},{\"property\":\"churned_air_subscriptions\",\"value\":\"" + i.ChurnedAirCount + "\"}]}";
                                    contact.UpdateExistingContact(HubSpotvid, UpdateContactJSON);
                                    
                                    var ContactByIDResult = HubspotAPIWrapper.ResponseClass.JsonDeserialize<HubspotAPIWrapper.ContactResult>(GetContactByEmail.ToString());
                                    if (ContactByIDResult.properties.associatedcompanyid != null)
                                    {
                                        IsCompnayExist = true;
                                    }
                                    else
                                    {
                                        IsCompnayExist = false;
                                    }
                                }

                                if (!IsCompnayExist && i.Company.Trim() != "")
                                {
                                    var HubCompanyid = AllCompanies.Where(c => c.Name.ToLower().Trim() == i.Company.ToLower().Trim()).Take(1).Select(id => id.CompanyId).SingleOrDefault();
                                    if (HubCompanyid != null && HubCompanyid != 0)
                                    {
                                        HubSpotcompanyId = HubCompanyid.ToString();
                                    }
                                    else
                                    {
                                        string CreateCompanyJSON = "{\"properties\":[{\"name\":\"name\",\"value\":\"" + i.Company + "\"},{\"name\":\"description\",\"value\":\" \"}]}";
                                        JObject AddCompanyResponse = companies.CreateNewCompany(CreateCompanyJSON);
                                        HubSpotcompanyId = AddCompanyResponse.SelectToken(@"companyId").Value<string>();
                                    }

                                    JObject AddContactToCompany = companies.AddContactToCompany(HubSpotcompanyId, HubSpotvid);

                                }
                            }
                            catch (Exception et)
                            {

                            }
                        }

                    }

                }
            }
            catch (Exception err)
            {

            }
        }

        public List<HubSpotCompany> GetAllCompaniesFromHubSpot()
        {
            List<HubSpotCompany> HSCompany = new List<HubSpotCompany>();
            try
            {
                int milliseconds = 2000;
                Thread.Sleep(milliseconds);
                HubspotAPIWrapper.Companies companies = new HubspotAPIWrapper.Companies();
                string propertyName = "name";
                int offset = 0, total = 0;
                bool hasMore = false;
                do
                {
                    
                    JObject AddContactResponse = companies.GetAllCompanies(offset: offset, property: propertyName);
                    var CompanyResult = HubspotAPIWrapper.ResponseClass.JsonDeserialize<HubspotAPIWrapper.CompanyResult>(AddContactResponse.ToString());
                    foreach (var result in CompanyResult.companies)
                    {
                        HubSpotCompany c = new HubSpotCompany();
                        if (result.properties.name != null && !result.isDeleted)
                        {
                            c.Name = result.properties.name.value;
                            c.CompanyId = result.companyId;
                            HSCompany.Add(c);
                        }
                        

                        
                        
                    }
                    offset = CompanyResult.offset;
                    //total = CompanyResult.total;
                    hasMore = Convert.ToBoolean(JObject.Parse(AddContactResponse.ToString())["has-more"].ToString());
                } while (hasMore);

                if (HSCompany != null && HSCompany.Count > 0)
                {
                    //ExportToExcel(HSCompany);
                }

            }
            catch (Exception err)
            {

            }
            return HSCompany;

        }
		
		public JObject GetContactByEmailAddress(string emailAddress, string property = "")
        {
            var optionalParams = new Dictionary<string, string>();
            if (property.Length > 0)
            {
                optionalParams["property"] = property;
            }
            var subPath = string.Format("contact/email/{0}/profile", emailAddress);
            return Call(subpath: subPath, optionalParams: optionalParams);
        }
		
		protected JObject Call(string subpath, string method = "GET", string query = "", string contentType = "application/text",
                                  string data = "", Dictionary<string, string> optionalParams = null, string other = "")
        {
            string uri;

            if (_accessToken != null)
            {
                uri = String.Format("https://{0}/{1}?access_token={2}", _options["api_base"],
                                    GetPath(subpath), _accessToken);
            }
            else
            {
                uri = String.Format("https://{0}/{1}?hapikey={2}", _options["api_base"],
                                    GetPath(subpath), _apiKey);
            }

            if (query.Length > 0)
            {
                uri = string.Format("{0}&q={1}", uri, query);
            }

            if (other.Length > 0)
            {
                uri = string.Format("{0}&{1}", uri, other);
            }

            if (optionalParams != null)
            {
                uri = optionalParams.Aggregate(uri,
                                               (current, optionalParam) =>
                                               string.Format("{0}&{1}={2}", current, optionalParam.Key,
                                                             optionalParam.Value));
            }
            //Debug.WriteLine(uri);
            var returnVal = UserWebClient.UploadString(uri, method: method, contentType: contentType, data: data);

            if (returnVal != null)
            {
                if (returnVal.Length > 0)
                {
                    return JObject.Parse(returnVal);
                }
            }

            return new JObject();
        }
		
		public string UploadString(string uri, string method = "GET", string contentType = "application/text",
                                   string data = "")
        {
            string responseText="";
            var request = (HttpWebRequest) WebRequest.Create(uri);
            request.Method = method;
            request.ContentType = contentType;

            if (data.Length > 0)
            {
                var writer = new StreamWriter(request.GetRequestStream());
                writer.Write(data);
                writer.Close();
            }


            try
            {
                var response = (HttpWebResponse) request.GetResponse();
                Stream responseStream = response.GetResponseStream();
                if (responseStream != null)
                {
                    var streamReader = new StreamReader(responseStream);
                    return streamReader.ReadToEnd();
                }
            }
            catch (WebException e)
            {
                try
                {
                    using (var response = (HttpWebResponse)e.Response)
                    {
                        Console.WriteLine("Error code: {0}", response.StatusCode);
                        Stream responseStream = response.GetResponseStream();
                        if (responseStream != null)
                        {
                            var reader = new StreamReader(responseStream);
                            responseText = reader.ReadToEnd();
                            return responseText;
                        }
                    }
                }
                catch (Exception etg)
                {

                }
            }

            return String.Empty;
        }