@xapp/stentor-service-hubspot 1.80.3 → 1.82.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,13 @@
1
- /*! Copyright (c) 2022, XAPPmedia */
2
1
  import { FetchService } from "stentor-service-fetch";
3
2
  import { BaseService, CrmResponse, CrmService, CrmServiceAvailability, CrmServiceAvailabilityOptions, CrmServiceJobType, DateTimeRange, ExternalLead } from "stentor-models";
4
- import { Client } from "@hubspot/api-client";
5
3
  export interface HubspotServiceProps extends BaseService {
6
4
  appId: string;
5
+ /**
6
+ * Hubspot private app access token. If omitted, falls back to
7
+ * `process.env.HUBSPOT_TOKEN`. The stateless `buildHubspotContactRequest`
8
+ * helper requires this to be set explicitly.
9
+ */
10
+ accessToken?: string;
7
11
  }
8
12
  export interface HubspotExternalLeadExtras {
9
13
  /**
@@ -57,11 +61,46 @@ export interface HubspotResponse {
57
61
  */
58
62
  Reason?: string;
59
63
  }
64
+ /**
65
+ * The contact body accepted by Hubspot's REST endpoint (`POST /crm/v3/objects/contacts`).
66
+ */
67
+ export interface HubspotContactPayload {
68
+ properties: {
69
+ firstname?: string;
70
+ lastname?: string;
71
+ email?: string;
72
+ phone?: string;
73
+ message?: string;
74
+ };
75
+ }
76
+ /**
77
+ * Describes the HTTP request that should be POSTed to Hubspot's contact
78
+ * REST endpoint. Both `HubspotService.send()` and stateless callers
79
+ * (e.g. stentor-api's chain runner) use this descriptor.
80
+ *
81
+ * SECURITY: `headers.Authorization` carries the Bearer access token.
82
+ * Callers that audit-log this descriptor must redact the `Authorization`
83
+ * header before persisting.
84
+ */
85
+ export interface HubspotRequestDescriptor {
86
+ url: string;
87
+ method: "POST";
88
+ headers: Record<string, string>;
89
+ body: HubspotContactPayload;
90
+ }
60
91
  export declare class HubspotService extends FetchService implements CrmService {
61
- hubspotClient: Client;
62
92
  private props;
63
93
  constructor(props: HubspotServiceProps);
64
94
  getAvailability(range: DateTimeRange, options?: CrmServiceAvailabilityOptions): Promise<CrmServiceAvailability>;
65
95
  getJobType(message: string, externalLead?: ExternalLead): Promise<CrmServiceJobType>;
66
96
  send(externalLead: ExternalLead, extras?: HubspotExternalLeadExtras): Promise<CrmResponse>;
67
97
  }
98
+ /**
99
+ * Builds the Hubspot contact request descriptor without performing any I/O.
100
+ */
101
+ export declare function buildHubspotContactRequest(props: HubspotServiceProps, externalLead: ExternalLead, extras?: HubspotExternalLeadExtras): HubspotRequestDescriptor;
102
+ /**
103
+ * Parses a Hubspot contact response (from SDK or REST) into a `CrmResponse`.
104
+ * Both transports return the same shape with an `id` field on success.
105
+ */
106
+ export declare function parseHubspotContactResponse(body: unknown): CrmResponse;
@@ -8,19 +8,23 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
11
14
  Object.defineProperty(exports, "__esModule", { value: true });
12
15
  exports.HubspotService = void 0;
16
+ exports.buildHubspotContactRequest = buildHubspotContactRequest;
17
+ exports.parseHubspotContactResponse = parseHubspotContactResponse;
13
18
  /*! Copyright (c) 2022, XAPPmedia */
19
+ const axios_1 = __importDefault(require("axios"));
14
20
  const stentor_service_fetch_1 = require("stentor-service-fetch");
15
21
  const stentor_logger_1 = require("stentor-logger");
16
22
  const util_1 = require("./util");
