Skip to content

Commit

Permalink
Gainsight NXT new components (#14453)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
GTFalcao authored Nov 6, 2024
1 parent e707543 commit 2989ea2
Show file tree
Hide file tree
Showing 7 changed files with 436 additions and 58 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import { parseObjectEntries } from "../../common/utils.mjs";
import app from "../../gainsight_nxt.app.mjs";

export default {
key: "gainsight_nxt-create-or-update-company",
name: "Create or Update Company",
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)",
version: "0.0.1",
type: "action",
props: {
app,
name: {
type: "string",
label: "Name",
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.",
},
industry: {
type: "string",
label: "Industry",
description: "The industry name of the company.",
optional: true,
},
arr: {
type: "string",
label: "Annual Recurring Revenue (ARR)",
description: "The annual recurring revenue of the company, as a currency value.",
optional: true,
},
employees: {
type: "integer",
label: "Employees",
description: "The number of employees the company has.",
optional: true,
},
lifecycleInWeeks: {
type: "integer",
label: "Life Cycle in Weeks",
description: "The number of weeks the entire process goes through.",
optional: true,
},
originalContractDate: {
type: "string",
label: "Original Contract Date",
description: "The date the engagement with the client started, in `YYYY-MM-DD` format.",
optional: true,
},
renewalDate: {
type: "string",
label: "Renewal Date",
description: "The upcoming renewal date of the contract, in `YYYY-MM-DD` format.",
optional: true,
},
stage: {
type: "string",
label: "Stage",
description: "The current stage of the company in the sales pipeline.",
optional: true,
options: [
"New Customer",
"Kicked Off",
"Launched",
"Adopting",
"Will Churn",
"Churn",
],
},
status: {
type: "string",
label: "Status",
description: "The current status of the company.",
optional: true,
options: [
"Active",
"Inactive",
"Churn",
],
},
additionalOptions: {
type: "object",
label: "Additional Options",
description:
"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.",
optional: true,
},
},
async run({ $ }) {
const data = {
records: [
{
Name: this.name,
Industry: this.industry,
ARR: this.arr,
Employees: this.employees,
LifecycleInWeeks: this.lifecycleInWeeks,
OriginalContractDate: this.originalContractDate,
RenewalDate: this.renewalDate,
Stage: this.stage,
Status: this.status,
...(this.additionalOptions && parseObjectEntries(this.additionalOptions)),
},
],
};

let summary = "";
let result;
try {
const updateReq = await this.app.updateCompany({
$,
data,
});
result = updateReq;
summary = updateReq.result === true
? `Successfully updated company '${this.name}'`
: `Error updating company '${this.name}'`;
}
catch (err) {
const createReq = await this.app.createCompany({
$,
data,
});
result = createReq;
summary = createReq.result === true
? `Successfully created company '${this.name}'`
: `Error creating company '${this.name}'`;
}

$.export(
"$summary",
summary,
);
return result;
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import app from "../../gainsight_nxt.app.mjs";

export default {
key: "gainsight_nxt-create-or-update-custom-object",
name: "Create or Update Custom Object",
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)",
version: "0.0.1",
type: "action",
props: {
app,
objectName: {
propDefinition: [
app,
"objectName",
],
},
infoBox: {
type: "alert",
alertType: "info",
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.",
},
fields: {
type: "string[]",
label: "Key Field(s)",
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.",
},
fieldValues: {
type: "object",
label: "Field Values",
description: "The record data to create or update, as key-value pairs.",
},
},
async run({ $ }) {
const { objectName } = this;
const data = {
records: [
this.fieldValues,
],
};

let summary = "";
let result;
try {
result = await this.app.updateCustomObject({
$,
objectName,
data,
params: {
keys: this.fields.join?.() ?? this.fields,
},
});
summary = result.result === true
? `Successfully updated custom object ${objectName}`
: `Error updating custom object ${objectName}`;
}
catch (err) {
result = await this.app.createCustomObject({
$,
objectName,
data,
});
summary = result.result === true
? `Successfully created custom object ${objectName}`
: `Error creating custom object ${objectName}`;
}

$.export(
"$summary",
summary,
);
return result;
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import app from "../../gainsight_nxt.app.mjs";

export default {
key: "gainsight_nxt-create-or-update-person",
name: "Create or Update Person",
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)",
version: "0.0.1",
type: "action",
props: {
app,
email: {
type: "string",
label: "Email",
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.",
},
firstName: {
type: "string",
label: "First Name",
description: "The first name of the person.",
optional: true,
},
lastName: {
type: "string",
label: "Last Name",
description: "The last name of the person.",
optional: true,
},
linkedinUrl: {
type: "string",
label: "LinkedIn URL",
description: "The LinkedIn URL of the person.",
optional: true,
},
location: {
type: "string",
label: "Location",
description: "The location of the person.",
optional: true,
},
additionalFields: {
type: "object",
label: "Additional Fields",
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.",
optional: true,
},
},
async run({ $ }) {
const response = await this.app.createOrUpdatePerson({
$,
data: {
Email: this.email,
FirstName: this.firstName,
LastName: this.lastName,
LinkedinUrl: this.linkedinUrl,
Location: this.location,
...this.additionalFields,
},
});

$.export("$summary", `Successfully upserted person with email ${this.email}`);
return response;
},
};
22 changes: 22 additions & 0 deletions components/gainsight_nxt/common/utils.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
function optionalParseAsJSON(value) {
try {
return JSON.parse(value);
} catch (e) {
return value;
}
}

export function parseObjectEntries(value) {
const obj = typeof value === "string"
? JSON.parse(value)
: value;
return Object.fromEntries(
Object.entries(obj).map(([
key,
value,
]) => [
key,
optionalParseAsJSON(value),
]),
);
}
89 changes: 85 additions & 4 deletions components/gainsight_nxt/gainsight_nxt.app.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,92 @@
import { axios } from "@pipedream/platform";

export default {
type: "app",
app: "gainsight_nxt",
propDefinitions: {},
propDefinitions: {
objectName: {
type: "string",
label: "Custom Object",
description: "The name of the custom object.",
async options() {
const { data } = await this.listCustomObjects();
return data?.filter?.((obj) => obj.objectType === "CUSTOM").map(( {
label, objectName,
}) => ({
label,
value: objectName,
}));
},
},
},
methods: {
// this.$auth contains connected account data
authKeys() {
console.log(Object.keys(this.$auth));
_baseUrl() {
return `${this.$auth.customer_domain}/v1`;
},
async _makeRequest({
$ = this,
path,
headers = {},
...otherOpts
} = {}) {
return axios($, {
...otherOpts,
url: this._baseUrl() + path,
headers: {
"content-type": "application/json",
"accept": "application/json, text/plain, */*",
"accept-language": "en-GB,en-US;q=0.9,en;q=0.8",
"accesskey": `${this.$auth.access_key}`,
...headers,
},
});
},
async updateCompany(args) {
return this._makeRequest({
path: "/data/objects/Company",
method: "PUT",
params: {
keys: "Name",
},
...args,
});
},
async createCompany(args) {
return this._makeRequest({
path: "/data/objects/Company",
method: "POST",
...args,
});
},
async createOrUpdatePerson(args) {
return this._makeRequest({
path: "/peoplemgmt/v1.0/people",
method: "PUT",
...args,
});
},
async listCustomObjects() {
return this._makeRequest({
path: "/meta/services/objects/list",
});
},
async updateCustomObject({
objectName, ...args
}) {
return this._makeRequest({
path: `/data/objects/${objectName}`,
method: "PUT",
...args,
});
},
async createCustomObject({
objectName, ...args
}) {
return this._makeRequest({
path: `/data/objects/${objectName}`,
method: "POST",
...args,
});
},
},
};
Loading

0 comments on commit 2989ea2

Please sign in to comment.