@pipedream/freshdesk 0.0.1
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 +7 -0
- package/actions/create-company/create-company.mjs +57 -0
- package/actions/create-contact/create-contact.mjs +58 -0
- package/actions/create-ticket/create-ticket.mjs +88 -0
- package/actions/get-ticket/get-ticket.mjs +25 -0
- package/actions/list-all-tickets/list-all-tickets.mjs +25 -0
- package/common/constants.mjs +48 -0
- package/common/utils.mjs +27 -0
- package/freshdesk.app.mjs +222 -0
- package/package.json +21 -0
- package/sources/new-contact/new-contact.mjs +50 -0
- package/sources/new-ticket/new-ticket.mjs +50 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
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.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { removeNullEntries } from "../../common/utils.mjs";
|
|
2
|
+
import freshdesk from "../../freshdesk.app.mjs";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
key: "freshdesk-create-company",
|
|
6
|
+
name: "Create a Company",
|
|
7
|
+
description: "Create a company. [See docs here](https://developers.freshdesk.com/api/#companies)",
|
|
8
|
+
version: "0.0.1",
|
|
9
|
+
type: "action",
|
|
10
|
+
props: {
|
|
11
|
+
freshdesk,
|
|
12
|
+
name: {
|
|
13
|
+
type: "string",
|
|
14
|
+
label: "Name",
|
|
15
|
+
description: "Name of the company.",
|
|
16
|
+
},
|
|
17
|
+
description: {
|
|
18
|
+
type: "string",
|
|
19
|
+
label: "Description",
|
|
20
|
+
description: "Description of the company.",
|
|
21
|
+
optional: true,
|
|
22
|
+
},
|
|
23
|
+
note: {
|
|
24
|
+
type: "string",
|
|
25
|
+
label: "Note",
|
|
26
|
+
description: "Any specific note about the company.",
|
|
27
|
+
optional: true,
|
|
28
|
+
},
|
|
29
|
+
industry: {
|
|
30
|
+
type: "string",
|
|
31
|
+
label: "Industry",
|
|
32
|
+
description: "The industry the company serves in.",
|
|
33
|
+
optional: true,
|
|
34
|
+
},
|
|
35
|
+
domains: {
|
|
36
|
+
type: "string[]",
|
|
37
|
+
label: "Domains",
|
|
38
|
+
description: "Domains of the company. Email addresses of contacts that contain this domain will be associated with that company automatically. e.g. [\"supernova\",\"nova\"]",
|
|
39
|
+
optional: true,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
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({
|
|
51
|
+
$,
|
|
52
|
+
payload,
|
|
53
|
+
});
|
|
54
|
+
response && $.export("$summary", "Company sucessfully created");
|
|
55
|
+
return response;
|
|
56
|
+
},
|
|
57
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { removeNullEntries } from "../../common/utils.mjs";
|
|
2
|
+
import freshdesk from "../../freshdesk.app.mjs";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
key: "freshdesk-create-contact",
|
|
6
|
+
name: "Create a Contact",
|
|
7
|
+
description: "Create a contact. [See docs here](https://developers.freshdesk.com/api/#create_contact)",
|
|
8
|
+
version: "0.0.1",
|
|
9
|
+
type: "action",
|
|
10
|
+
props: {
|
|
11
|
+
freshdesk,
|
|
12
|
+
name: {
|
|
13
|
+
type: "string",
|
|
14
|
+
label: "Name",
|
|
15
|
+
description: "Name of the contact.",
|
|
16
|
+
},
|
|
17
|
+
email: {
|
|
18
|
+
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.",
|
|
21
|
+
optional: true,
|
|
22
|
+
},
|
|
23
|
+
otherEmails: {
|
|
24
|
+
type: "string[]",
|
|
25
|
+
label: "Additional email addresses",
|
|
26
|
+
description: "String array of additional email addresses.",
|
|
27
|
+
optional: true,
|
|
28
|
+
},
|
|
29
|
+
phone: {
|
|
30
|
+
type: "string",
|
|
31
|
+
label: "Phone number",
|
|
32
|
+
description: "Telephone number of the contact.",
|
|
33
|
+
optional: true,
|
|
34
|
+
},
|
|
35
|
+
companyId: {
|
|
36
|
+
propDefinition: [
|
|
37
|
+
freshdesk,
|
|
38
|
+
"companyId",
|
|
39
|
+
],
|
|
40
|
+
optional: true,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
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
|
+
});
|
|
51
|
+
const response = await this.freshdesk.createContact({
|
|
52
|
+
$,
|
|
53
|
+
data,
|
|
54
|
+
});
|
|
55
|
+
response && $.export("$summary", "Contact successfully created");
|
|
56
|
+
return response;
|
|
57
|
+
},
|
|
58
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import freshdesk from "../../freshdesk.app.mjs";
|
|
2
|
+
import { removeNullEntries } from "../../common/utils.mjs";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
key: "freshdesk-create-ticket",
|
|
6
|
+
name: "Create a Ticket",
|
|
7
|
+
description: "Create a ticket. [See docs here](https://developers.freshdesk.com/api/#tickets)",
|
|
8
|
+
version: "0.0.2",
|
|
9
|
+
type: "action",
|
|
10
|
+
props: {
|
|
11
|
+
freshdesk,
|
|
12
|
+
companyId: {
|
|
13
|
+
propDefinition: [
|
|
14
|
+
freshdesk,
|
|
15
|
+
"companyId",
|
|
16
|
+
],
|
|
17
|
+
description: "ID of the company to which this ticket belongs",
|
|
18
|
+
},
|
|
19
|
+
email: {
|
|
20
|
+
propDefinition: [
|
|
21
|
+
freshdesk,
|
|
22
|
+
"contactEmail",
|
|
23
|
+
({ companyId }) => ({
|
|
24
|
+
companyId,
|
|
25
|
+
}),
|
|
26
|
+
],
|
|
27
|
+
description: "Email address of the requester.",
|
|
28
|
+
optional: true,
|
|
29
|
+
},
|
|
30
|
+
priority: {
|
|
31
|
+
propDefinition: [
|
|
32
|
+
freshdesk,
|
|
33
|
+
"ticketPriority",
|
|
34
|
+
],
|
|
35
|
+
default: 1,
|
|
36
|
+
},
|
|
37
|
+
description: {
|
|
38
|
+
type: "string",
|
|
39
|
+
label: "Description",
|
|
40
|
+
description: "HTML content of the ticket.",
|
|
41
|
+
optional: true,
|
|
42
|
+
},
|
|
43
|
+
descriptionText: {
|
|
44
|
+
type: "string",
|
|
45
|
+
label: "Description text",
|
|
46
|
+
description: "Content of the ticket in plain text.",
|
|
47
|
+
optional: true,
|
|
48
|
+
},
|
|
49
|
+
phone: {
|
|
50
|
+
type: "string",
|
|
51
|
+
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.",
|
|
59
|
+
optional: true,
|
|
60
|
+
},
|
|
61
|
+
status: {
|
|
62
|
+
propDefinition: [
|
|
63
|
+
freshdesk,
|
|
64
|
+
"ticketStatus",
|
|
65
|
+
],
|
|
66
|
+
default: 2,
|
|
67
|
+
optional: true,
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
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({
|
|
82
|
+
$,
|
|
83
|
+
data,
|
|
84
|
+
});
|
|
85
|
+
response && $.export("$summary", "Ticket successfully created");
|
|
86
|
+
return response;
|
|
87
|
+
},
|
|
88
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import freshdesk from "../../freshdesk.app.mjs";
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
key: "freshdesk-get-ticket",
|
|
5
|
+
name: "Get Ticket Details",
|
|
6
|
+
description: "Get a Ticket. [See docs here](https://developers.freshdesk.com/api/#tickets)",
|
|
7
|
+
version: "0.0.1",
|
|
8
|
+
type: "action",
|
|
9
|
+
props: {
|
|
10
|
+
freshdesk,
|
|
11
|
+
id: {
|
|
12
|
+
type: "string",
|
|
13
|
+
label: "Ticket ID",
|
|
14
|
+
description: "Ticket ID.",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
async run({ $ }) {
|
|
18
|
+
const response = await this.freshdesk.getTicket({
|
|
19
|
+
$,
|
|
20
|
+
id: this.id,
|
|
21
|
+
});
|
|
22
|
+
response && $.export("$summary", "Successfully found ticket");
|
|
23
|
+
return response;
|
|
24
|
+
},
|
|
25
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// legacy_hash_id: a_A6i5zz
|
|
2
|
+
import { axios } from "@pipedream/platform";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
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",
|
|
9
|
+
type: "action",
|
|
10
|
+
props: {
|
|
11
|
+
freshdesk: {
|
|
12
|
+
type: "app",
|
|
13
|
+
app: "freshdesk",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
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: "",
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
HTTP_PROTOCOL: "https://",
|
|
3
|
+
BASE_PATH: "/api",
|
|
4
|
+
VERSION_PATH: "/v2",
|
|
5
|
+
PAGE_SIZE: 100,
|
|
6
|
+
retriableStatusCodes: [
|
|
7
|
+
408,
|
|
8
|
+
429,
|
|
9
|
+
500,
|
|
10
|
+
],
|
|
11
|
+
DB_LAST_DATE_CHECK: "DB_LAST_DATE_CHECK",
|
|
12
|
+
TICKET_STATUS: [
|
|
13
|
+
{
|
|
14
|
+
label: "Open",
|
|
15
|
+
value: 2,
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
label: "Pending",
|
|
19
|
+
value: 3,
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
label: "Resolved",
|
|
23
|
+
value: 4,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
label: "Closed",
|
|
27
|
+
value: 5,
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
TICKET_PRIORITY: [
|
|
31
|
+
{
|
|
32
|
+
label: "Low",
|
|
33
|
+
value: 1,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
label: "Medium",
|
|
37
|
+
value: 2,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
label: "High",
|
|
41
|
+
value: 3,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
label: "Urgent",
|
|
45
|
+
value: 4,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
};
|
package/common/utils.mjs
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const removeNullEntries = (obj) =>
|
|
2
|
+
obj && Object.entries(obj).reduce((acc, [
|
|
3
|
+
key,
|
|
4
|
+
value,
|
|
5
|
+
]) => {
|
|
6
|
+
const isNumber = typeof value === "number";
|
|
7
|
+
const isBoolean = typeof value === "boolean";
|
|
8
|
+
const isNotEmpyString = typeof value === "string" && value.trim() !== "";
|
|
9
|
+
const isNotEmptyArray = Array.isArray(value) && value.length;
|
|
10
|
+
const isNotEmptyObject =
|
|
11
|
+
typeof value === "object" &&
|
|
12
|
+
value !== null &&
|
|
13
|
+
!Array.isArray(value) &&
|
|
14
|
+
Object.keys(value).length !== 0;
|
|
15
|
+
isNotEmptyObject && (value = removeNullEntries(value));
|
|
16
|
+
return ((value || value === false) &&
|
|
17
|
+
(isNotEmpyString || isNotEmptyArray || isNotEmptyObject || isBoolean || isNumber))
|
|
18
|
+
? {
|
|
19
|
+
...acc,
|
|
20
|
+
[key]: value,
|
|
21
|
+
}
|
|
22
|
+
: acc;
|
|
23
|
+
}, {});
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
removeNullEntries,
|
|
27
|
+
};
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import constants from "./common/constants.mjs";
|
|
2
|
+
import {
|
|
3
|
+
axios, ConfigurationError,
|
|
4
|
+
} from "@pipedream/platform";
|
|
5
|
+
import retry from "async-retry";
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
type: "app",
|
|
9
|
+
app: "freshdesk",
|
|
10
|
+
propDefinitions: {
|
|
11
|
+
companyId: {
|
|
12
|
+
type: "integer",
|
|
13
|
+
label: "Company ID",
|
|
14
|
+
description: "The ID of the company",
|
|
15
|
+
async options() {
|
|
16
|
+
const response = await this.getCompanies();
|
|
17
|
+
return response.map((project) => ({
|
|
18
|
+
label: project.name,
|
|
19
|
+
value: project.id,
|
|
20
|
+
}));
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
ticketStatus: {
|
|
24
|
+
type: "integer",
|
|
25
|
+
label: "Status",
|
|
26
|
+
description: "Status of the ticket.",
|
|
27
|
+
options() {
|
|
28
|
+
return constants.TICKET_STATUS;
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
ticketPriority: {
|
|
32
|
+
type: "integer",
|
|
33
|
+
label: "Priority",
|
|
34
|
+
description: "Priority of the ticket.",
|
|
35
|
+
options() {
|
|
36
|
+
return constants.TICKET_PRIORITY;
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
contactEmail: {
|
|
40
|
+
type: "string",
|
|
41
|
+
label: "Email",
|
|
42
|
+
description: "Contact Email.",
|
|
43
|
+
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
|
+
}));
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
methods: {
|
|
54
|
+
setLastDateChecked(db, value) {
|
|
55
|
+
db && db.set(constants.DB_LAST_DATE_CHECK, value);
|
|
56
|
+
},
|
|
57
|
+
getLastDateChecked(db) {
|
|
58
|
+
return db && db.get(constants.DB_LAST_DATE_CHECK);
|
|
59
|
+
},
|
|
60
|
+
base64Encode(data) {
|
|
61
|
+
return Buffer.from(data).toString("base64");
|
|
62
|
+
},
|
|
63
|
+
_getHeaders() {
|
|
64
|
+
return {
|
|
65
|
+
"Authorization": "Basic " + this.base64Encode(this.$auth.api_key + ":X"),
|
|
66
|
+
"Content-Type": "application/json;charset=utf-8",
|
|
67
|
+
};
|
|
68
|
+
},
|
|
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);
|
|
97
|
+
},
|
|
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);
|
|
120
|
+
},
|
|
121
|
+
async *filterTickets(params) {
|
|
122
|
+
let loadedData = 0;
|
|
123
|
+
do {
|
|
124
|
+
const response = await this.searchTickets(params);
|
|
125
|
+
|
|
126
|
+
if (!response || response.results.length === 0) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
loadedData += response.results.length;
|
|
130
|
+
for (const ticket of response.results) {
|
|
131
|
+
yield ticket;
|
|
132
|
+
}
|
|
133
|
+
if (loadedData >= response.total) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
params.page += 1;
|
|
137
|
+
} while (true);
|
|
138
|
+
},
|
|
139
|
+
async *filterContacts(params) {
|
|
140
|
+
let loadedData = 0;
|
|
141
|
+
do {
|
|
142
|
+
const response = await this.searchContacts(params);
|
|
143
|
+
|
|
144
|
+
if (!response || response.results.length === 0) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
loadedData += response.results.length;
|
|
148
|
+
for (const ticket of response.results) {
|
|
149
|
+
yield ticket;
|
|
150
|
+
}
|
|
151
|
+
if (loadedData >= response.total) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
params.page += 1;
|
|
155
|
+
} while (true);
|
|
156
|
+
},
|
|
157
|
+
async createCompany({
|
|
158
|
+
$, payload: data,
|
|
159
|
+
}) {
|
|
160
|
+
return this._makeRequest({
|
|
161
|
+
$,
|
|
162
|
+
path: "/companies",
|
|
163
|
+
data,
|
|
164
|
+
method: "post",
|
|
165
|
+
});
|
|
166
|
+
},
|
|
167
|
+
async getCompanies($ = undefined) {
|
|
168
|
+
return this._makeRequest({
|
|
169
|
+
$,
|
|
170
|
+
path: "/contacts",
|
|
171
|
+
});
|
|
172
|
+
},
|
|
173
|
+
async getContacts($ = undefined) {
|
|
174
|
+
return this._makeRequest({
|
|
175
|
+
$,
|
|
176
|
+
path: "/companies",
|
|
177
|
+
});
|
|
178
|
+
},
|
|
179
|
+
async createContact({
|
|
180
|
+
$, data,
|
|
181
|
+
}) {
|
|
182
|
+
return this._makeRequest({
|
|
183
|
+
$,
|
|
184
|
+
path: "/contacts",
|
|
185
|
+
data,
|
|
186
|
+
method: "post",
|
|
187
|
+
});
|
|
188
|
+
},
|
|
189
|
+
async createTicket({
|
|
190
|
+
$, data,
|
|
191
|
+
}) {
|
|
192
|
+
return this._makeRequest({
|
|
193
|
+
$,
|
|
194
|
+
path: "/tickets",
|
|
195
|
+
data,
|
|
196
|
+
method: "post",
|
|
197
|
+
});
|
|
198
|
+
},
|
|
199
|
+
async getTicket({
|
|
200
|
+
$, id,
|
|
201
|
+
}) {
|
|
202
|
+
return this._makeRequest({
|
|
203
|
+
$,
|
|
204
|
+
path: `/tickets/${id}`,
|
|
205
|
+
});
|
|
206
|
+
},
|
|
207
|
+
async searchTickets(params, $ = undefined) {
|
|
208
|
+
return this._makeRequest({
|
|
209
|
+
$,
|
|
210
|
+
path: "/search/tickets",
|
|
211
|
+
params,
|
|
212
|
+
});
|
|
213
|
+
},
|
|
214
|
+
async searchContacts(params, $ = undefined) {
|
|
215
|
+
return this._makeRequest({
|
|
216
|
+
$,
|
|
217
|
+
path: "/search/contacts",
|
|
218
|
+
params,
|
|
219
|
+
});
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pipedream/freshdesk",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Pipedream Freshdesk Components",
|
|
5
|
+
"main": "freshdesk.app.mjs",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"pipedream",
|
|
8
|
+
"freshdesk"
|
|
9
|
+
],
|
|
10
|
+
"homepage": "https://pipedream.com/apps/freshdesk",
|
|
11
|
+
"author": "Pipedream <support@pipedream.com> (https://pipedream.com/)",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"access": "public"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@pipedream/platform": "^0.9.0",
|
|
18
|
+
"async-retry": "^1.3.3",
|
|
19
|
+
"moment": "2.29.2"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import freshdesk from "../../freshdesk.app.mjs";
|
|
2
|
+
import moment from "moment";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
key: "freshdesk-new-contact",
|
|
6
|
+
name: "New Contact",
|
|
7
|
+
description: "Emit new notifications when a new contact is created",
|
|
8
|
+
version: "0.0.1",
|
|
9
|
+
type: "source",
|
|
10
|
+
props: {
|
|
11
|
+
freshdesk,
|
|
12
|
+
timer: {
|
|
13
|
+
label: "Polling interval",
|
|
14
|
+
description: "Pipedream will poll Harvest API on this schedule",
|
|
15
|
+
type: "$.interface.timer",
|
|
16
|
+
default: {
|
|
17
|
+
intervalSeconds: 60 * 15,
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
db: "$.service.db",
|
|
21
|
+
},
|
|
22
|
+
dedupe: "unique",
|
|
23
|
+
async run() {
|
|
24
|
+
const data = [];
|
|
25
|
+
let lastDateChecked = this.freshdesk.getLastDateChecked(this.db);
|
|
26
|
+
if (!lastDateChecked) {
|
|
27
|
+
lastDateChecked = new Date().toISOString();
|
|
28
|
+
this.freshdesk.setLastDateChecked(this.db, lastDateChecked);
|
|
29
|
+
}
|
|
30
|
+
const formatedDate = lastDateChecked.substr(0, (lastDateChecked + "T").indexOf("T"));
|
|
31
|
+
const contacts = await this.freshdesk.filterContacts({
|
|
32
|
+
query: `"created_at:>'${formatedDate}'"`,
|
|
33
|
+
page: 1,
|
|
34
|
+
});
|
|
35
|
+
for await (const contact of contacts) {
|
|
36
|
+
data.push(contact);
|
|
37
|
+
}
|
|
38
|
+
data && data.reverse().forEach((contact) => {
|
|
39
|
+
this.freshdesk.setLastDateChecked(this.db, contact.created_at);
|
|
40
|
+
if (moment(contact.created_at).isAfter(lastDateChecked)) {
|
|
41
|
+
this.$emit(contact,
|
|
42
|
+
{
|
|
43
|
+
id: contact.id,
|
|
44
|
+
summary: `Contact name: ${contact.name}`,
|
|
45
|
+
ts: Date.parse(contact.created_at),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
},
|
|
50
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import freshdesk from "../../freshdesk.app.mjs";
|
|
2
|
+
import moment from "moment";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
key: "freshdesk-new-ticket",
|
|
6
|
+
name: "New Ticket",
|
|
7
|
+
description: "Emit new notifications when a new ticket is created",
|
|
8
|
+
version: "0.0.1",
|
|
9
|
+
type: "source",
|
|
10
|
+
props: {
|
|
11
|
+
freshdesk,
|
|
12
|
+
timer: {
|
|
13
|
+
label: "Polling interval",
|
|
14
|
+
description: "Pipedream will poll Harvest API on this schedule",
|
|
15
|
+
type: "$.interface.timer",
|
|
16
|
+
default: {
|
|
17
|
+
intervalSeconds: 60 * 15,
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
db: "$.service.db",
|
|
21
|
+
},
|
|
22
|
+
dedupe: "unique",
|
|
23
|
+
async run() {
|
|
24
|
+
const data = [];
|
|
25
|
+
let lastDateChecked = this.freshdesk.getLastDateChecked(this.db);
|
|
26
|
+
if (!lastDateChecked) {
|
|
27
|
+
lastDateChecked = new Date().toISOString();
|
|
28
|
+
this.freshdesk.setLastDateChecked(this.db, lastDateChecked);
|
|
29
|
+
}
|
|
30
|
+
const formatedDate = lastDateChecked.substr(0, (lastDateChecked + "T").indexOf("T"));
|
|
31
|
+
const tickets = await this.freshdesk.filterTickets({
|
|
32
|
+
query: `"created_at:>'${formatedDate}'"`,
|
|
33
|
+
page: 1,
|
|
34
|
+
});
|
|
35
|
+
for await (const ticket of tickets) {
|
|
36
|
+
data.push(ticket);
|
|
37
|
+
}
|
|
38
|
+
data && data.reverse().forEach((ticket) => {
|
|
39
|
+
this.freshdesk.setLastDateChecked(this.db, ticket.created_at);
|
|
40
|
+
if (moment(ticket.created_at).isAfter(lastDateChecked)) {
|
|
41
|
+
this.$emit(ticket,
|
|
42
|
+
{
|
|
43
|
+
id: ticket.id,
|
|
44
|
+
summary: `Ticket number: ${ticket.id}`,
|
|
45
|
+
ts: Date.parse(ticket.created_at)
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
},
|
|
50
|
+
};
|