@pipedream/freshdesk 0.0.3 → 0.1.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.
package/LICENSE CHANGED
@@ -1,7 +1,41 @@
1
- Copyright 2020 Pipedream, Inc.
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
-
5
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
-
7
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ Pipedream Source Available License Version 1.0
2
+
3
+ This Pipedream Source Available License Agreement Version 1.0 (this “Agreement”) sets forth the terms on which Pipedream, Inc., a Delaware corporation (“Pipedream”) makes available certain software (the Software). By installing, downloading, accessing, using or distributing the Software, you agree to the terms of this Agreement. If you do not agree to such terms, you must not use the Software. If you are receiving the Software on behalf of a legal entity, you represent and warrant that you have the actual authority to agree to the terms and conditions of this Agreement on behalf of such entity. “Licensee” means you, an individual, or the entity on whose behalf you are receiving the Software.
4
+
5
+ LICENSE GRANT AND CONDITIONS.
6
+
7
+ 1.1 License. Subject to the terms and conditions of this Agreement, Pipedream hereby grants to Licensee a non-exclusive, royalty-free, worldwide, non-transferable, non-sublicenseable license during the term of this Agreement to use, prepare modifications and derivative works, distribute (including without limitation in source code or object code form) and reproduce copies of the Software (the “License”). Licensee is not granted the right to, and Licensee shall not, exercise the License for an Excluded Purpose. For purposes of this Agreement, “Excluded Purpose” means any commercial use of the software including, but not limited to, making available any software-as-a-service, platform-as-a-service, infrastructure-as-a-service or other online service that competes with the Software or any other Pipedream products or services.
8
+
9
+ 1.2 Conditions. In consideration of the License, Licensee’s distribution of the Software is subject to the following conditions:
10
+
11
+ a. Licensee must cause any Software modified by Licensee to carry prominent notices stating that Licensee modified the Software.
12
+
13
+ b. On each Software copy, Licensee shall reproduce and not remove or alter all Pipedream or third party copyright or other proprietary notices contained in the Software, and Licensee must provide this with each copy: “This software is made available by Pipedream, Inc., under the terms of the Pipedream Source Available License, Version 1.0 located at https://github.com/PipedreamHQ/pipedream/blob/master/LICENSE. By installing, downloading, accessing, using or distributing the Software, you agree to the terms of such License Agreement.”
14
+
15
+ 1.3 Modifications. Licensee may add its own copyright notices to modifications made by Licensee and may provide additional or different license terms and conditions for use, reproduction, or distribution of Licensee’s modifications. While redistributing the Software or modifications thereof, Licensee may choose to offer, for a fee or free of charge, support, warranty, indemnity, or other obligations. Licensee, and not Pipedream, will be responsible for any such obligations.
16
+
17
+ 1.4 No Sublicensing. The License does not include the right to sublicense the Software; provided, however, that any recipient to which Licensee provides the Software may exercise the License so long as such recipient agrees to the terms and conditions of this Agreement.
18
+
19
+ TERM AND TERMINATION.
20
+
21
+ This Agreement will continue unless and until earlier terminated as set forth herein. If Licensee breaches any of its conditions or obligations under this Agreement, this Agreement will terminate automatically and the License will terminate automatically and permanently.
22
+
23
+ INTELLECTUAL PROPERTY.
24
+
25
+ As between the parties, Pipedream retains all right, title, and interest in the Software, and all intellectual property rights therein. Pipedream hereby reserves all rights not expressly granted to Licensee in this Agreement. Pipedream reserves all rights in its trademarks and service marks, and no licenses thereto are granted by this Agreement.
26
+
27
+ DISCLAIMER.
28
+
29
+ PIPEDREAM HEREBY DISCLAIMS ANY AND ALL WARRANTIES AND CONDITIONS, EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, AND SPECIFICALLY DISCLAIMS ANY WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, WITH RESPECT TO THE SOFTWARE.
30
+
31
+ LIMITATION OF LIABILITY.
32
+
33
+ PIPEDREAM WILL NOT BE LIABLE FOR ANY DAMAGES OF ANY KIND, INCLUDING BUT NOT LIMITED TO, LOST PROFITS OR ANY CONSEQUENTIAL, SPECIAL, INCIDENTAL, INDIRECT, OR DIRECT DAMAGES, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, ARISING OUT OF THIS AGREEMENT. THE FOREGOING SHALL APPLY TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW.
34
+
35
+ GENERAL.
36
+
37
+ 6.1 Governing Law. This Agreement will be governed by and interpreted in accordance with the laws of the state of California, without reference to its conflict of laws principles. If Licensee is located outside of the United States, any dispute, controversy or claim arising out of or relating to this Agreement will be referred to and finally determined by arbitration in accordance with the JAMS International Arbitration Rules. The tribunal will consist of one arbitrator. Judgment upon the award rendered by the arbitrator may be entered in any court having jurisdiction thereof. All disputes including arbitrations shall take place in Santa Clara County, California. The language to be used in any such proceedings shall be English.
38
+
39
+ 6.2. Assignment. Licensee is not authorized to assign its rights under this Agreement to any third party. Pipedream may freely assign its rights under this Agreement to any third party.
40
+
41
+ 6.3. Other. This Agreement is the entire agreement between the parties regarding the subject matter hereof. No amendment or modification of this Agreement will be valid or binding upon the parties unless made in writing and signed by the duly authorized representatives of both parties. In the event that any provision, including without limitation any condition, of this Agreement is held to be unenforceable, this Agreement and all licenses and rights granted hereunder will immediately terminate. Waiver by Pipedream of a breach of any provision of this Agreement or the failure by Pipedream to exercise any right hereunder will not be construed as a waiver of any subsequent breach of that right or as a waiver of any other right.
package/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # Overview
2
+
3
+ The Freshdesk API empowers you to interact programmatically with your customer support platform, creating possibilities for automating repetitive tasks, integrating with other services, and enhancing customer experiences. With Pipedream, you can effortlessly connect Freshdesk to a multitude of apps, tapping into triggers and actions that streamline workflows. For instance, you can automate ticket creation, sync customer issues with a CRM, or trigger notifications based on ticket updates, all within a serverless environment.
4
+
5
+ # Example Use Cases
6
+
7
+ - **Auto-ticket Generation from Emails**: When an email arrives at a specific mailbox, Pipedream can capture that event and use the Freshdesk API to create a new support ticket. This ensures that no customer query goes unanswered and allows support teams to manage all requests from Freshdesk's centralized interface.
8
+
9
+ - **CRM Sync with Ticket Updates**: Once a ticket in Freshdesk is updated—be it a status change, priority update, or note addition—a Pipedream workflow can push these updates to a connected CRM, like Salesforce. This keeps sales and support teams aligned on customer interactions, providing a seamless customer service experience.
10
+
11
+ - **Slack Notifications for Urgent Tickets**: Using Pipedream's integration with Slack, build a workflow that listens for new tickets tagged as 'urgent' in Freshdesk. Then, automatically send a message to a designated Slack channel or direct message to a team member, ensuring immediate attention is given to critical support issues.
@@ -1,35 +1,34 @@
1
- import { removeNullEntries } from "../../common/utils.mjs";
2
1
  import freshdesk from "../../freshdesk.app.mjs";
3
2
 
4
3
  export default {
5
4
  key: "freshdesk-create-company",
6
5
  name: "Create a Company",
7
- description: "Create a company. [See docs here](https://developers.freshdesk.com/api/#companies)",
8
- version: "0.0.1",
6
+ description: "Create a company. [See the documentation](https://developers.freshdesk.com/api/#create_company)",
7
+ version: "0.0.2",
9
8
  type: "action",
10
9
  props: {
11
10
  freshdesk,
12
11
  name: {
13
12
  type: "string",
14
13
  label: "Name",
15
- description: "Name of the company.",
14
+ description: "Name of the company",
16
15
  },
17
16
  description: {
18
17
  type: "string",
19
18
  label: "Description",
20
- description: "Description of the company.",
19
+ description: "Description of the company",
21
20
  optional: true,
22
21
  },
23
22
  note: {
24
23
  type: "string",
25
24
  label: "Note",
26
- description: "Any specific note about the company.",
25
+ description: "Any specific note about the company",
27
26
  optional: true,
28
27
  },
29
28
  industry: {
30
29
  type: "string",
31
30
  label: "Industry",
32
- description: "The industry the company serves in.",
31
+ description: "The industry the company serves in",
33
32
  optional: true,
34
33
  },
35
34
  domains: {
@@ -40,18 +39,14 @@ export default {
40
39
  },
41
40
  },
42
41
  async run({ $ }) {
43
- const payload = removeNullEntries({
44
- name: this.name,
45
- domains: this.domains,
46
- note: this.note,
47
- industry: this.industry,
48
- description: this.description,
49
- });
50
- const response = await this.freshdesk.createCompany({
42
+ const {
43
+ freshdesk, ...data
44
+ } = this;
45
+ const response = await freshdesk.createCompany({
51
46
  $,
52
- payload,
47
+ data,
53
48
  });
54
- response && $.export("$summary", "Company sucessfully created");
49
+ response && $.export("$summary", "Company successfully created");
55
50
  return response;
56
51
  },
57
52
  };
@@ -1,11 +1,10 @@
1
- import { removeNullEntries } from "../../common/utils.mjs";
2
1
  import freshdesk from "../../freshdesk.app.mjs";
3
2
 
4
3
  export default {
5
4
  key: "freshdesk-create-contact",
6
5
  name: "Create a Contact",
7
- description: "Create a contact. [See docs here](https://developers.freshdesk.com/api/#create_contact)",
8
- version: "0.0.1",
6
+ description: "Create a contact. [See the documentation](https://developers.freshdesk.com/api/#create_contact)",
7
+ version: "0.0.2",
9
8
  type: "action",
10
9
  props: {
11
10
  freshdesk,
@@ -16,20 +15,20 @@ export default {
16
15
  },
17
16
  email: {
18
17
  type: "string",
19
- label: "Email",
20
- description: "Primary email address of the contact. If you want to associate additional email(s) with this contact, use the other_emails attribute.",
18
+ label: "Email Address",
19
+ description: "Primary email address of the contact",
21
20
  optional: true,
22
21
  },
23
22
  otherEmails: {
24
23
  type: "string[]",
25
- label: "Additional email addresses",
26
- description: "String array of additional email addresses.",
24
+ label: "Additional Email Addresses",
25
+ description: "One or more additional email addresses for the contact",
27
26
  optional: true,
28
27
  },
29
28
  phone: {
30
29
  type: "string",
31
- label: "Phone number",
32
- description: "Telephone number of the contact.",
30
+ label: "Phone Number",
31
+ description: "Phone number of the contact",
33
32
  optional: true,
34
33
  },
35
34
  companyId: {
@@ -41,16 +40,16 @@ export default {
41
40
  },
42
41
  },
43
42
  async run({ $ }) {
44
- const data = removeNullEntries({
45
- name: this.name,
46
- email: this.email,
47
- other_emails: this.otherEmails,
48
- phone: this.phone,
49
- company_id: this.companyId && Number(this.companyId),
50
- });
43
+ const {
44
+ companyId, otherEmails, ...data
45
+ } = this;
51
46
  const response = await this.freshdesk.createContact({
52
47
  $,
53
- data,
48
+ data: {
49
+ other_emails: otherEmails,
50
+ company_id: companyId && Number(companyId),
51
+ ...data,
52
+ },
54
53
  });
55
54
  response && $.export("$summary", "Contact successfully created");
56
55
  return response;
@@ -1,11 +1,10 @@
1
1
  import freshdesk from "../../freshdesk.app.mjs";
2
- import { removeNullEntries } from "../../common/utils.mjs";
3
2
 
4
3
  export default {
5
4
  key: "freshdesk-create-ticket",
6
5
  name: "Create a Ticket",
7
- description: "Create a ticket. [See docs here](https://developers.freshdesk.com/api/#tickets)",
8
- version: "0.0.2",
6
+ description: "Create a ticket. [See the documentation](https://developers.freshdesk.com/api/#create_ticket)",
7
+ version: "0.0.3",
9
8
  type: "action",
10
9
  props: {
11
10
  freshdesk,
@@ -14,7 +13,6 @@ export default {
14
13
  freshdesk,
15
14
  "companyId",
16
15
  ],
17
- description: "ID of the company to which this ticket belongs",
18
16
  },
19
17
  email: {
20
18
  propDefinition: [
@@ -24,7 +22,6 @@ export default {
24
22
  companyId,
25
23
  }),
26
24
  ],
27
- description: "Email address of the requester.",
28
25
  optional: true,
29
26
  },
30
27
  priority: {
@@ -34,28 +31,28 @@ export default {
34
31
  ],
35
32
  default: 1,
36
33
  },
34
+ subject: {
35
+ type: "string",
36
+ label: "Subject",
37
+ description: "Subject of the ticket",
38
+ optional: true,
39
+ },
37
40
  description: {
38
41
  type: "string",
39
42
  label: "Description",
40
- description: "HTML content of the ticket.",
43
+ description: "HTML content of the ticket",
41
44
  optional: true,
42
45
  },
43
46
  descriptionText: {
44
47
  type: "string",
45
48
  label: "Description text",
46
- description: "Content of the ticket in plain text.",
49
+ description: "Content of the ticket in plain text",
47
50
  optional: true,
48
51
  },
49
52
  phone: {
50
53
  type: "string",
51
54
  label: "Phone number",
52
- description: "Telephone number of the contact.",
53
- optional: true,
54
- },
55
- subject: {
56
- type: "string",
57
- label: "Subject",
58
- description: "Subject of the ticket.",
55
+ description: "Phone number of the requester. If no contact exists with this phone number on Freshdesk, it will be added as a new contact",
59
56
  optional: true,
60
57
  },
61
58
  status: {
@@ -68,19 +65,16 @@ export default {
68
65
  },
69
66
  },
70
67
  async run({ $ }) {
71
- const data = removeNullEntries({
72
- company_id: this.companyId && Number(this.companyId),
73
- description: this.description,
74
- description_text: this.descriptionText,
75
- email: this.email,
76
- phone: this.phone,
77
- subject: this.subject,
78
- status: this.status && Number(this.status),
79
- priority: this.priority && Number(this.priority),
80
- });
81
- const response = await this.freshdesk.createTicket({
68
+ const {
69
+ freshdesk, companyId, descriptionText, ...data
70
+ } = this;
71
+ const response = await freshdesk.createTicket({
82
72
  $,
83
- data,
73
+ data: {
74
+ company_id: Number(companyId),
75
+ description_text: descriptionText,
76
+ ...data,
77
+ },
84
78
  });
85
79
  response && $.export("$summary", "Ticket successfully created");
86
80
  return response;
@@ -3,23 +3,27 @@ import freshdesk from "../../freshdesk.app.mjs";
3
3
  export default {
4
4
  key: "freshdesk-get-ticket",
5
5
  name: "Get Ticket Details",
6
- description: "Get a Ticket. [See docs here](https://developers.freshdesk.com/api/#tickets)",
7
- version: "0.0.1",
6
+ description: "Get details of a Ticket. [See the documentation](https://developers.freshdesk.com/api/#view_a_ticket)",
7
+ version: "0.1.0",
8
8
  type: "action",
9
9
  props: {
10
10
  freshdesk,
11
- id: {
12
- type: "string",
13
- label: "Ticket ID",
14
- description: "Ticket ID.",
11
+ ticketId: {
12
+ propDefinition: [
13
+ freshdesk,
14
+ "ticketId",
15
+ ],
15
16
  },
16
17
  },
17
18
  async run({ $ }) {
18
- const response = await this.freshdesk.getTicket({
19
+ const {
20
+ freshdesk, ticketId,
21
+ } = this;
22
+ const response = await freshdesk.getTicket({
19
23
  $,
20
- id: this.id,
24
+ ticketId,
21
25
  });
22
- response && $.export("$summary", "Successfully found ticket");
26
+ response && $.export("$summary", "Successfully retrieved ticket");
23
27
  return response;
24
28
  },
25
29
  };
@@ -1,25 +1,69 @@
1
- // legacy_hash_id: a_A6i5zz
2
- import { axios } from "@pipedream/platform";
1
+ import freshdesk from "../../freshdesk.app.mjs";
3
2
 
4
3
  export default {
5
4
  key: "freshdesk-list-all-tickets",
6
- name: "List All Tickets",
7
- description: "Use filters to view only specific tickets (those which match the criteria that you choose). By default, only tickets that have not been deleted or marked as spam will be returned, unless you use the 'deleted' filter.",
8
- version: "0.1.1",
5
+ name: "List Tickets",
6
+ description:
7
+ "Fetch up to 100 tickets according to the selected filters. [See the documentation](https://developers.freshdesk.com/api/#list_all_tickets)",
8
+ version: "0.2.0",
9
9
  type: "action",
10
10
  props: {
11
- freshdesk: {
12
- type: "app",
13
- app: "freshdesk",
11
+ freshdesk,
12
+ orderBy: {
13
+ type: "string",
14
+ label: "Sort By",
15
+ description: "Which field to sort tickets by. Defaults to `Created At`",
16
+ optional: true,
17
+ options: [
18
+ {
19
+ value: "created_at",
20
+ label: "Created At",
21
+ },
22
+ {
23
+ value: "due_by",
24
+ label: "Due By",
25
+ },
26
+ {
27
+ value: "updated_at",
28
+ label: "Updated At",
29
+ },
30
+ {
31
+ value: "status",
32
+ label: "Status",
33
+ },
34
+ ],
35
+ },
36
+ orderType: {
37
+ type: "string",
38
+ label: "Sort Order",
39
+ description:
40
+ "Whether to sort in ascending or descending order. Defaults to descending",
41
+ optional: true,
42
+ options: [
43
+ {
44
+ label: "Ascending",
45
+ value: "asc",
46
+ },
47
+ {
48
+ label: "Descending",
49
+ value: "desc",
50
+ },
51
+ ],
14
52
  },
15
53
  },
16
54
  async run({ $ }) {
17
- return await axios($, {
18
- url: `https://${this.freshdesk.$auth.domain}.freshdesk.com/api/v2/tickets`,
19
- auth: {
20
- username: `${this.freshdesk.$auth.api_key}:X`,
21
- password: "",
55
+ const response = await this.freshdesk.listTickets({
56
+ $,
57
+ params: {
58
+ order_by: this.orderBy,
59
+ order_type: this.orderType,
22
60
  },
23
61
  });
62
+
63
+ const { length } = response;
64
+ $.export("$summary", `Successfully fetched ${length} ticket${length === 1
65
+ ? ""
66
+ : "s"}`);
67
+ return response;
24
68
  },
25
69
  };
@@ -1,13 +1,5 @@
1
1
  export default {
2
- HTTP_PROTOCOL: "https://",
3
- BASE_PATH: "/api",
4
- VERSION_PATH: "/v2",
5
2
  PAGE_SIZE: 100,
6
- retriableStatusCodes: [
7
- 408,
8
- 429,
9
- 500,
10
- ],
11
3
  DB_LAST_DATE_CHECK: "DB_LAST_DATE_CHECK",
12
4
  TICKET_STATUS: [
13
5
  {
package/freshdesk.app.mjs CHANGED
@@ -1,8 +1,5 @@
1
1
  import constants from "./common/constants.mjs";
2
- import {
3
- axios, ConfigurationError,
4
- } from "@pipedream/platform";
5
- import retry from "async-retry";
2
+ import { axios } from "@pipedream/platform";
6
3
 
7
4
  export default {
8
5
  type: "app",
@@ -11,19 +8,39 @@ export default {
11
8
  companyId: {
12
9
  type: "integer",
13
10
  label: "Company ID",
14
- description: "The ID of the company",
11
+ description: "Select a company or provide a company ID",
15
12
  async options() {
16
13
  const response = await this.getCompanies();
17
- return response.map((project) => ({
18
- label: project.name,
19
- value: project.id,
14
+ return response.map(({
15
+ id, name,
16
+ }) => ({
17
+ label: name || id,
18
+ value: id,
19
+ }));
20
+ },
21
+ },
22
+ ticketId: {
23
+ type: "integer",
24
+ label: "Ticket ID",
25
+ description: "Select a ticket or provide a ticket ID",
26
+ async options({ page = 0 }) {
27
+ const response = await this.listTickets({
28
+ params: {
29
+ page: page + 1,
30
+ },
31
+ });
32
+ return response.map(({
33
+ id, subject,
34
+ }) => ({
35
+ label: subject || id,
36
+ value: id,
20
37
  }));
21
38
  },
22
39
  },
23
40
  ticketStatus: {
24
41
  type: "integer",
25
42
  label: "Status",
26
- description: "Status of the ticket.",
43
+ description: "Status of the ticket",
27
44
  options() {
28
45
  return constants.TICKET_STATUS;
29
46
  },
@@ -31,7 +48,7 @@ export default {
31
48
  ticketPriority: {
32
49
  type: "integer",
33
50
  label: "Priority",
34
- description: "Priority of the ticket.",
51
+ description: "Priority of the ticket",
35
52
  options() {
36
53
  return constants.TICKET_PRIORITY;
37
54
  },
@@ -39,14 +56,18 @@ export default {
39
56
  contactEmail: {
40
57
  type: "string",
41
58
  label: "Email",
42
- description: "Contact Email.",
59
+ description: "Select a contact or provide a contact's email",
43
60
  async options({ companyId }) {
44
- const response = await this.getCompanies();
45
- const contacts = response.filter((contact) => contact.company_id === Number(companyId));
46
- return contacts.map((contact) => ({
47
- label: contact?.email ?? contact?.name,
48
- value: contact.email,
49
- }));
61
+ const contacts = await this.getContacts();
62
+ const numId = Number(companyId);
63
+ return contacts
64
+ .filter((contact) => contact.company_id === numId)
65
+ .map(({
66
+ email, name,
67
+ }) => ({
68
+ label: name || email,
69
+ value: email,
70
+ }));
50
71
  },
51
72
  },
52
73
  },
@@ -66,64 +87,32 @@ export default {
66
87
  "Content-Type": "application/json;charset=utf-8",
67
88
  };
68
89
  },
69
- _getUrl(path) {
70
- const {
71
- HTTP_PROTOCOL,
72
- BASE_PATH,
73
- VERSION_PATH,
74
- } = constants;
75
- return `${HTTP_PROTOCOL}${this.$auth.domain}${BASE_PATH}${VERSION_PATH}${path}`;
76
- },
77
- async _makeRequest(args = {}) {
78
- const {
79
- $,
80
- method = "get",
81
- path,
82
- params,
83
- data,
84
- } = args;
85
- const config = {
86
- method,
87
- url: this._getUrl(path),
88
- headers: this._getHeaders(),
89
- params,
90
- data,
91
- };
92
-
93
- return axios($ ?? this, config);
94
- },
95
- _isRetriableStatusCode(statusCode) {
96
- constants.retriableStatusCodes.includes(statusCode);
90
+ _getDomain() {
91
+ const { domain } = this.$auth;
92
+ return domain.includes("freshdesk.com")
93
+ ? domain
94
+ : `${domain}.freshdesk.com`;
97
95
  },
98
- async _withRetries(apiCall) {
99
- const retryOpts = {
100
- retries: 5,
101
- factor: 2,
102
- };
103
- return retry(async (bail) => {
104
- try {
105
- const data = await apiCall();
106
-
107
- return data;
108
- } catch (err) {
109
-
110
- const { status = 500 } = err;
111
- if (!this._isRetriableStatusCode(status)) {
112
- bail(`
113
- Unexpected error (status code: ${status}):
114
- ${JSON.stringify(err.response)}
115
- `);
116
- }
117
- throw new ConfigurationError("Could not get data");
118
- }
119
- }, retryOpts);
96
+ async _makeRequest({
97
+ $ = this, headers, ...args
98
+ }) {
99
+ return axios($, {
100
+ baseURL: `https://${this._getDomain()}/api/v2`,
101
+ headers: {
102
+ ...this._getHeaders(),
103
+ ...headers,
104
+ },
105
+ ...args,
106
+ });
120
107
  },
121
108
  async *filterTickets(params) {
122
109
  let loadedData = 0;
123
110
  do {
124
- const response = await this.searchTickets(params);
111
+ const response = await this.searchTickets({
112
+ params,
113
+ });
125
114
 
126
- if (!response || response.results.length === 0) {
115
+ if (!response?.results?.length) {
127
116
  return;
128
117
  }
129
118
  loadedData += response.results.length;
@@ -139,9 +128,11 @@ export default {
139
128
  async *filterContacts(params) {
140
129
  let loadedData = 0;
141
130
  do {
142
- const response = await this.searchContacts(params);
131
+ const response = await this.searchContacts({
132
+ params,
133
+ });
143
134
 
144
- if (!response || response.results.length === 0) {
135
+ if (!response?.results?.length) {
145
136
  return;
146
137
  }
147
138
  loadedData += response.results.length;
@@ -154,68 +145,63 @@ export default {
154
145
  params.page += 1;
155
146
  } while (true);
156
147
  },
157
- async createCompany({
158
- $, payload: data,
159
- }) {
148
+ async createCompany(args) {
160
149
  return this._makeRequest({
161
- $,
162
- path: "/companies",
163
- data,
150
+ url: "/companies",
164
151
  method: "post",
152
+ ...args,
165
153
  });
166
154
  },
167
- async getCompanies($ = undefined) {
155
+ async getCompanies(args) {
168
156
  return this._makeRequest({
169
- $,
170
- path: "/contacts",
157
+ url: "/companies",
158
+ ...args,
171
159
  });
172
160
  },
173
- async getContacts($ = undefined) {
161
+ async getContacts(args) {
174
162
  return this._makeRequest({
175
- $,
176
- path: "/companies",
163
+ url: "/contacts",
164
+ ...args,
177
165
  });
178
166
  },
179
- async createContact({
180
- $, data,
181
- }) {
167
+ async createContact(args) {
182
168
  return this._makeRequest({
183
- $,
184
- path: "/contacts",
185
- data,
169
+ url: "/contacts",
186
170
  method: "post",
171
+ ...args,
187
172
  });
188
173
  },
189
- async createTicket({
190
- $, data,
191
- }) {
174
+ async createTicket(args) {
192
175
  return this._makeRequest({
193
- $,
194
- path: "/tickets",
195
- data,
176
+ url: "/tickets",
196
177
  method: "post",
178
+ ...args,
197
179
  });
198
180
  },
199
181
  async getTicket({
200
- $, id,
182
+ ticketId, ...args
201
183
  }) {
202
184
  return this._makeRequest({
203
- $,
204
- path: `/tickets/${id}`,
185
+ url: `/tickets/${ticketId}`,
186
+ ...args,
187
+ });
188
+ },
189
+ async searchTickets(args) {
190
+ return this._makeRequest({
191
+ url: "/search/tickets",
192
+ ...args,
205
193
  });
206
194
  },
207
- async searchTickets(params, $ = undefined) {
195
+ async searchContacts(args) {
208
196
  return this._makeRequest({
209
- $,
210
- path: "/search/tickets",
211
- params,
197
+ url: "/search/contacts",
198
+ ...args,
212
199
  });
213
200
  },
214
- async searchContacts(params, $ = undefined) {
201
+ async listTickets(args) {
215
202
  return this._makeRequest({
216
- $,
217
- path: "/search/contacts",
218
- params,
203
+ url: "/tickets",
204
+ ...args,
219
205
  });
220
206
  },
221
207
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipedream/freshdesk",
3
- "version": "0.0.3",
3
+ "version": "0.1.0",
4
4
  "description": "Pipedream Freshdesk Components",
5
5
  "main": "freshdesk.app.mjs",
6
6
  "keywords": [
@@ -9,13 +9,12 @@
9
9
  ],
10
10
  "homepage": "https://pipedream.com/apps/freshdesk",
11
11
  "author": "Pipedream <support@pipedream.com> (https://pipedream.com/)",
12
- "license": "MIT",
13
12
  "publishConfig": {
14
13
  "access": "public"
15
14
  },
16
15
  "dependencies": {
17
- "@pipedream/platform": "^1.2.0",
16
+ "@pipedream/platform": "^3.0.3",
18
17
  "async-retry": "^1.3.3",
19
- "moment": "2.29.2"
18
+ "moment": "2.29.4"
20
19
  }
21
20
  }
@@ -4,15 +4,13 @@ import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform";
4
4
 
5
5
  export default {
6
6
  key: "freshdesk-new-contact",
7
- name: "New Contact",
8
- description: "Emit new notifications when a new contact is created",
9
- version: "0.0.2",
7
+ name: "New Contact Created",
8
+ description: "Emit new event when a contact is created. [See the documentation](https://developers.freshdesk.com/api/#filter_contacts)",
9
+ version: "0.0.3",
10
10
  type: "source",
11
11
  props: {
12
12
  freshdesk,
13
13
  timer: {
14
- label: "Polling interval",
15
- description: "Pipedream will poll Harvest API on this schedule",
16
14
  type: "$.interface.timer",
17
15
  default: {
18
16
  intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
@@ -42,7 +40,7 @@ export default {
42
40
  this.$emit(contact,
43
41
  {
44
42
  id: contact.id,
45
- summary: `Contact name: ${contact.name}`,
43
+ summary: `New Contact: "${contact.name}"`,
46
44
  ts: Date.parse(contact.created_at),
47
45
  });
48
46
  }
@@ -4,15 +4,13 @@ import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform";
4
4
 
5
5
  export default {
6
6
  key: "freshdesk-new-ticket",
7
- name: "New Ticket",
8
- description: "Emit new notifications when a new ticket is created",
9
- version: "0.0.2",
7
+ name: "New Ticket Created",
8
+ description: "Emit new event when a ticket is created. [See the documentation](https://developers.freshdesk.com/api/#filter_tickets)",
9
+ version: "0.0.3",
10
10
  type: "source",
11
11
  props: {
12
12
  freshdesk,
13
13
  timer: {
14
- label: "Polling interval",
15
- description: "Pipedream will poll Harvest API on this schedule",
16
14
  type: "$.interface.timer",
17
15
  default: {
18
16
  intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
@@ -28,7 +26,10 @@ export default {
28
26
  lastDateChecked = new Date().toISOString();
29
27
  this.freshdesk.setLastDateChecked(this.db, lastDateChecked);
30
28
  }
31
- const formatedDate = lastDateChecked.substr(0, (lastDateChecked + "T").indexOf("T"));
29
+ const formatedDate = lastDateChecked.substr(
30
+ 0,
31
+ (lastDateChecked + "T").indexOf("T"),
32
+ );
32
33
  const tickets = await this.freshdesk.filterTickets({
33
34
  query: `"created_at:>'${formatedDate}'"`,
34
35
  page: 1,
@@ -36,16 +37,16 @@ export default {
36
37
  for await (const ticket of tickets) {
37
38
  data.push(ticket);
38
39
  }
39
- data && data.reverse().forEach((ticket) => {
40
- this.freshdesk.setLastDateChecked(this.db, ticket.created_at);
41
- if (moment(ticket.created_at).isAfter(lastDateChecked)) {
42
- this.$emit(ticket,
43
- {
40
+ data &&
41
+ data.reverse().forEach((ticket) => {
42
+ this.freshdesk.setLastDateChecked(this.db, ticket.created_at);
43
+ if (moment(ticket.created_at).isAfter(lastDateChecked)) {
44
+ this.$emit(ticket, {
44
45
  id: ticket.id,
45
- summary: `Ticket number: ${ticket.id}`,
46
+ summary: `New Ticket (ID: ${ticket.id})`,
46
47
  ts: Date.parse(ticket.created_at),
47
48
  });
48
- }
49
- });
49
+ }
50
+ });
50
51
  },
51
52
  };