Пример #1
0
        /// <summary>
        /// Update arbitrary contact properties
        /// </summary>
        /// <param name="vid">the unique HubSpot ID of the Contact</param>
        /// <param name="props">A HubSpotContactProperties object that specifies all the properties to be changed</param>
        /// <param name="log"></param>
        /// <param name="isTest"></param>
        /// <returns></returns>
        public async Task <HubSpotContactResult> UpdateContactDetailsAsync(
            string vid,
            HubSpotContactProperties props,
            ILogger log,
            bool isTest)
        {
            // Check that the appropriate Hubspot API key was correctly retrieved in the static constructor
            var activeHapiKey = isTest ? sandbox_hapikey : hapikey;

            if (string.IsNullOrEmpty(activeHapiKey))
            {
                return(new HubSpotContactResult(HttpStatusCode.InternalServerError, "Hubspot API key not found"));
            }

            var url = string.Format($"https://api.hubapi.com/contacts/v1/contact/vid/{vid}/profile?hapikey={activeHapiKey}");

            log.LogInformation($"Updating {vid} details");
            HttpResponseMessage response = await httpClient.PostAsJsonAsync(url, props);

            // Check Status Code.
            if (response.StatusCode == HttpStatusCode.NoContent)
            {
                log.LogInformation("Hubspot status update OK");
                var retval = new HubSpotContactResult(HttpStatusCode.OK);
                return(retval);
            }
            else
            {
                // Some kind of error - return the status code and body to the caller of the function
                string resultText = await response.Content.ReadAsStringAsync();

                log.LogError("Hubspot update failed: {0}: {1}", response.StatusCode, resultText);
                return(new HubSpotContactResult(response.StatusCode, resultText));
            }
        }
Пример #2
0
        /// <summary>
        /// Utility method that retrieves a Hubspot contact from the API and extracts the most important parameters into a structure.
        /// </summary>
        /// <param name="url">A valid GET url for retrieving a Hubspot contact. It's expected to have the hapikey on the url</param>
        /// <param name="fetchPreviousValues"></param>
        /// <returns></returns>
        private async Task <HubSpotContactResult> RetrieveHubspotContactWithUrl(string url, bool fetchPreviousValues, ILogger log)
        {
            // Go get the contact from HubSpot using the supplied url
            HttpResponseMessage response = await httpClient.GetAsync(url);

            HttpContent content = response.Content;

            // Check Status Code. If we got the Contact OK, then raise the appropriate event.
            if (response.StatusCode == HttpStatusCode.OK)
            {
                // All good. Read the string out of the body
                string resultText = await content.ReadAsStringAsync();

                //log.LogInformation(resultText);
                var canonicalContact = ConvertHubspotJsonToCanonicalContact(resultText, fetchPreviousValues, log);

                var retval = new HubSpotContactResult(canonicalContact);
                return(retval);
            }
            else if (response.StatusCode == HttpStatusCode.NotFound)
            {
                // NotFound error
                return(new HubSpotContactResult(response.StatusCode, response.ReasonPhrase));
            }
            else
            {
                // Some other error
                string resultText = await content.ReadAsStringAsync();

                return(new HubSpotContactResult(response.StatusCode, resultText));
            }
        }
Пример #3
0
        /// <summary>
        /// Create a contact in Hubspot.
        /// </summary>
        /// <param name="email"></param>
        /// <param name="firstname"></param>
        /// <param name="lastname"></param>
        /// <returns>Returns the created contact. If a contact with this email already exists, returns the conflicting contact from HubSpot</returns>
        /// <see cref="https://developers.hubspot.com/docs/methods/contacts/create_contact"/>
        public async Task <HubSpotContactResult> CreateHubspotContactAsync(
            string email,
            string firstname,
            string lastname,
            string preferredName,
            string primaryPhone,
            string streetAddress1,
            string streetAddress2,
            string city,
            string state,
            string postcode,
            string leadStatus,
            bool installationRecordExists,
            ILogger log,
            bool isTest)
        {
            // Check that the appropriate Hubspot API key was correctly retrieved in the static constructor
            var activeHapiKey = isTest ? sandbox_hapikey : hapikey;

            // Check that the Hubspot API key was correctly retrieved in the static constructor
            if (string.IsNullOrEmpty(activeHapiKey))
            {
                return(new HubSpotContactResult(HttpStatusCode.InternalServerError, "Hubspot API key not found"));
            }

            if (!(new EmailAddressAttribute().IsValid(email)))
            {
                return(new HubSpotContactResult(HttpStatusCode.InternalServerError, "New Contact email address not supplied"));
            }

            // To send a Contact to Hubspot via the API we need an object that will serialise into a bunch of {property, value} pairs
            HubSpotContactProperties newContactProperties = AssembleContactProperties(
                email,
                firstname,
                lastname,
                preferredName,
                primaryPhone,
                streetAddress1,
                streetAddress2,
                city,
                state,
                postcode,
                leadStatus,
                installationRecordExists);

            if (newContactProperties == null)
            {
                return(new HubSpotContactResult(HttpStatusCode.InternalServerError, "unhandled error assembling new contact command"));
            }

            var url = string.Format($"https://api.hubapi.com/contacts/v1/contact/?hapikey={activeHapiKey}");

            //var dbg = JsonConvert.SerializeObject(newContactProperties);

            // Need to POST to Hubspot to create a contact
            log.LogInformation($"Posting to HubSpot to create {firstname} {lastname}");
            HttpResponseMessage response = await httpClient.PostAsJsonAsync(url, newContactProperties);

            HttpContent content = response.Content;

            // Check Status Code.
            if (response.StatusCode == HttpStatusCode.OK)
            {
                log.LogInformation("Hubspot creation OK");
                // All good. Read the string out of the body
                string resultText = await content.ReadAsStringAsync();

                var newContactResponse = ConvertHubspotJsonToCanonicalContact(resultText, fetchPreviousValues: false, log: log);

                log.LogInformation("New Contact identifier is {0}", newContactResponse.contactId);

                var retval = new HubSpotContactResult(newContactResponse);
                return(retval);
            }
            else if (response.StatusCode == HttpStatusCode.Conflict)
            {
                // The contact already exists. That's OK - we need to direct this contact to a human for review.
                log.LogWarning($"Contact already exists: {email}");

                // Let's read the whole contact back, then.
                var actualContact = await RetrieveHubspotContactByEmailAddr(email, false, log, isTest);

                var retval = new HubSpotContactResult(actualContact.Payload);
                retval.StatusCode = response.StatusCode;
                return(retval);
            }
            else
            {
                // Some other error - return the status code and body to the caller of the function
                string resultText = await content.ReadAsStringAsync();

                log.LogError("Hubspot creation failed: {0}: {1}", response.StatusCode, resultText);
                return(new HubSpotContactResult(response.StatusCode, resultText));
            }
        }
