diff --git a/components/microsoft_dynamics_365_sales/actions/create-custom-entity/create-custom-entity.mjs b/components/microsoft_dynamics_365_sales/actions/create-custom-entity/create-custom-entity.mjs new file mode 100644 index 0000000000000..9763a7c75b58e --- /dev/null +++ b/components/microsoft_dynamics_365_sales/actions/create-custom-entity/create-custom-entity.mjs @@ -0,0 +1,157 @@ +import microsoft from "../../microsoft_dynamics_365_sales.app.mjs"; +import languageCodes from "../../common/language-codes.mjs"; +import pluralize from "pluralize"; + +export default { + key: "microsoft_dynamics_365_sales-create-custom-entity", + name: "Create Custom Entity", + description: "Create a custom entity. [See the documentation](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/webapi/create-update-entity-definitions-using-web-api)", + version: "0.0.1", + type: "action", + props: { + microsoft, + solutionId: { + propDefinition: [ + microsoft, + "solutionId", + ], + }, + displayName: { + type: "string", + label: "Display Name", + description: "The name of the new entity. E.g. `Bank Account`", + }, + primaryAttribute: { + type: "string", + label: "Primary Attribute", + description: "The primary name attribute of the new entity. E.g. `Account Name`", + }, + languageCode: { + type: "integer", + label: "Language Code", + description: "The language code to use for the entity", + options: languageCodes, + default: 1033, + optional: true, + }, + additionalAttributes: { + type: "object", + label: "Additional Attributes", + description: "An array of objects representing attributes to add to the custom entity. [See the documentation](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/webapi/create-update-entity-definitions-using-web-api) for more information about formatting attribute objects", + optional: true, + }, + description: { + type: "string", + label: "Description", + description: "A description of the new entity", + optional: true, + }, + hasActivities: { + type: "boolean", + label: "Has Activities", + description: "Set to `true` if the new entity has activities", + default: false, + optional: true, + }, + hasNotes: { + type: "boolean", + label: "Has Notes", + description: "Set to `true` if the new entity has notes", + default: false, + optional: true, + }, + }, + methods: { + parseAttributes() { + return this.additionalAttributes + ? typeof this.additionalAttributes === "string" + ? JSON.parse(this.additionalAttributes) + : this.additionalAttributes + : []; + }, + removeSpaces(str) { + return str.replace(/\s+/g, ""); + }, + buildLocalizedLabelArray(label) { + return [ + { + "@odata.type": "Microsoft.Dynamics.CRM.LocalizedLabel", + "Label": label, + "LanguageCode": this.languageCode, + }, + ]; + }, + }, + async run({ $ }) { + const solution = await this.microsoft.getSolution({ + $, + solutionId: this.solutionId, + }); + + const { customizationprefix } = await this.microsoft.getPublisher({ + $, + publisherId: solution._publisherid_value, + }); + + const attributes = this.parseAttributes(); + + const { headers } = await this.microsoft.createCustomEntity({ + $, + returnFullResponse: true, + headers: { + "MSCRM.SolutionUniqueName": solution.uniquename, + }, + data: { + "@odata.type": "Microsoft.Dynamics.CRM.EntityMetadata", + "Attributes": [ + { + "@odata.type": "Microsoft.Dynamics.CRM.StringAttributeMetadata", + "DisplayName": { + "@odata.type": "Microsoft.Dynamics.CRM.Label", + "LocalizedLabels": this.buildLocalizedLabelArray(this.primaryAttribute), + }, + "IsPrimaryName": true, + "SchemaName": `${customizationprefix}_${this.removeSpaces(this.primaryAttribute)}`, + "MaxLength": 100, + "FormatName": { + "Value": "Text", + }, + "RequiredLevel": { + "Value": "None", + "CanBeChanged": true, + "ManagedPropertyLogicalName": "canmodifyrequirementlevelsettings", + }, + }, + ...attributes, + ], + "DisplayName": { + "@odata.type": "Microsoft.Dynamics.CRM.Label", + "LocalizedLabels": this.buildLocalizedLabelArray(this.displayName), + }, + "DisplayCollectionName": { + "@odata.type": "Microsoft.Dynamics.CRM.Label", + "LocalizedLabels": this.buildLocalizedLabelArray(pluralize(this.displayName)), + }, + "Description": this.description && { + "@odata.type": "Microsoft.Dynamics.CRM.Label", + "LocalizedLabels": this.buildLocalizedLabelArray(this.description), + }, + "HasActivities": this.hasActivities, + "HasNotes": this.hasNotes, + "SchemaName": `${customizationprefix}_${this.removeSpaces(this.displayName)}`, + "PrimaryNameAttribute": `${customizationprefix}_${this.removeSpaces(this.primaryAttribute)}`, + "OwnershipType": "UserOwned", + }, + }); + + const entityId = headers["odata-entityid"].substring(headers["odata-entityid"].lastIndexOf("/") + 1); + const response = await this.microsoft.getEntity({ + $, + entityId, + }); + + $.export("$summary", `Successfully created custom entity with ID: ${entityId}`); + + return response; + }, +}; diff --git a/components/microsoft_dynamics_365_sales/actions/find-contact/find-contact.mjs b/components/microsoft_dynamics_365_sales/actions/find-contact/find-contact.mjs new file mode 100644 index 0000000000000..a146ac59ea7cf --- /dev/null +++ b/components/microsoft_dynamics_365_sales/actions/find-contact/find-contact.mjs @@ -0,0 +1,59 @@ +import microsoft from "../../microsoft_dynamics_365_sales.app.mjs"; + +export default { + key: "microsoft_dynamics_365_sales-find-contact", + name: "Find Contact", + description: "Search for a contact by id, name, or using a custom filter. [See the documentation](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/webapi/query/overview)", + version: "0.0.1", + type: "action", + props: { + microsoft, + contactId: { + propDefinition: [ + microsoft, + "contactId", + ], + }, + name: { + type: "string", + label: "Name", + description: "Find contacts whose full name contains the name entered", + optional: true, + }, + filter: { + type: "string", + label: "Filter", + description: "Enter a custom filter to search contacts. E.g. `lastname eq 'Smith'`. [See the documentation] for more information about [filters](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/webapi/query/filter-rows)", + optional: true, + }, + }, + async run({ $ }) { + const filterArray = []; + if (this.contactId) { + filterArray.push(`contactid eq '${this.contactId}'`); + } + if (this.name) { + filterArray.push(`contains(fullname, '${this.name}')`); + } + if (this.filter) { + filterArray.push(`(${this.filter})`); + } + + const filter = filterArray.length + ? filterArray.join(" and ") + : undefined; + + const { value } = await this.microsoft.listContacts({ + $, + params: { + $filter: filter, + }, + }); + + $.export("$summary", `Successfully retrieved ${value.length} contact${value.length === 1 + ? "" + : "s"}`); + + return value; + }, +}; diff --git a/components/microsoft_dynamics_365_sales/common/language-codes.mjs b/components/microsoft_dynamics_365_sales/common/language-codes.mjs new file mode 100644 index 0000000000000..5d7674fb60fba --- /dev/null +++ b/components/microsoft_dynamics_365_sales/common/language-codes.mjs @@ -0,0 +1,434 @@ +export default [ + { + label: "Afrikaans - South Africa", + value: 1078, + }, + { + label: "Albanian - Albania", + value: 1052, + }, + { + label: "Arabic - Algeria", + value: 5121, + }, + { + label: "Arabic - Bahrain", + value: 15361, + }, + { + label: "Arabic - Egypt", + value: 3073, + }, + { + label: "Arabic - Iraq", + value: 2049, + }, + { + label: "Arabic - Jordan", + value: 11265, + }, + { + label: "Arabic - Kuwait", + value: 13313, + }, + { + label: "Arabic - Lebanon", + value: 12289, + }, + { + label: "Arabic - Libya", + value: 4097, + }, + { + label: "Arabic - Morocco", + value: 6145, + }, + { + label: "Arabic - Oman", + value: 8193, + }, + { + label: "Arabic - Qatar", + value: 16385, + }, + { + label: "Arabic - Saudi Arabia", + value: 1025, + }, + { + label: "Arabic - Syria", + value: 10241, + }, + { + label: "Arabic - Tunisia", + value: 7169, + }, + { + label: "Arabic - U.A.E.", + value: 14337, + }, + { + label: "Arabic - Yemen", + value: 9217, + }, + { + label: "Armenian - Armenia", + value: 1067, + }, + { + label: "Azeri (Cyrillic) - Azerbaijan", + value: 2092, + }, + { + label: "Azeri (Latin) - Azerbaijan", + value: 1068, + }, + { + label: "Basque - Spain", + value: 1069, + }, + { + label: "Belarusian - Belarus", + value: 1059, + }, + { + label: "Bulgarian - Bulgaria", + value: 1026, + }, + { + label: "Catalan - Spain", + value: 1027, + }, + { + label: "Chinese - Hong Kong S.A.R.", + value: 3076, + }, + { + label: "Chinese - Macau S.A.R.", + value: 5124, + }, + { + label: "Chinese - People's Republic of China", + value: 2052, + }, + { + label: "Chinese - Singapore", + value: 4100, + }, + { + label: "Chinese - Taiwan", + value: 1028, + }, + { + label: "Croatian - Croatia", + value: 1050, + }, + { + label: "Czech - Czech Republic", + value: 1029, + }, + { + label: "Danish - Denmark", + value: 1030, + }, + { + label: "Divehi - Maldives", + value: 1125, + }, + { + label: "Dutch - Belgium", + value: 2067, + }, + { + label: "Dutch - Netherlands", + value: 1043, + }, + { + label: "English - Australia", + value: 3081, + }, + { + label: "English - Belize", + value: 10249, + }, + { + label: "English - Canada", + value: 4105, + }, + { + label: "English - Caribbean", + value: 9225, + }, + { + label: "English - Ireland", + value: 6153, + }, + { + label: "English - Jamaica", + value: 8201, + }, + { + label: "English - New Zealand", + value: 5129, + }, + { + label: "English - Republic of the Philippines", + value: 13321, + }, + { + label: "English - South Africa", + value: 7177, + }, + { + label: "English - Trinidad and Tobago", + value: 11273, + }, + { + label: "English - United Kingdom", + value: 2057, + }, + { + label: "English - United States", + value: 1033, + }, + { + label: "English - Zimbabwe", + value: 12297, + }, + { + label: "Estonian - Estonia", + value: 1061, + }, + { + label: "Faroese - Faeroe Islands", + value: 1080, + }, + { + label: "Farsi - Iran", + value: 1065, + }, + { + label: "Finnish - Finland", + value: 1035, + }, + { + label: "French - Belgium", + value: 2060, + }, + { + label: "French - Canada", + value: 3084, + }, + { + label: "French - France", + value: 1036, + }, + { + label: "French - Luxembourg", + value: 5132, + }, + { + label: "French - Monaco", + value: 6156, + }, + { + label: "French - Switzerland", + value: 4108, + }, + { + label: "Macedonian - North Macedonia", + value: 1071, + }, + { + label: "Galician - Spain", + value: 1110, + }, + { + label: "Georgian - Georgia", + value: 1079, + }, + { + label: "German - Austria", + value: 3079, + }, + { + label: "German - Germany", + value: 1031, + }, + { + label: "German - Liechtenstein", + value: 5127, + }, + { + label: "German - Luxembourg", + value: 4103, + }, + { + label: "German - Switzerland", + value: 2055, + }, + { + label: "Greek - Greece", + value: 1032, + }, + { + label: "Gujarati - India", + value: 1095, + }, + { + label: "Hebrew - Israel", + value: 1037, + }, + { + label: "Hindi - India", + value: 1081, + }, + { + label: "Hungarian - Hungary", + value: 1038, + }, + { + label: "Icelandic - Iceland", + value: 1039, + }, + { + label: "Indonesian - Indonesia", + value: 1057, + }, + { + label: "Italian - Italy", + value: 1040, + }, + { + label: "Italian - Switzerland", + value: 2064, + }, + { + label: "Japanese - Japan", + value: 1041, + }, + { + label: "Kannada - India", + value: 1099, + }, + { + label: "Kazakh - Kazakhstan", + value: 1087, + }, + { + label: "Korean - Korea", + value: 1042, + }, + { + label: "Latvian - Latvia", + value: 1062, + }, + { + label: "Lithuanian - Lithuania", + value: 1063, + }, + { + label: "Malay - Brunei Darussalam", + value: 2110, + }, + { + label: "Malay - Malaysia", + value: 1086, + }, + { + label: "Marathi - India", + value: 1102, + }, + { + label: "Mongolian - Mongolia", + value: 1104, + }, + { + label: "Norwegian (Bokmål) - Norway", + value: 1044, + }, + { + label: "Norwegian (Nynorsk) - Norway", + value: 2068, + }, + { + label: "Polish - Poland", + value: 1045, + }, + { + label: "Portuguese - Brazil", + value: 1046, + }, + { + label: "Portuguese - Portugal", + value: 2070, + }, + { + label: "Punjabi - India", + value: 1094, + }, + { + label: "Romanian - Romania", + value: 1048, + }, + { + label: "Russian - Russia", + value: 1049, + }, + { + label: "Spanish - Spain", + value: 1034, + }, + { + label: "Spanish - Mexico", + value: 2058, + }, + { + label: "Spanish - Argentina", + value: 11274, + }, + { + label: "Spanish - Chile", + value: 13322, + }, + { + label: "Spanish - Colombia", + value: 9226, + }, + { + label: "Swahili - Kenya", + value: 1089, + }, + { + label: "Swedish - Sweden", + value: 1053, + }, + { + label: "Tamil - India", + value: 1097, + }, + { + label: "Thai - Thailand", + value: 1054, + }, + { + label: "Turkish - Turkey", + value: 1055, + }, + { + label: "Ukrainian - Ukraine", + value: 1058, + }, + { + label: "Urdu - Pakistan", + value: 1056, + }, + { + label: "Vietnamese - Vietnam", + value: 1066, + }, + { + label: "Welsh - United Kingdom", + value: 1106, + }, +]; diff --git a/components/microsoft_dynamics_365_sales/microsoft_dynamics_365_sales.app.mjs b/components/microsoft_dynamics_365_sales/microsoft_dynamics_365_sales.app.mjs index 84568479e8958..92582ba189642 100644 --- a/components/microsoft_dynamics_365_sales/microsoft_dynamics_365_sales.app.mjs +++ b/components/microsoft_dynamics_365_sales/microsoft_dynamics_365_sales.app.mjs @@ -1,11 +1,104 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "microsoft_dynamics_365_sales", - propDefinitions: {}, + propDefinitions: { + contactId: { + type: "string", + label: "Contact ID", + description: "The identifier of a contact", + optional: true, + async options() { + const { value } = await this.listContacts(); + return value?.map(({ + contactid: value, fullname: label, + }) => ({ + value, + label, + })) || []; + }, + }, + solutionId: { + type: "string", + label: "Solution ID", + description: "Identifier of a solution", + async options() { + const { value } = await this.listSolutions(); + return value?.filter(({ isvisible }) => isvisible)?.map(({ + solutionid: value, uniquename, friendlyname, + }) => ({ + value, + label: friendlyname || uniquename, + })) || []; + }, + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _baseUrl() { + return `https://${this.$auth.org_domain}.crm.dynamics.com/api/data/v9.2`; + }, + _makeRequest({ + $ = this, + path, + headers, + ...opts + }) { + return axios($, { + url: `${this._baseUrl()}${path}`, + headers: { + ...headers, + "Authorization": `Bearer ${this.$auth.oauth_access_token}`, + "odata-maxversion": "4.0", + "odata-version": "4.0", + "content-type": "application/json", + "If-None-Match": null, + }, + ...opts, + }); + }, + listContacts(opts = {}) { + return this._makeRequest({ + path: "/contacts", + ...opts, + }); + }, + getPublisher({ + publisherId, ...opts + }) { + return this._makeRequest({ + path: `/publishers(${publisherId})`, + ...opts, + }); + }, + getSolution({ + solutionId, ...opts + }) { + return this._makeRequest({ + path: `/solutions(${solutionId})`, + ...opts, + }); + }, + listSolutions(opts = {}) { + return this._makeRequest({ + path: "/solutions", + ...opts, + }); + }, + getEntity({ + entityId, ...opts + }) { + return this._makeRequest({ + path: `/${entityId}`, + ...opts, + }); + }, + createCustomEntity(opts = {}) { + return this._makeRequest({ + method: "POST", + path: "/EntityDefinitions", + ...opts, + }); }, }, -}; \ No newline at end of file +}; diff --git a/components/microsoft_dynamics_365_sales/package.json b/components/microsoft_dynamics_365_sales/package.json index 940e870f03d74..0c3a5b2660126 100644 --- a/components/microsoft_dynamics_365_sales/package.json +++ b/components/microsoft_dynamics_365_sales/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/microsoft_dynamics_365_sales", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream Microsoft Dynamics 365 Sales Components", "main": "microsoft_dynamics_365_sales.app.mjs", "keywords": [ @@ -11,5 +11,9 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^3.0.3", + "pluralize": "^8.0.0" } -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bac7b6366b43d..27446620b6db5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6519,7 +6519,14 @@ importers: specifier: ^3.0.3 version: 3.0.3 - components/microsoft_dynamics_365_sales: {} + components/microsoft_dynamics_365_sales: + dependencies: + '@pipedream/platform': + specifier: ^3.0.3 + version: 3.0.3 + pluralize: + specifier: ^8.0.0 + version: 8.0.0 components/microsoft_entra_id: dependencies: @@ -10285,8 +10292,7 @@ importers: specifier: ^3.0.1 version: 3.0.3 - components/storerocket: - specifiers: {} + components/storerocket: {} components/stormboard: {} @@ -32103,6 +32109,8 @@ snapshots: '@putout/operator-filesystem': 5.0.0(putout@36.13.1(eslint@8.57.1)(typescript@5.6.3)) '@putout/operator-json': 2.2.0 putout: 36.13.1(eslint@8.57.1)(typescript@5.6.3) + transitivePeerDependencies: + - supports-color '@putout/operator-regexp@1.0.0(putout@36.13.1(eslint@8.57.1)(typescript@5.6.3))': dependencies: