Skip to content

Commit d956d5c

Browse files
GTFalcaolcaresia
authored andcommitted
Gainsight NXT new components (#14453)
* Initial AI-generated code (w/ eslint fixes) * App/package adjustments * pnpm * Create/Update company adjustments * Create/Update adjustments * Create/update person adjustments * Create/Update Custom Object + improvements * Version numbers * Fixes * Removing CSM props and adding "additional options" * Readding 'custom' object filter * Adding info box
1 parent aa96997 commit d956d5c

File tree

7 files changed

+436
-58
lines changed

7 files changed

+436
-58
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import { parseObjectEntries } from "../../common/utils.mjs";
2+
import app from "../../gainsight_nxt.app.mjs";
3+
4+
export default {
5+
key: "gainsight_nxt-create-or-update-company",
6+
name: "Create or Update Company",
7+
description: "Create or update a company record. [See the documentation](https://support.gainsight.com/gainsight_nxt/API_and_Developer_Docs/Company_and_Relationship_API/Company_API_Documentation#Parameters)",
8+
version: "0.0.1",
9+
type: "action",
10+
props: {
11+
app,
12+
name: {
13+
type: "string",
14+
label: "Name",
15+
description: "The name of the company. If a company record with this name exists, it will be updated, otherwise a new one will be created.",
16+
},
17+
industry: {
18+
type: "string",
19+
label: "Industry",
20+
description: "The industry name of the company.",
21+
optional: true,
22+
},
23+
arr: {
24+
type: "string",
25+
label: "Annual Recurring Revenue (ARR)",
26+
description: "The annual recurring revenue of the company, as a currency value.",
27+
optional: true,
28+
},
29+
employees: {
30+
type: "integer",
31+
label: "Employees",
32+
description: "The number of employees the company has.",
33+
optional: true,
34+
},
35+
lifecycleInWeeks: {
36+
type: "integer",
37+
label: "Life Cycle in Weeks",
38+
description: "The number of weeks the entire process goes through.",
39+
optional: true,
40+
},
41+
originalContractDate: {
42+
type: "string",
43+
label: "Original Contract Date",
44+
description: "The date the engagement with the client started, in `YYYY-MM-DD` format.",
45+
optional: true,
46+
},
47+
renewalDate: {
48+
type: "string",
49+
label: "Renewal Date",
50+
description: "The upcoming renewal date of the contract, in `YYYY-MM-DD` format.",
51+
optional: true,
52+
},
53+
stage: {
54+
type: "string",
55+
label: "Stage",
56+
description: "The current stage of the company in the sales pipeline.",
57+
optional: true,
58+
options: [
59+
"New Customer",
60+
"Kicked Off",
61+
"Launched",
62+
"Adopting",
63+
"Will Churn",
64+
"Churn",
65+
],
66+
},
67+
status: {
68+
type: "string",
69+
label: "Status",
70+
description: "The current status of the company.",
71+
optional: true,
72+
options: [
73+
"Active",
74+
"Inactive",
75+
"Churn",
76+
],
77+
},
78+
additionalOptions: {
79+
type: "object",
80+
label: "Additional Options",
81+
description:
82+
"Additional parameters to send in the request. [See the documentation](https://support.gainsight.com/gainsight_nxt/API_and_Developer_Docs/Company_and_Relationship_API/Company_API_Documentation#Parameters) for available parameters. Values will be parsed as JSON where applicable.",
83+
optional: true,
84+
},
85+
},
86+
async run({ $ }) {
87+
const data = {
88+
records: [
89+
{
90+
Name: this.name,
91+
Industry: this.industry,
92+
ARR: this.arr,
93+
Employees: this.employees,
94+
LifecycleInWeeks: this.lifecycleInWeeks,
95+
OriginalContractDate: this.originalContractDate,
96+
RenewalDate: this.renewalDate,
97+
Stage: this.stage,
98+
Status: this.status,
99+
...(this.additionalOptions && parseObjectEntries(this.additionalOptions)),
100+
},
101+
],
102+
};
103+
104+
let summary = "";
105+
let result;
106+
try {
107+
const updateReq = await this.app.updateCompany({
108+
$,
109+
data,
110+
});
111+
result = updateReq;
112+
summary = updateReq.result === true
113+
? `Successfully updated company '${this.name}'`
114+
: `Error updating company '${this.name}'`;
115+
}
116+
catch (err) {
117+
const createReq = await this.app.createCompany({
118+
$,
119+
data,
120+
});
121+
result = createReq;
122+
summary = createReq.result === true
123+
? `Successfully created company '${this.name}'`
124+
: `Error creating company '${this.name}'`;
125+
}
126+
127+
$.export(
128+
"$summary",
129+
summary,
130+
);
131+
return result;
132+
},
133+
};
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import app from "../../gainsight_nxt.app.mjs";
2+
3+
export default {
4+
key: "gainsight_nxt-create-or-update-custom-object",
5+
name: "Create or Update Custom Object",
6+
description: "Create or update a custom object record. [See the documentation](https://support.gainsight.com/gainsight_nxt/API_and_Developer_Docs/Custom_Object_API/Gainsight_Custom_Object_API_Documentation#Insert_API)",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
app,
11+
objectName: {
12+
propDefinition: [
13+
app,
14+
"objectName",
15+
],
16+
},
17+
infoBox: {
18+
type: "alert",
19+
alertType: "info",
20+
content: "Custom object fields may be suffixed with `__gc`, e.g. if you've named your field \"Object Name\", its key would be `Object_Name__gc`. Check the object configuration in the Gainsight platform for the correct field names.",
21+
},
22+
fields: {
23+
type: "string[]",
24+
label: "Key Field(s)",
25+
description: "The field(s) which identify this object (max 3), e.g. `fieldName1`. If a record with the same key field(s) exists, it will be updated, otherwise a new one will be created.",
26+
},
27+
fieldValues: {
28+
type: "object",
29+
label: "Field Values",
30+
description: "The record data to create or update, as key-value pairs.",
31+
},
32+
},
33+
async run({ $ }) {
34+
const { objectName } = this;
35+
const data = {
36+
records: [
37+
this.fieldValues,
38+
],
39+
};
40+
41+
let summary = "";
42+
let result;
43+
try {
44+
result = await this.app.updateCustomObject({
45+
$,
46+
objectName,
47+
data,
48+
params: {
49+
keys: this.fields.join?.() ?? this.fields,
50+
},
51+
});
52+
summary = result.result === true
53+
? `Successfully updated custom object ${objectName}`
54+
: `Error updating custom object ${objectName}`;
55+
}
56+
catch (err) {
57+
result = await this.app.createCustomObject({
58+
$,
59+
objectName,
60+
data,
61+
});
62+
summary = result.result === true
63+
? `Successfully created custom object ${objectName}`
64+
: `Error creating custom object ${objectName}`;
65+
}
66+
67+
$.export(
68+
"$summary",
69+
summary,
70+
);
71+
return result;
72+
},
73+
};
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import app from "../../gainsight_nxt.app.mjs";
2+
3+
export default {
4+
key: "gainsight_nxt-create-or-update-person",
5+
name: "Create or Update Person",
6+
description: "Create or update a person's record. [See the documentation](https://support.gainsight.com/gainsight_nxt/API_and_Developer_Docs/Person_API/People_API_Documentation#Person)",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
app,
11+
email: {
12+
type: "string",
13+
label: "Email",
14+
description: "The email address of the person. If a record with this email exists, it will be updated, otherwise a new one will be created.",
15+
},
16+
firstName: {
17+
type: "string",
18+
label: "First Name",
19+
description: "The first name of the person.",
20+
optional: true,
21+
},
22+
lastName: {
23+
type: "string",
24+
label: "Last Name",
25+
description: "The last name of the person.",
26+
optional: true,
27+
},
28+
linkedinUrl: {
29+
type: "string",
30+
label: "LinkedIn URL",
31+
description: "The LinkedIn URL of the person.",
32+
optional: true,
33+
},
34+
location: {
35+
type: "string",
36+
label: "Location",
37+
description: "The location of the person.",
38+
optional: true,
39+
},
40+
additionalFields: {
41+
type: "object",
42+
label: "Additional Fields",
43+
description: "Additional fields to include in the request body. [See the documentation](https://support.gainsight.com/gainsight_nxt/API_and_Developer_Docs/Person_API/People_API_Documentation#Person) for all available fields.",
44+
optional: true,
45+
},
46+
},
47+
async run({ $ }) {
48+
const response = await this.app.createOrUpdatePerson({
49+
$,
50+
data: {
51+
Email: this.email,
52+
FirstName: this.firstName,
53+
LastName: this.lastName,
54+
LinkedinUrl: this.linkedinUrl,
55+
Location: this.location,
56+
...this.additionalFields,
57+
},
58+
});
59+
60+
$.export("$summary", `Successfully upserted person with email ${this.email}`);
61+
return response;
62+
},
63+
};
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
function optionalParseAsJSON(value) {
2+
try {
3+
return JSON.parse(value);
4+
} catch (e) {
5+
return value;
6+
}
7+
}
8+
9+
export function parseObjectEntries(value) {
10+
const obj = typeof value === "string"
11+
? JSON.parse(value)
12+
: value;
13+
return Object.fromEntries(
14+
Object.entries(obj).map(([
15+
key,
16+
value,
17+
]) => [
18+
key,
19+
optionalParseAsJSON(value),
20+
]),
21+
);
22+
}
Lines changed: 85 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,92 @@
1+
import { axios } from "@pipedream/platform";
2+
13
export default {
24
type: "app",
35
app: "gainsight_nxt",
4-
propDefinitions: {},
6+
propDefinitions: {
7+
objectName: {
8+
type: "string",
9+
label: "Custom Object",
10+
description: "The name of the custom object.",
11+
async options() {
12+
const { data } = await this.listCustomObjects();
13+
return data?.filter?.((obj) => obj.objectType === "CUSTOM").map(( {
14+
label, objectName,
15+
}) => ({
16+
label,
17+
value: objectName,
18+
}));
19+
},
20+
},
21+
},
522
methods: {
6-
// this.$auth contains connected account data
7-
authKeys() {
8-
console.log(Object.keys(this.$auth));
23+
_baseUrl() {
24+
return `${this.$auth.customer_domain}/v1`;
25+
},
26+
async _makeRequest({
27+
$ = this,
28+
path,
29+
headers = {},
30+
...otherOpts
31+
} = {}) {
32+
return axios($, {
33+
...otherOpts,
34+
url: this._baseUrl() + path,
35+
headers: {
36+
"content-type": "application/json",
37+
"accept": "application/json, text/plain, */*",
38+
"accept-language": "en-GB,en-US;q=0.9,en;q=0.8",
39+
"accesskey": `${this.$auth.access_key}`,
40+
...headers,
41+
},
42+
});
43+
},
44+
async updateCompany(args) {
45+
return this._makeRequest({
46+
path: "/data/objects/Company",
47+
method: "PUT",
48+
params: {
49+
keys: "Name",
50+
},
51+
...args,
52+
});
53+
},
54+
async createCompany(args) {
55+
return this._makeRequest({
56+
path: "/data/objects/Company",
57+
method: "POST",
58+
...args,
59+
});
60+
},
61+
async createOrUpdatePerson(args) {
62+
return this._makeRequest({
63+
path: "/peoplemgmt/v1.0/people",
64+
method: "PUT",
65+
...args,
66+
});
67+
},
68+
async listCustomObjects() {
69+
return this._makeRequest({
70+
path: "/meta/services/objects/list",
71+
});
72+
},
73+
async updateCustomObject({
74+
objectName, ...args
75+
}) {
76+
return this._makeRequest({
77+
path: `/data/objects/${objectName}`,
78+
method: "PUT",
79+
...args,
80+
});
81+
},
82+
async createCustomObject({
83+
objectName, ...args
84+
}) {
85+
return this._makeRequest({
86+
path: `/data/objects/${objectName}`,
87+
method: "POST",
88+
...args,
89+
});
990
},
1091
},
1192
};

0 commit comments

Comments
 (0)