Пример #4
0
        /// <summary>
        /// Updates a HubSpot contact fields with the given contract status
        /// </summary>
        /// <param name="email"></param>
        /// <param name="status"></param>
        /// <param name="log"></param>
        /// <param name="isTest"></param>
        /// <returns></returns>
        /// <remarks>Make 'status' an enum that reflects the Sharepoint 'ContractStatus' field</remarks>
        public async Task <HubSpotContactResult> UpdateContractStatusAsync(
            string email,
            string status,
            ILogger log,
            bool isTest)
        {
            // Check that the appropriate Hubspot API key was correctly retrieved in the static constructor
            var activeHapiKey = isTest ? sandbox_hapikey : hapikey;

            if (string.IsNullOrEmpty(activeHapiKey))
            {
                return(new HubSpotContactResult(HttpStatusCode.InternalServerError, "Hubspot API key not found"));
            }

            // To update a Contact Property we need a HubSpotContactProperties object that specifies all the properties
            var props = new HubSpotContactProperties();

            var internalLeadStatusValue = string.Empty;

            // For now, we update a few fields:
            // 'Lead Status' - used by Brian for reporting. Not sustainable, will fall over when the a contact has two installations
            //                 I would like to retire these two states from Lead Status and re-do the reports.
            //
            // 'TotalSentContracts'
            // 'TotalSignedContracts' - these will support aggregates. But aggregates are expense to obtain from Sharepoint. When we
            //                          move the Installations table to SQL Server, we will revisit this logic and compute aggregates.
            //
            // So there is a temporary hack here right now. We're not computing proper totals.

            switch (status.ToLower())
            {
            case "sent":
                props.Add("totalsentcontracts", "1");
                internalLeadStatusValue = "CONTRACT_SENT";
                break;

            case "signed":
                props.Add("totalsignedcontracts", "1");
                internalLeadStatusValue = "CONTRACT_SIGNED";
                break;

            case "rejected":
                props.Add("totalsignedcontracts", "0");
                internalLeadStatusValue = "NOT_INTERESTED";
                break;

            default:
                throw new CrmUpdateHandlerException("Unrecognised contract status: '" + status + "'");
            }
            props.Add("hs_lead_status", internalLeadStatusValue);

            // We need to resolve the email into a contact id (a 'vid', in HubSpot language)
            var hubSpotContactResult = await this.RetrieveHubspotContactByEmailAddr(email, false, log, isTest);

            if (hubSpotContactResult.StatusCode != HttpStatusCode.OK)
            {
                log.LogInformation($"Error {hubSpotContactResult.StatusCode} retrieving HubSpot details for '{email}': {hubSpotContactResult.ErrorMessage}");
                return(hubSpotContactResult);
            }

            // Great, we managed to retrieve the contact via the email address.
            var vid = hubSpotContactResult.Payload.contactId;

            // Now just POST it - see https://developers.hubspot.com/docs/methods/contacts/update_contact
            // Returns a 204 No Content on success
            var url = string.Format($"https://api.hubapi.com/contacts/v1/contact/vid/{vid}/profile?hapikey={activeHapiKey}");

            log.LogInformation($"Updating {vid} contract status to {status}");
            HttpResponseMessage response = await httpClient.PostAsJsonAsync(url, props);

            // Check Status Code.
            if (response.StatusCode == HttpStatusCode.NoContent)
            {
                log.LogInformation("Hubspot status update OK");
                var retval = new HubSpotContactResult(HttpStatusCode.OK);
                return(retval);
            }
            else
            {
                // Some kind of error - return the status code and body to the caller of the function
                string resultText = await response.Content.ReadAsStringAsync();

                log.LogError("Hubspot update failed: {0}: {1}", response.StatusCode, resultText);
                return(new HubSpotContactResult(response.StatusCode, string.Format($"Error {response.StatusCode}: '{resultText}'")));
            }
        }