@friggframework/api-module-pipedrive 1.0.1-v1-alpha.5 → 2.1.0-canary.56.2dc58f9.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.md +10 -3
- package/README.md +3 -2
- package/defaultConfig.json +9 -7
- package/dist/api.d.ts +59 -0
- package/dist/api.js +160 -0
- package/dist/definition.d.ts +4 -0
- package/dist/definition.js +79 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +9 -0
- package/package.json +31 -21
- package/.eslintrc.json +0 -3
- package/CHANGELOG.md +0 -171
- package/api.js +0 -117
- package/index.js +0 -13
- package/jest-setup.js +0 -2
- package/jest-teardown.js +0 -2
- package/jest.config.js +0 -20
- package/manager.js +0 -193
- package/manager.test.js +0 -26
- package/mocks/activities/createActivity.js +0 -172
- package/mocks/activities/deleteActivity.js +0 -3
- package/mocks/activities/listActivities.js +0 -1538
- package/mocks/activities/updateActivity.js +0 -172
- package/mocks/apiMock.js +0 -28
- package/mocks/deals/listDeals.js +0 -236
- package/models/credential.js +0 -21
- package/models/entity.js +0 -9
- package/test/Api.test.js +0 -157
- package/test/Manager.test.js +0 -138
package/api.js
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
const { get, OAuth2Requester } = require('@friggframework/core');
|
|
2
|
-
|
|
3
|
-
class Api extends OAuth2Requester {
|
|
4
|
-
constructor(params) {
|
|
5
|
-
super(params);
|
|
6
|
-
|
|
7
|
-
this.access_token = get(params, 'access_token', null);
|
|
8
|
-
this.refresh_token = get(params, 'refresh_token', null);
|
|
9
|
-
this.companyDomain = get(params, 'companyDomain', null);
|
|
10
|
-
this.baseURL = () => `${this.companyDomain}/api`;
|
|
11
|
-
|
|
12
|
-
this.client_id = process.env.PIPEDRIVE_CLIENT_ID;
|
|
13
|
-
this.client_secret = process.env.PIPEDRIVE_CLIENT_SECRET;
|
|
14
|
-
this.redirect_uri = `${process.env.REDIRECT_URI}/pipedrive`;
|
|
15
|
-
this.scopes = process.env.PIPEDRIVE_SCOPES;
|
|
16
|
-
|
|
17
|
-
this.URLs = {
|
|
18
|
-
activities: '/v1/activities',
|
|
19
|
-
activityFields: '/v1/activityFields',
|
|
20
|
-
activityById: (activityId) => `/v1/activities/${activityId}`,
|
|
21
|
-
getUser: '/v1/users/me',
|
|
22
|
-
users: '/v1/users',
|
|
23
|
-
deals: '/v1/deals',
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
this.authorizationUri = encodeURI(
|
|
27
|
-
`https://oauth.pipedrive.com/oauth/authorize?client_id=${this.client_id}&redirect_uri=${this.redirect_uri}&response_type=code&scope=${this.scopes}`
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
this.tokenUri = 'https://oauth.pipedrive.com/oauth/token';
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
async setTokens(params) {
|
|
34
|
-
await this.setCompanyDomain(params.api_domain);
|
|
35
|
-
return super.setTokens(params);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async setCompanyDomain(companyDomain) {
|
|
39
|
-
this.companyDomain = companyDomain;
|
|
40
|
-
}
|
|
41
|
-
// ************************** Deals **********************************
|
|
42
|
-
async listDeals() {
|
|
43
|
-
const options = {
|
|
44
|
-
url: this.baseURL() + this.URLs.deals,
|
|
45
|
-
};
|
|
46
|
-
const res = await this._get(options);
|
|
47
|
-
return res;
|
|
48
|
-
}
|
|
49
|
-
// ************************** Activities **********************************
|
|
50
|
-
async listActivityFields() {
|
|
51
|
-
const options = {
|
|
52
|
-
url: this.baseURL() + this.URLs.activityFields,
|
|
53
|
-
};
|
|
54
|
-
const res = await this._get(options);
|
|
55
|
-
return res;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
async listActivities(params) {
|
|
59
|
-
const options = {
|
|
60
|
-
url: this.baseURL() + this.URLs.activities,
|
|
61
|
-
};
|
|
62
|
-
if (params.query) {
|
|
63
|
-
options.query = params.query;
|
|
64
|
-
}
|
|
65
|
-
const res = await this._get(options);
|
|
66
|
-
return res;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async deleteActivity(activityId) {
|
|
70
|
-
const options = {
|
|
71
|
-
url: this.baseURL() + this.URLs.activityById(activityId),
|
|
72
|
-
};
|
|
73
|
-
const res = await this._delete(options);
|
|
74
|
-
return res;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
async updateActivity(activityId, task) {
|
|
78
|
-
const options = {
|
|
79
|
-
url: this.baseURL() + this.URLs.activityById(activityId),
|
|
80
|
-
body: task,
|
|
81
|
-
};
|
|
82
|
-
const res = await this._patch(options);
|
|
83
|
-
return res;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
async createActivity(params) {
|
|
87
|
-
const dealId = get(params, 'dealId', null);
|
|
88
|
-
const subject = get(params, 'subject');
|
|
89
|
-
const type = get(params, 'type');
|
|
90
|
-
const options = {
|
|
91
|
-
url: this.baseURL() + this.URLs.activities,
|
|
92
|
-
body: { ...params },
|
|
93
|
-
headers: {
|
|
94
|
-
'Content-Type': 'application/json',
|
|
95
|
-
},
|
|
96
|
-
};
|
|
97
|
-
const res = await this._post(options);
|
|
98
|
-
return res;
|
|
99
|
-
}
|
|
100
|
-
// ************************** Users **********************************
|
|
101
|
-
async getUser() {
|
|
102
|
-
const options = {
|
|
103
|
-
url: this.baseURL() + this.URLs.getUser,
|
|
104
|
-
};
|
|
105
|
-
const res = await this._get(options);
|
|
106
|
-
return res;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
async listUsers() {
|
|
110
|
-
const options = {
|
|
111
|
-
url: this.baseURL() + this.URLs.users,
|
|
112
|
-
};
|
|
113
|
-
const res = await this._get(options);
|
|
114
|
-
return res;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
module.exports = { Api };
|
package/index.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
const { Api } = require('./api');
|
|
2
|
-
const { Credential } = require('./models/credential');
|
|
3
|
-
const { Entity } = require('./models/entity');
|
|
4
|
-
const ModuleManager = require('./manager');
|
|
5
|
-
const Config = require('./defaultConfig');
|
|
6
|
-
|
|
7
|
-
module.exports = {
|
|
8
|
-
Api,
|
|
9
|
-
Credential,
|
|
10
|
-
Entity,
|
|
11
|
-
ModuleManager,
|
|
12
|
-
Config,
|
|
13
|
-
};
|
package/jest-setup.js
DELETED
package/jest-teardown.js
DELETED
package/jest.config.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* For a detailed explanation regarding each configuration property, visit:
|
|
3
|
-
* https://jestjs.io/docs/configuration
|
|
4
|
-
*/
|
|
5
|
-
module.exports = {
|
|
6
|
-
// preset: '@friggframework/test-environment',
|
|
7
|
-
coverageThreshold: {
|
|
8
|
-
global: {
|
|
9
|
-
statements: 13,
|
|
10
|
-
branches: 0,
|
|
11
|
-
functions: 1,
|
|
12
|
-
lines: 13,
|
|
13
|
-
},
|
|
14
|
-
},
|
|
15
|
-
// A path to a module which exports an async function that is triggered once before all test suites
|
|
16
|
-
globalSetup: './jest-setup.js',
|
|
17
|
-
|
|
18
|
-
// A path to a module which exports an async function that is triggered once after all test suites
|
|
19
|
-
globalTeardown: './jest-teardown.js',
|
|
20
|
-
};
|
package/manager.js
DELETED
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
const {
|
|
2
|
-
ModuleManager,
|
|
3
|
-
ModuleConstants,
|
|
4
|
-
flushDebugLog,
|
|
5
|
-
debug
|
|
6
|
-
} = require('@friggframework/core');
|
|
7
|
-
const {Api} = require('./api.js');
|
|
8
|
-
const {Entity} = require('./models/entity');
|
|
9
|
-
const {Credential} = require('./models/credential');
|
|
10
|
-
const Config = require('./defaultConfig.json');
|
|
11
|
-
|
|
12
|
-
class Manager extends ModuleManager {
|
|
13
|
-
static
|
|
14
|
-
Entity = Entity;
|
|
15
|
-
|
|
16
|
-
static
|
|
17
|
-
Credential = Credential;
|
|
18
|
-
|
|
19
|
-
constructor(params) {
|
|
20
|
-
super(params);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
static getName() {
|
|
24
|
-
return Config.name;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
static
|
|
28
|
-
async getInstance(params) {
|
|
29
|
-
const instance = new this(params);
|
|
30
|
-
|
|
31
|
-
const apiParams = {delegate: instance};
|
|
32
|
-
if (params.entityId) {
|
|
33
|
-
instance.entity = await instance.entityMO.get(params.entityId);
|
|
34
|
-
instance.credential = await instance.credentialMO.get(
|
|
35
|
-
instance.entity.credential
|
|
36
|
-
);
|
|
37
|
-
} else if (params.credentialId) {
|
|
38
|
-
instance.credential = await instance.credentialMO.get(
|
|
39
|
-
params.credentialId
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
if (instance.entity?.credential) {
|
|
43
|
-
apiParams.access_token = instance.credential.accessToken;
|
|
44
|
-
apiParams.refresh_token = instance.credential.refreshToken;
|
|
45
|
-
apiParams.companyDomain = instance.credential.companyDomain;
|
|
46
|
-
}
|
|
47
|
-
instance.api = await new Api(apiParams);
|
|
48
|
-
|
|
49
|
-
return instance;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async getAuthorizationRequirements(params) {
|
|
53
|
-
return {
|
|
54
|
-
url: this.api.authorizationUri,
|
|
55
|
-
type: ModuleConstants.authType.oauth2,
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async testAuth() {
|
|
60
|
-
let validAuth = false;
|
|
61
|
-
try {
|
|
62
|
-
if (await this.api.getUser()) validAuth = true;
|
|
63
|
-
} catch (e) {
|
|
64
|
-
await this.markCredentialsInvalid();
|
|
65
|
-
flushDebugLog(e);
|
|
66
|
-
}
|
|
67
|
-
return validAuth;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async processAuthorizationCallback(params) {
|
|
71
|
-
const code = get(params.data, 'code');
|
|
72
|
-
await this.api.getTokenFromCode(code);
|
|
73
|
-
await this.testAuth();
|
|
74
|
-
|
|
75
|
-
const userProfile = await this.api.getUser();
|
|
76
|
-
await this.findOrCreateEntity({
|
|
77
|
-
companyId: userProfile.data.company_id,
|
|
78
|
-
companyName: userProfile.data.company_name,
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
return {
|
|
82
|
-
credential_id: this.credential.id,
|
|
83
|
-
entity_id: this.entity.id,
|
|
84
|
-
type: Manager.getName(),
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
async findOrCreateEntity(params) {
|
|
89
|
-
const companyId = get(params, 'companyId');
|
|
90
|
-
const companyName = get(params, 'companyName');
|
|
91
|
-
|
|
92
|
-
const search = await this.entityMO.list({
|
|
93
|
-
user: this.userId,
|
|
94
|
-
externalId: companyId,
|
|
95
|
-
});
|
|
96
|
-
if (search.length === 0) {
|
|
97
|
-
// validate choices!!!
|
|
98
|
-
// create entity
|
|
99
|
-
const createObj = {
|
|
100
|
-
credential: this.credential.id,
|
|
101
|
-
user: this.userId,
|
|
102
|
-
name: companyName,
|
|
103
|
-
externalId: companyId,
|
|
104
|
-
};
|
|
105
|
-
this.entity = await this.entityMO.create(createObj);
|
|
106
|
-
} else if (search.length === 1) {
|
|
107
|
-
this.entity = search[0];
|
|
108
|
-
} else {
|
|
109
|
-
debug(
|
|
110
|
-
'Multiple entities found with the same Company ID:',
|
|
111
|
-
companyId
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return {
|
|
116
|
-
entity_id: this.entity.id,
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
async deauthorize() {
|
|
121
|
-
this.api = new Api();
|
|
122
|
-
|
|
123
|
-
const entity = await this.entityMO.getByUserId(this.userId);
|
|
124
|
-
if (entity.credential) {
|
|
125
|
-
await this.credentialMO.delete(entity.credential);
|
|
126
|
-
entity.credential = undefined;
|
|
127
|
-
await entity.save();
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
async receiveNotification(notifier, delegateString, object = null) {
|
|
132
|
-
if (notifier instanceof Api) {
|
|
133
|
-
if (delegateString === this.api.DLGT_TOKEN_UPDATE) {
|
|
134
|
-
const userProfile = await this.api.getUser();
|
|
135
|
-
const pipedriveUserId = userProfile.data.id;
|
|
136
|
-
const updatedToken = {
|
|
137
|
-
user: this.userId,
|
|
138
|
-
accessToken: this.api.access_token,
|
|
139
|
-
refreshToken: this.api.refresh_token,
|
|
140
|
-
accessTokenExpire: this.api.accessTokenExpire,
|
|
141
|
-
externalId: pipedriveUserId,
|
|
142
|
-
companyDomain: object.api_domain,
|
|
143
|
-
auth_is_valid: true,
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
if (!this.credential) {
|
|
147
|
-
let credentialSearch = await this.credentialMO.list({
|
|
148
|
-
externalId: pipedriveUserId,
|
|
149
|
-
});
|
|
150
|
-
if (credentialSearch.length === 0) {
|
|
151
|
-
this.credential = await this.credentialMO.create(
|
|
152
|
-
updatedToken
|
|
153
|
-
);
|
|
154
|
-
} else if (credentialSearch.length === 1) {
|
|
155
|
-
if (
|
|
156
|
-
credentialSearch[0].user.toString() ===
|
|
157
|
-
this.userId.toString()
|
|
158
|
-
) {
|
|
159
|
-
this.credential = await this.credentialMO.update(
|
|
160
|
-
credentialSearch[0],
|
|
161
|
-
updatedToken
|
|
162
|
-
);
|
|
163
|
-
} else {
|
|
164
|
-
debug(
|
|
165
|
-
'Somebody else already created a credential with the same User ID:',
|
|
166
|
-
pipedriveUserId
|
|
167
|
-
);
|
|
168
|
-
}
|
|
169
|
-
} else {
|
|
170
|
-
// Handling multiple credentials found with an error for the time being
|
|
171
|
-
debug(
|
|
172
|
-
'Multiple credentials found with the same User ID:',
|
|
173
|
-
pipedriveUserId
|
|
174
|
-
);
|
|
175
|
-
}
|
|
176
|
-
} else {
|
|
177
|
-
this.credential = await this.credentialMO.update(
|
|
178
|
-
this.credential,
|
|
179
|
-
updatedToken
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
if (delegateString === this.api.DLGT_TOKEN_DEAUTHORIZED) {
|
|
184
|
-
await this.deauthorize();
|
|
185
|
-
}
|
|
186
|
-
if (delegateString === this.api.DLGT_INVALID_AUTH) {
|
|
187
|
-
await this.markCredentialsInvalid();
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
module.exports = Manager;
|
package/manager.test.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
const Manager = require('./manager');
|
|
2
|
-
const mongoose = require('mongoose');
|
|
3
|
-
const config = require('./defaultConfig.json');
|
|
4
|
-
|
|
5
|
-
describe(`Should fully test the ${config.label} Manager`, () => {
|
|
6
|
-
let manager, userManager;
|
|
7
|
-
|
|
8
|
-
beforeAll(async () => {
|
|
9
|
-
await mongoose.connect(process.env.MONGO_URI);
|
|
10
|
-
manager = await Manager.getInstance({
|
|
11
|
-
userId: new mongoose.Types.ObjectId(),
|
|
12
|
-
});
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
afterAll(async () => {
|
|
16
|
-
await Manager.Credential.deleteMany();
|
|
17
|
-
await Manager.Entity.deleteMany();
|
|
18
|
-
await mongoose.disconnect();
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it('should return auth requirements', async () => {
|
|
22
|
-
const requirements = await manager.getAuthorizationRequirements();
|
|
23
|
-
expect(requirements).exists;
|
|
24
|
-
expect(requirements.type).toEqual('oauth2');
|
|
25
|
-
});
|
|
26
|
-
});
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
data: {
|
|
3
|
-
type: 'task',
|
|
4
|
-
id: 31,
|
|
5
|
-
attributes: {
|
|
6
|
-
action: 'email',
|
|
7
|
-
autoskipAt: null,
|
|
8
|
-
compiledSequenceTemplateHtml: null,
|
|
9
|
-
completed: false,
|
|
10
|
-
completedAt: null,
|
|
11
|
-
createdAt: '2021-11-06T02:52:48.000Z',
|
|
12
|
-
dueAt: '2021-11-06T02:52:48.000Z',
|
|
13
|
-
note: null,
|
|
14
|
-
opportunityAssociation: null,
|
|
15
|
-
scheduledAt: null,
|
|
16
|
-
state: 'incomplete',
|
|
17
|
-
stateChangedAt: null,
|
|
18
|
-
taskType: 'manual',
|
|
19
|
-
updatedAt: '2021-11-06T02:52:48.000Z',
|
|
20
|
-
},
|
|
21
|
-
relationships: {
|
|
22
|
-
account: {
|
|
23
|
-
data: {
|
|
24
|
-
type: 'account',
|
|
25
|
-
id: 1,
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
call: {
|
|
29
|
-
data: null,
|
|
30
|
-
},
|
|
31
|
-
calls: {
|
|
32
|
-
links: {
|
|
33
|
-
related:
|
|
34
|
-
'https://api.pipedrive.io/api/v2/calls?filter%5Btask%5D%5Bid%5D=31',
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
completer: {
|
|
38
|
-
data: null,
|
|
39
|
-
},
|
|
40
|
-
creator: {
|
|
41
|
-
data: {
|
|
42
|
-
type: 'user',
|
|
43
|
-
id: 1,
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
defaultPluginMapping: {
|
|
47
|
-
data: null,
|
|
48
|
-
},
|
|
49
|
-
mailing: {
|
|
50
|
-
data: null,
|
|
51
|
-
},
|
|
52
|
-
mailings: {
|
|
53
|
-
links: {
|
|
54
|
-
related:
|
|
55
|
-
'https://api.pipedrive.io/api/v2/mailings?filter%5Btask%5D%5Bid%5D=31',
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
opportunity: {
|
|
59
|
-
data: null,
|
|
60
|
-
},
|
|
61
|
-
owner: {
|
|
62
|
-
data: {
|
|
63
|
-
type: 'user',
|
|
64
|
-
id: 1,
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
prospect: {
|
|
68
|
-
data: null,
|
|
69
|
-
},
|
|
70
|
-
prospectAccount: {
|
|
71
|
-
data: null,
|
|
72
|
-
},
|
|
73
|
-
prospectContacts: {
|
|
74
|
-
data: [],
|
|
75
|
-
links: {
|
|
76
|
-
related:
|
|
77
|
-
'https://api.pipedrive.io/api/v2/emailAddresses?filter%5Btask%5D%5Bid%5D=31',
|
|
78
|
-
},
|
|
79
|
-
meta: {
|
|
80
|
-
count: 0,
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
prospectOwner: {
|
|
84
|
-
data: null,
|
|
85
|
-
},
|
|
86
|
-
prospectPhoneNumbers: {
|
|
87
|
-
data: [],
|
|
88
|
-
links: {
|
|
89
|
-
related:
|
|
90
|
-
'https://api.pipedrive.io/api/v2/phoneNumbers?filter%5Btask%5D%5Bid%5D=31',
|
|
91
|
-
},
|
|
92
|
-
meta: {
|
|
93
|
-
count: 0,
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
prospectStage: {
|
|
97
|
-
data: null,
|
|
98
|
-
},
|
|
99
|
-
sequence: {
|
|
100
|
-
data: null,
|
|
101
|
-
},
|
|
102
|
-
sequenceSequenceSteps: {
|
|
103
|
-
data: [],
|
|
104
|
-
links: {
|
|
105
|
-
related:
|
|
106
|
-
'https://api.pipedrive.io/api/v2/sequenceSteps?filter%5Btask%5D%5Bid%5D=31',
|
|
107
|
-
},
|
|
108
|
-
meta: {
|
|
109
|
-
count: 0,
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
sequenceState: {
|
|
113
|
-
data: null,
|
|
114
|
-
},
|
|
115
|
-
sequenceStateSequenceStep: {
|
|
116
|
-
data: null,
|
|
117
|
-
},
|
|
118
|
-
sequenceStateSequenceStepOverrides: {
|
|
119
|
-
data: [],
|
|
120
|
-
meta: {
|
|
121
|
-
count: 0,
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
sequenceStateStartingTemplate: {
|
|
125
|
-
data: null,
|
|
126
|
-
},
|
|
127
|
-
sequenceStep: {
|
|
128
|
-
data: null,
|
|
129
|
-
},
|
|
130
|
-
sequenceStepOverrideTemplates: {
|
|
131
|
-
data: [],
|
|
132
|
-
links: {
|
|
133
|
-
related:
|
|
134
|
-
'https://api.pipedrive.io/api/v2/templates?filter%5Btask%5D%5Bid%5D=31',
|
|
135
|
-
},
|
|
136
|
-
meta: {
|
|
137
|
-
count: 0,
|
|
138
|
-
},
|
|
139
|
-
},
|
|
140
|
-
sequenceTemplate: {
|
|
141
|
-
data: null,
|
|
142
|
-
},
|
|
143
|
-
sequenceTemplateTemplate: {
|
|
144
|
-
data: null,
|
|
145
|
-
},
|
|
146
|
-
subject: {
|
|
147
|
-
data: {
|
|
148
|
-
type: 'account',
|
|
149
|
-
id: 1,
|
|
150
|
-
},
|
|
151
|
-
},
|
|
152
|
-
taskPriority: {
|
|
153
|
-
data: {
|
|
154
|
-
type: 'taskPriority',
|
|
155
|
-
id: 3,
|
|
156
|
-
},
|
|
157
|
-
},
|
|
158
|
-
taskTheme: {
|
|
159
|
-
data: {
|
|
160
|
-
type: 'taskTheme',
|
|
161
|
-
id: 1,
|
|
162
|
-
},
|
|
163
|
-
},
|
|
164
|
-
template: {
|
|
165
|
-
data: null,
|
|
166
|
-
},
|
|
167
|
-
},
|
|
168
|
-
links: {
|
|
169
|
-
self: 'https://api.pipedrive.io/api/v2/tasks/31',
|
|
170
|
-
},
|
|
171
|
-
},
|
|
172
|
-
};
|