17
- // Hubspot API Client
18
- const api_client_1 = require("@hubspot/api-client");
23
+ const HUBSPOT_CONTACTS_ENDPOINT = "https://api.hubapi.com/crm/v3/objects/contacts";
19
24
  class HubspotService extends stentor_service_fetch_1.FetchService {
20
25
  constructor(props) {
21
26
  super(props);
22
- this.hubspotClient = new api_client_1.Client({ accessToken: process.env.HUBSPOT_TOKEN });
23
- this.props = Object.assign({}, props);
27
+ this.props = Object.assign(Object.assign({}, props), { accessToken: props.accessToken || process.env.HUBSPOT_TOKEN });
24
28
  (0, stentor_logger_1.log)().info(`app id: ${this.props.appId}`);
25
29
  }
26
30
  getAvailability(range, options) {
@@ -41,39 +45,77 @@ class HubspotService extends stentor_service_fetch_1.FetchService {
41
45
  }
42
46
  send(externalLead, extras) {
43
47
  return __awaiter(this, void 0, void 0, function* () {
44
- const transcript = (0, util_1.transformTranscript)(externalLead.transcript, extras === null || extras === void 0 ? void 0 : extras.botId);
45
- let messages = "";
46
- transcript.forEach((message) => {
47
- messages += "input: " + message["question"] + "\n" + "response: " + message["answer"] + "\n";
48
- });
49
- const crmResponse = {
50
- status: "Failure",
51
- message: "",
52
- };
53
48
  try {
54
- const lead = {
55
- properties: {
56
- firstname: externalLead.fields.find((x) => x.name == "FIRST_NAME").value,
57
- lastname: externalLead.fields.find((x) => x.name == "LAST_NAME").value,
58
- email: externalLead.fields.find((x) => x.name == "EMAIL").value,
59
- phone: externalLead.fields.find((x) => x.name == "PHONE").value,
60
- message: messages,
61
- },
62
- };
63
- const createContactResponse = yield this.hubspotClient.crm.contacts.basicApi.create(lead);
64
- if (createContactResponse.id) {
65
- crmResponse.status = "Success";
66
- crmResponse.message = `contact id: ${createContactResponse.id}`;
67
- (0, stentor_logger_1.log)().info(`Contact sent to Hubspot: ${createContactResponse.id}`);
68
- return crmResponse;
49
+ const descriptor = buildHubspotContactRequest(this.props, externalLead, extras);
50
+ const axiosResponse = yield axios_1.default.post(descriptor.url, descriptor.body, {
51
+ headers: descriptor.headers
52
+ });
53
+ const parsed = parseHubspotContactResponse(axiosResponse.data);
54
+ if (parsed.status === "Success") {
55
+ (0, stentor_logger_1.log)().info(`Contact sent to Hubspot: ${parsed.refId}`);
69
56
  }
57
+ return parsed;
70
58
  }
71
59
  catch (e) {
72
- (0, stentor_logger_1.log)().error(`Error sending lead to Hubspot ${e}`);
60
+ const responseDetail = axios_1.default.isAxiosError(e) && e.response
61
+ ? ` (status ${e.response.status}; body ${JSON.stringify(e.response.data)})`
62
+ : "";
63
+ (0, stentor_logger_1.log)().error(`Error sending lead to Hubspot ${e}${responseDetail}`);
64
+ return {
65
+ status: "Failure",
66
+ message: e instanceof Error ? e.message : String(e)
67
+ };
73
68
  }
74
- return crmResponse;
75
69
  });
76
70
  }
77
71
  }
78
72
  exports.HubspotService = HubspotService;
73
+ /**
74
+ * Builds the Hubspot contact request descriptor without performing any I/O.
75
+ */
76
+ function buildHubspotContactRequest(props, externalLead, extras) {
77
+ var _a, _b, _c, _d;
78
+ if (!props.accessToken) {
79
+ throw new Error("Hubspot: access token is not set");
80
+ }
81
+ const transcript = (0, util_1.transformTranscript)(externalLead.transcript, extras === null || extras === void 0 ? void 0 : extras.botId);
82
+ let messages = "";
83
+ transcript.forEach((message) => {
84
+ messages += "input: " + message.question + "\n" + "response: " + message.answer + "\n";
85
+ });
86
+ const properties = {
87
+ firstname: (_a = externalLead.fields.find((x) => x.name === "FIRST_NAME")) === null || _a === void 0 ? void 0 : _a.value,
88
+ lastname: (_b = externalLead.fields.find((x) => x.name === "LAST_NAME")) === null || _b === void 0 ? void 0 : _b.value,
89
+ email: (_c = externalLead.fields.find((x) => x.name === "EMAIL")) === null || _c === void 0 ? void 0 : _c.value,
90
+ phone: (_d = externalLead.fields.find((x) => x.name === "PHONE")) === null || _d === void 0 ? void 0 : _d.value,
91
+ message: messages
92
+ };
93
+ return {
94
+ url: HUBSPOT_CONTACTS_ENDPOINT,
95
+ method: "POST",
96
+ headers: {
97
+ "Authorization": `Bearer ${props.accessToken}`,
98
+ "Content-Type": "application/json"
99
+ },
100
+ body: { properties }
101
+ };
102
+ }
103
+ /**
104
+ * Parses a Hubspot contact response (from SDK or REST) into a `CrmResponse`.
105
+ * Both transports return the same shape with an `id` field on success.
106
+ */
107
+ function parseHubspotContactResponse(body) {
108
+ const response = body;
109
+ if (response === null || response === void 0 ? void 0 : response.id) {
110
+ return {
111
+ status: "Success",
112
+ message: `contact id: ${response.id}`,
113
+ refId: response.id
114
+ };
115
+ }
116
+ return {
117
+ status: "Failure",
118
+ message: "Hubspot did not return a contact id"
119
+ };
120
+ }
79
121
  //# sourceMappingURL=HubspotService.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"HubspotService.js","sourceRoot":"","sources":["../src/HubspotService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"HubspotService.js","sourceRoot":"","sources":["../src/HubspotService.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "1.80.3",
7
+ "version": "1.82.0",
8
8
  "description": "Service to interface the Hubspot CRM service",
9
9
  "types": "lib/index",
10
10
  "main": "lib/index",
@@ -27,7 +27,7 @@
27
27
  "typescript": "5.9.3"
28
28
  },
29
29
  "dependencies": {
30
- "@hubspot/api-client": "13.5.0"
30
+ "axios": "1.16.1"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "stentor-logger": "1.x",
@@ -39,5 +39,5 @@
39
39
  "clean": "rm -rf ./lib/*",
40
40
  "test": "mocha --recursive -r ts-node/register \"./src/**/*.test.ts\""
41
41
  },
42
- "gitHead": "06fa3fc79deca527eab7f75696fae30afa5e1587"
42
+ "gitHead": "d4ad419e6b72c016edeb41c56210b2a70c1e94a9"
43
43
  }