pipedrive 22.3.1-rc.3 → 22.3.1-rc.4

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.md CHANGED
@@ -8,8 +8,18 @@ For public Changelog covering all changes done to Pipedrive’s API, webhooks an
8
8
 
9
9
  ## [Unreleased]
10
10
 
11
+ ## [22.3.1-rc.4] - 2024-02-12
12
+
11
13
  ## [22.3.1-rc.3] - 2024-01-08
12
- - Add `lead_id` as an acceptable body parameter for the `POST /v1/callLogs` endpoint
14
+ - Add TypeScript Support
15
+
16
+ ## [22.5.0] - 2024-02-02
17
+ ### Added
18
+ - Added documentation for new endpoint `/deals/{id}/participantsChangelog`.
19
+
20
+ ## [22.4.0] - 2024-01-05
21
+ ### Added
22
+ - Added documentation for `/meetings/userProviderLinks` endpoints
13
23
 
14
24
  ## [22.3.1-rc.2] - 2023-12-22
15
25
 
@@ -595,7 +605,8 @@ structure
595
605
  * Fixed `GET /goal/:id/results` error handling in case when there are no existing stages connected to specified goal
596
606
  * Fixed typo in lead example response (`crrency` to `currency`)
597
607
 
598
- [Unreleased]: https://github.com/pipedrive/api-docs/compare/v22.3.1-rc.3...HEAD
608
+ [Unreleased]: https://github.com/pipedrive/api-docs/compare/v22.3.1-rc.4...HEAD
609
+ [22.3.1-rc.4]: https://github.com/pipedrive/api-docs/compare/v22.3.1-rc.3...v22.3.1-rc.4
599
610
  [22.3.1-rc.3]: https://github.com/pipedrive/api-docs/compare/v22.4.0...v22.3.1-rc.3
600
611
  [22.4.0]: https://github.com/pipedrive/api-docs/compare/v22.3.0...v22.4.0
601
612
  [22.3.0]: https://github.com/pipedrive/api-docs/compare/v22.2.0...v22.3.0
package/README.md CHANGED
@@ -27,7 +27,7 @@ import { Configuration, DealsApi } from "pipedrive";
27
27
 
28
28
  const app = express();
29
29
 
30
- const PORT = 1800;
30
+ const PORT = 3000;
31
31
 
32
32
  // Configure Client with API key authorization
33
33
  const apiConfig = new Configuration({
@@ -41,7 +41,7 @@ app.listen(PORT, () => {
41
41
  app.get("/", async (req, res) => {
42
42
  const dealsApi = new DealsApi(apiConfig);
43
43
  const response = await dealsApi.getDeals();
44
- const { data: deals } = response.data;
44
+ const { data: deals } = response;
45
45
 
46
46
  res.send(deals);
47
47
  });
@@ -68,7 +68,7 @@ import { OAuth2Configuration, Configuration } from 'pipedrive';
68
68
  const oauth2 = new OAuth2Configuration({
69
69
  clientId: "clientId", // OAuth 2 Client ID
70
70
  clientSecret: "clientSecret", // OAuth 2 Client Secret
71
- redirectUri: 'redirectUri'; // OAuth 2 Redirection endpoint or Callback Uri
71
+ redirectUri: 'redirectUri' // OAuth 2 Redirection endpoint or Callback Uri
72
72
  });
73
73
 
74
74
  const apiConfig = new Configuration({
@@ -183,9 +183,9 @@ It then redirects back to the base endpoint for calling endpoints from the SDK.
183
183
  ```typescript
184
184
 
185
185
  import express from "express";
186
- import cookieParse from "cookie-parser";
187
- import cookeSession from "cookie-session";
188
186
  import { Configuration, DealsApi, OAuth2Configuration } from "pipedrive";
187
+ import cookieParser from "cookie-parser";
188
+ import cookieSession from "cookie-session";
189
189
 
190
190
  const app = express();
191
191
 
@@ -195,26 +195,21 @@ app.use(cookieSession({
195
195
  keys: ["key1"]
196
196
  }));
197
197
 
198
- const PORT = 1800;
198
+ const PORT = 3000;
199
199
 
200
200
 
201
201
  const oauth2 = new OAuth2Configuration({
202
- clientId: "clientId", // OAuth 2 Client ID
203
- clientSecret: "clientSecret", // OAuth 2 Client Secret
204
- redirectUri: 'redirectUri'; // OAuth 2 Redirection endpoint or Callback Uri
205
- });
206
-
207
- const apiConfig = new Configuration({
208
- accessToken: oauth2.getAccessToken,
209
- basePath: oauth2.basePath,
202
+ clientId: "clientId", // OAuth 2 Client ID
203
+ clientSecret: "clientSecret", // OAuth 2 Client Secret
204
+ redirectUri: 'redirectUri' // OAuth 2 Redirection endpoint or Callback Uri
210
205
  });
211
206
 
212
-
213
207
  app.listen(PORT, () => {
214
- console.log(`Listening on port ${PORT}`);
208
+ console.log(`Listening on port ${PORT}`);
215
209
  });
216
210
 
217
211
  app.get('/', async (req, res) => {
212
+ try {
218
213
  // method will handle return null if token is not available in the session
219
214
  const token = oauth2.updateToken(req.session?.accessToken);
220
215
 
@@ -232,19 +227,29 @@ app.get('/', async (req, res) => {
232
227
  // token is already set in the session
233
228
  // now make API calls as required
234
229
  // client will automatically refresh the token when it expires and call the token update callback
235
- const api = new DealsApi(apiClient);
230
+ const dealsApi = new DealsApi(apiConfig)
231
+
236
232
  const response = await dealsApi.getDeals();
237
- const { data: deals } = response.data;
233
+ const { data: deals } = response;
238
234
 
239
- res.send(deals);
235
+ return res.send(deals);
236
+ } catch (error){
237
+ console.error(error)
238
+ return res.status(500).send(error)
239
+ }
240
240
  });
241
241
 
242
242
  app.get('/callback', async (req, res) => {
243
- const authCode = req.query.code;
244
- const newAccessToken = await oauth2.authorize(authCode);
245
-
246
- req.session.accessToken = newAccessToken;
247
- res.redirect("/");
243
+ try {
244
+ const authCode = req.query.code as string;
245
+ const newAccessToken = await oauth2.authorize(authCode);
246
+
247
+ req.session.accessToken = newAccessToken;
248
+ return res.redirect("/");
249
+ }catch (error) {
250
+ console.error(error)
251
+ return res.status(500).send(error)
252
+ }
248
253
  });
249
254
 
250
255
  ```
package/base.ts CHANGED
@@ -45,8 +45,16 @@ export interface RequestArgs {
45
45
  * Axios interceptor to add the SDK version as a User-Agent header
46
46
  * */
47
47
  globalAxios.interceptors.request.use(function (config) {
48
- const version = require("../package.json").version;
48
+ let version;
49
+
50
+ try {
51
+ version = require('../package.json').version;
52
+ } catch (error) {
53
+ version = '22.x';
54
+ }
55
+
49
56
  config.headers['User-Agent'] = `Pipedrive-SDK-Javascript-${version}`;
57
+
50
58
  return config;
51
59
  });
52
60
 
package/configuration.ts CHANGED
@@ -206,7 +206,14 @@ export class OAuth2Configuration {
206
206
  }
207
207
 
208
208
  private getUserAgent = () => {
209
- const version = require("../package.json").version;
209
+ let version;
210
+
211
+ try {
212
+ version = require('../package.json').version;
213
+ } catch (error) {
214
+ version = '22.x';
215
+ }
216
+
210
217
  return `Pipedrive-SDK-Javascript-${version}`;
211
218
  };
212
219
 
package/dist/base.js CHANGED
@@ -30,7 +30,13 @@ exports.COLLECTION_FORMATS = {
30
30
  * Axios interceptor to add the SDK version as a User-Agent header
31
31
  * */
32
32
  axios_1.default.interceptors.request.use(function (config) {
33
- const version = require("../package.json").version;
33
+ let version;
34
+ try {
35
+ version = require('../package.json').version;
36
+ }
37
+ catch (error) {
38
+ version = '22.x';
39
+ }
34
40
  config.headers['User-Agent'] = `Pipedrive-SDK-Javascript-${version}`;
35
41
  return config;
36
42
  });
@@ -114,7 +114,13 @@ class OAuth2Configuration {
114
114
  return token;
115
115
  };
116
116
  this.getUserAgent = () => {
117
- const version = require("../package.json").version;
117
+ let version;
118
+ try {
119
+ version = require('../package.json').version;
120
+ }
121
+ catch (error) {
122
+ version = '22.x';
123
+ }
118
124
  return `Pipedrive-SDK-Javascript-${version}`;
119
125
  };
120
126
  this.validateParam = (params, key) => {
package/dist/esm/base.js CHANGED
@@ -27,7 +27,13 @@ export const COLLECTION_FORMATS = {
27
27
  * Axios interceptor to add the SDK version as a User-Agent header
28
28
  * */
29
29
  globalAxios.interceptors.request.use(function (config) {
30
- const version = require("../package.json").version;
30
+ let version;
31
+ try {
32
+ version = require('../package.json').version;
33
+ }
34
+ catch (error) {
35
+ version = '22.x';
36
+ }
31
37
  config.headers['User-Agent'] = `Pipedrive-SDK-Javascript-${version}`;
32
38
  return config;
33
39
  });
@@ -111,7 +111,13 @@ export class OAuth2Configuration {
111
111
  return token;
112
112
  };
113
113
  this.getUserAgent = () => {
114
- const version = require("../package.json").version;
114
+ let version;
115
+ try {
116
+ version = require('../package.json').version;
117
+ }
118
+ catch (error) {
119
+ version = '22.x';
120
+ }
115
121
  return `Pipedrive-SDK-Javascript-${version}`;
116
122
  };
117
123
  this.validateParam = (params, key) => {
@@ -7,7 +7,7 @@ Name | Type | Description | Notes
7
7
  **subscriptionUrl** | **String** | A full, valid, publicly accessible URL which determines where to send the notifications. Please note that you cannot use Pipedrive API endpoints as the `subscription_url` and the chosen URL must not redirect to another link. |
8
8
  **eventAction** | **String** | The type of action to receive notifications about. Wildcard will match all supported actions. |
9
9
  **eventObject** | **String** | The type of object to receive notifications about. Wildcard will match all supported objects. |
10
- **userId** | **Number** | The ID of the user that this webhook will be authorized with. You have the option to use a different user's `user_id`. If it is not set, the current user's `user_id` will be used. As each webhook event is checked against a users permissions, the webhook will only be sent if the user has access to the specified object(s). If you want to receive notifications for all events, please use a top-level admin user’s `user_id`. | [optional]
10
+ **userId** | **Number** | The ID of the user that this webhook will be authorized with. You have the option to use a different user's `user_id`. If it is not set, the current user's `user_id` will be used. As each webhook event is checked against a user's permissions, the webhook will only be sent if the user has access to the specified object(s). If you want to receive notifications for all events, please use a top-level admin user’s `user_id`. | [optional]
11
11
  **httpAuthUser** | **String** | The HTTP basic auth username of the subscription URL endpoint (if required) | [optional]
12
12
  **httpAuthPassword** | **String** | The HTTP basic auth password of the subscription URL endpoint (if required) | [optional]
13
13
  **version** | **String** | The webhook's version | [optional] [default to '1.0']
package/docs/BasicDeal.md CHANGED
@@ -4,6 +4,9 @@
4
4
 
5
5
  Name | Type | Description | Notes
6
6
  ------------ | ------------- | ------------- | -------------
7
+ **wonTime** | **String** | The optional date and time of changing the deal status as won in UTC. Format: YYYY-MM-DD HH:MM:SS. Can be set only when deal `status` is already Won. Can not be used together with `lost_time`. | [optional]
8
+ **lostTime** | **String** | The optional date and time of changing the deal status as lost in UTC. Format: YYYY-MM-DD HH:MM:SS. Can be set only when deal `status` is already Lost. Can not be used together with `won_time`. | [optional]
9
+ **closeTime** | **String** | The optional date and time of closing the deal in UTC. Format: YYYY-MM-DD HH:MM:SS. | [optional]
7
10
  **expectedCloseDate** | **Date** | The expected close date of the deal. In ISO 8601 format: YYYY-MM-DD. | [optional]
8
11
  **probability** | **Number** | The success probability percentage of the deal. Used/shown only when `deal_probability` for the pipeline of the deal is enabled. | [optional]
9
12
  **lostReason** | **String** | The optional message about why the deal was lost (to be used when status = lost) | [optional]
@@ -0,0 +1,12 @@
1
+ # Pipedrive.DealParticipantsChangelog
2
+
3
+ ## Properties
4
+
5
+ Name | Type | Description | Notes
6
+ ------------ | ------------- | ------------- | -------------
7
+ **actorUserId** | **Number** | The ID of the user | [optional]
8
+ **personId** | **Number** | The ID of the person | [optional]
9
+ **action** | **String** | Deal participant action type | [optional]
10
+ **time** | **String** | The deal participant action log time | [optional]
11
+
12
+
package/docs/DealsApi.md CHANGED
@@ -20,6 +20,7 @@ Method | HTTP request | Description
20
20
  [**getDealFollowers**](DealsApi.md#getDealFollowers) | **GET** /deals/{id}/followers | List followers of a deal
21
21
  [**getDealMailMessages**](DealsApi.md#getDealMailMessages) | **GET** /deals/{id}/mailMessages | List mail messages associated with a deal
22
22
  [**getDealParticipants**](DealsApi.md#getDealParticipants) | **GET** /deals/{id}/participants | List participants of a deal
23
+ [**getDealParticipantsChangelog**](DealsApi.md#getDealParticipantsChangelog) | **GET** /deals/{id}/participantsChangelog | List updates about participants of a deal
23
24
  [**getDealPersons**](DealsApi.md#getDealPersons) | **GET** /deals/{id}/persons | List all persons associated with a deal
24
25
  [**getDealProducts**](DealsApi.md#getDealProducts) | **GET** /deals/{id}/products | List products attached to a deal
25
26
  [**getDealUpdates**](DealsApi.md#getDealUpdates) | **GET** /deals/{id}/flow | List updates about a deal
@@ -933,6 +934,65 @@ Name | Type | Description | Notes
933
934
  - **Accept**: application/json
934
935
 
935
936
 
937
+ ## getDealParticipantsChangelog
938
+
939
+ > ParticipantsChangelog getDealParticipantsChangelog(id, opts)
940
+
941
+ List updates about participants of a deal
942
+
943
+ List updates about participants of a deal. This is a cursor-paginated endpoint. For more information, please refer to our documentation on <a href=\"https://pipedrive.readme.io/docs/core-api-concepts-pagination\" target=\"_blank\" rel=\"noopener noreferrer\">pagination</a>.
944
+
945
+ ### Example
946
+
947
+ ```javascript
948
+ import Pipedrive from 'pipedrive';
949
+ let apiClient = new Pipedrive.ApiClient();
950
+ // Configure API key authorization: api_key
951
+ let api_key = apiClient.authentications['api_key'];
952
+ api_key.apiKey = 'YOUR API KEY';
953
+ // Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
954
+ //api_key.apiKeyPrefix = 'Token';
955
+ // Configure OAuth2 access token for authorization: oauth2
956
+ let oauth2 = apiClient.authentications['oauth2'];
957
+ oauth2.accessToken = 'YOUR ACCESS TOKEN';
958
+
959
+ let apiInstance = new Pipedrive.DealsApi(apiClient);
960
+ let id = 56; // Number | The ID of the deal
961
+ let opts = {
962
+ 'limit': 56, // Number | Items shown per page
963
+ 'cursor': "cursor_example" // String | For pagination, the marker (an opaque string value) representing the first item on the next page
964
+ };
965
+ apiInstance.getDealParticipantsChangelog(id, opts).then((data) => {
966
+ console.log('API called successfully. Returned data: ' + data);
967
+ }, (error) => {
968
+ console.error(error);
969
+ });
970
+
971
+ ```
972
+
973
+ ### Parameters
974
+
975
+
976
+ Name | Type | Description | Notes
977
+ ------------- | ------------- | ------------- | -------------
978
+ **id** | **Number**| The ID of the deal |
979
+ **limit** | **Number**| Items shown per page | [optional]
980
+ **cursor** | **String**| For pagination, the marker (an opaque string value) representing the first item on the next page | [optional]
981
+
982
+ ### Return type
983
+
984
+ [**ParticipantsChangelog**](ParticipantsChangelog.md)
985
+
986
+ ### Authorization
987
+
988
+ [api_key](../README.md#api_key), [oauth2](../README.md#oauth2)
989
+
990
+ ### HTTP request headers
991
+
992
+ - **Content-Type**: Not defined
993
+ - **Accept**: application/json
994
+
995
+
936
996
  ## getDealPersons
937
997
 
938
998
  > ListPersonsResponse getDealPersons(id, opts)
package/docs/NewDeal.md CHANGED
@@ -15,6 +15,9 @@ Name | Type | Description | Notes
15
15
  **stageId** | **Number** | The ID of the stage this deal will be added to. Please note that a pipeline will be assigned automatically based on the `stage_id`. If omitted, the deal will be placed in the first stage of the default pipeline. | [optional]
16
16
  **status** | **String** | open = Open, won = Won, lost = Lost, deleted = Deleted. If omitted, status will be set to open. | [optional]
17
17
  **addTime** | **String** | The optional creation date & time of the deal in UTC. Requires admin user API token. Format: YYYY-MM-DD HH:MM:SS | [optional]
18
+ **wonTime** | **String** | The optional date and time of changing the deal status as won in UTC. Format: YYYY-MM-DD HH:MM:SS. Can be set only when deal `status` is already Won. Can not be used together with `lost_time`. | [optional]
19
+ **lostTime** | **String** | The optional date and time of changing the deal status as lost in UTC. Format: YYYY-MM-DD HH:MM:SS. Can be set only when deal `status` is already Lost. Can not be used together with `won_time`. | [optional]
20
+ **closeTime** | **String** | The optional date and time of closing the deal in UTC. Format: YYYY-MM-DD HH:MM:SS. | [optional]
18
21
  **expectedCloseDate** | **Date** | The expected close date of the deal. In ISO 8601 format: YYYY-MM-DD. | [optional]
19
22
  **probability** | **Number** | The success probability percentage of the deal. Used/shown only when `deal_probability` for the pipeline of the deal is enabled. | [optional]
20
23
  **lostReason** | **String** | The optional message about why the deal was lost (to be used when status = lost) | [optional]
@@ -0,0 +1,11 @@
1
+ # Pipedrive.ParticipantsChangelog
2
+
3
+ ## Properties
4
+
5
+ Name | Type | Description | Notes
6
+ ------------ | ------------- | ------------- | -------------
7
+ **success** | **Boolean** | If the request was successful or not | [optional]
8
+ **data** | [**[ParticipantsChangelogItem]**](ParticipantsChangelogItem.md) | The array of participant changelog | [optional]
9
+ **additionalData** | [**AdditionalData**](AdditionalData.md) | | [optional]
10
+
11
+
@@ -0,0 +1,12 @@
1
+ # Pipedrive.ParticipantsChangelogItem
2
+
3
+ ## Properties
4
+
5
+ Name | Type | Description | Notes
6
+ ------------ | ------------- | ------------- | -------------
7
+ **actorUserId** | **Number** | The ID of the user | [optional]
8
+ **personId** | **Number** | The ID of the person | [optional]
9
+ **action** | **String** | Deal participant action type | [optional]
10
+ **time** | **String** | The deal participant action log time | [optional]
11
+
12
+
@@ -14,6 +14,9 @@ Name | Type | Description | Notes
14
14
  **pipelineId** | **Number** | The ID of the pipeline this deal will be added to. By default, the deal will be added to the first stage of the specified pipeline. Please note that `pipeline_id` and `stage_id` should not be used together as `pipeline_id` will be ignored. | [optional]
15
15
  **stageId** | **Number** | The ID of the stage this deal will be added to. Please note that a pipeline will be assigned automatically based on the `stage_id`. | [optional]
16
16
  **status** | **String** | open = Open, won = Won, lost = Lost, deleted = Deleted. | [optional]
17
+ **wonTime** | **String** | The optional date and time of changing the deal status as won in UTC. Format: YYYY-MM-DD HH:MM:SS. Can be set only when deal `status` is already Won. Can not be used together with `lost_time`. | [optional]
18
+ **lostTime** | **String** | The optional date and time of changing the deal status as lost in UTC. Format: YYYY-MM-DD HH:MM:SS. Can be set only when deal `status` is already Lost. Can not be used together with `won_time`. | [optional]
19
+ **closeTime** | **String** | The optional date and time of closing the deal in UTC. Format: YYYY-MM-DD HH:MM:SS. | [optional]
17
20
  **expectedCloseDate** | **Date** | The expected close date of the deal. In ISO 8601 format: YYYY-MM-DD. | [optional]
18
21
  **probability** | **Number** | The success probability percentage of the deal. Used/shown only when `deal_probability` for the pipeline of the deal is enabled. | [optional]
19
22
  **lostReason** | **String** | The optional message about why the deal was lost (to be used when status = lost) | [optional]
package/migration.md ADDED
@@ -0,0 +1,309 @@
1
+ ### Breaking changes
2
+
3
+ - Suggested nodejs version is 18
4
+ - Function signatures have changed from the previous version of the sdk. Now each function takes a strongly typed root object that contains all the parameters needed such as id and request payload, where in the previous version those were seperate function params
5
+
6
+
7
+ Example functions change:
8
+
9
+ - Previous version:
10
+
11
+ ```
12
+
13
+ await dealsApi.addDeal({
14
+ title: 'My First Deal',
15
+ });
16
+
17
+ await dealsApi.updateDeal(1, {
18
+ title: 'Updated Title',
19
+ });
20
+
21
+
22
+ await api.getDeal(1);
23
+
24
+ ```
25
+
26
+ - New version:
27
+ ```
28
+ await dealsApi.addDeal({
29
+ AddDealRequest: {
30
+ title: 'My First Deal',
31
+ },
32
+ });
33
+
34
+ await dealsApi.updateDeal({
35
+ id: 1,
36
+ UpdateDealRequest: {
37
+ title: 'Updated Title',
38
+ },
39
+ });
40
+
41
+ await dealsApi.getDeal({
42
+ id : 1
43
+ })
44
+
45
+ await dealsApi.deleteDeal({
46
+ id : 1
47
+ })
48
+
49
+ ```
50
+
51
+ ## Installation
52
+
53
+ ```
54
+ npm i pipedrive@22.3.1-rc.3
55
+ ```
56
+
57
+ ## API Reference
58
+
59
+ The Pipedrive RESTful API Reference can be found at https://developers.pipedrive.com/docs/api/v1.
60
+ Pipedrive API’s core concepts for its usage can be found in our [Developer documentation](https://pipedrive.readme.io/docs/core-api-concepts-about-pipedrive-api).
61
+
62
+ ## How to use it?
63
+
64
+ ### With a pre-set API token
65
+
66
+ You can retrieve the api_token from your existing Pipedrive account’s settings page. A step-by-step guide is available [here](https://pipedrive.readme.io/docs/how-to-find-the-api-token).
67
+
68
+ ```typescript
69
+ import express from "express";
70
+ import { Configuration, DealsApi } from "pipedrive";
71
+
72
+ const app = express();
73
+
74
+ const PORT = 3000;
75
+
76
+ // Configure Client with API key authorization
77
+ const apiConfig = new Configuration({
78
+ apiKey: "YOUR_API_TOKEN_HERE",
79
+ });
80
+
81
+ app.listen(PORT, () => {
82
+ console.log(`Listening on port ${PORT}`);
83
+ });
84
+
85
+ app.get("/", async (req, res) => {
86
+ const dealsApi = new DealsApi(apiConfig);
87
+ const response = await dealsApi.getDeals();
88
+ const { data: deals } = response;
89
+
90
+ res.send(deals);
91
+ });
92
+ ```
93
+
94
+ ### With OAuth 2
95
+
96
+ If you would like to use an OAuth access token for making API calls, then make sure the API key described in the previous section is not set or is set to an empty string. If both API token and OAuth access token are set, then the API token takes precedence.
97
+
98
+ To set up authentication in the API client, you need the following information. You can receive the necessary client tokens through a Sandbox account (get it [here](https://developers.pipedrive.com/start-here)) and generate the tokens (detailed steps [here](https://pipedrive.readme.io/docs/marketplace-manager#section-how-to-get-your-client-id-and-client-secret)).
99
+
100
+ | Parameter | Description |
101
+ | ------------ | -------------------------------------------- |
102
+ | clientId | OAuth 2 Client ID |
103
+ | clientSecret | OAuth 2 Client Secret |
104
+ | redirectUri | OAuth 2 Redirection endpoint or Callback Uri |
105
+
106
+ Next, initialize the API client as follows:
107
+
108
+ ```typescript
109
+ import { OAuth2Configuration, Configuration } from 'pipedrive';
110
+
111
+ // Configuration parameters and credentials
112
+ const oauth2 = new OAuth2Configuration({
113
+ clientId: "clientId", // OAuth 2 Client ID
114
+ clientSecret: "clientSecret", // OAuth 2 Client Secret
115
+ redirectUri: 'redirectUri' // OAuth 2 Redirection endpoint or Callback Uri
116
+ });
117
+
118
+ const apiConfig = new Configuration({
119
+ accessToken: oauth2.getAccessToken,
120
+ basePath: oauth2.basePath,
121
+ });
122
+
123
+ ```
124
+
125
+ You must now authorize the client.
126
+
127
+ ### Authorizing your client
128
+
129
+ Your application must obtain user authorization before it can execute an endpoint call. The SDK uses OAuth 2.0 authorization to obtain a user's consent to perform an API request on the user's behalf. Details about how the OAuth2.0 flow works in Pipedrive, how long tokens are valid, and more, can be found [here](https://pipedrive.readme.io/docs/marketplace-oauth-authorization).
130
+
131
+ #### 1. Obtaining user consent
132
+
133
+ To obtain user's consent, you must redirect the user to the authorization page. The `authorizationUrl` returns the URL to the authorization page.
134
+
135
+ ```typescript
136
+ // open up the authUrl in the browser
137
+ const authUrl = oauth2.authorizationUrl;
138
+ ```
139
+
140
+ #### 2. Handle the OAuth server response
141
+
142
+ Once the user responds to the consent request, the OAuth 2.0 server responds to your application's access request by using the URL specified in the request.
143
+
144
+ If the user approves the request, the authorization code will be sent as the `code` query string:
145
+
146
+ ```
147
+ https://example.com/oauth/callback?code=XXXXXXXXXXXXXXXXXXXXXXXXX
148
+ ```
149
+
150
+ If the user does not approve the request, the response contains an `error` query string:
151
+
152
+ ```
153
+ https://example.com/oauth/callback?error=access_denied
154
+ ```
155
+
156
+ #### 3. Authorize the client using the code
157
+
158
+ After the server receives the code, it can exchange this for an _access token_. The access token is an object containing information for authorizing the client and refreshing the token itself. In the API client all the access token fields are held separately in the `OAuth2Configuration` class. Additionally access token expiration time as an `OAuth2Configuration.expiresAt` field is calculated. It is measured in the number of milliseconds elapsed since January 1, 1970 00:00:00 UTC.
159
+
160
+ ```typescript
161
+ const token = await oauth2.authorize(code);
162
+ ```
163
+
164
+ The Node.js SDK supports only promises. So, the authorize call returns a promise.
165
+
166
+ ### Refreshing token
167
+
168
+ Access tokens may expire after sometime, if it necessary you can do it manually.
169
+
170
+ ```typescript
171
+ const newToken = await oauth2.tokenRefresh();
172
+ ```
173
+
174
+ If the access token expires, the SDK will attempt to automatically refresh it before the next endpoint call which requires authentication.
175
+
176
+ ### Storing an access token for reuse
177
+
178
+ It is recommended that you store the access token for reuse.
179
+
180
+ This code snippet stores the access token in a session for an express application. It uses the [cookie-parser](https://www.npmjs.com/package/cookie-parser) and [cookie-session](https://www.npmjs.com/package/cookie-session) npm packages for storing the access token.
181
+
182
+ ```typescript
183
+ import express from "express";
184
+ import cookieParse from "cookie-parser";
185
+ import cookeSession from "cookie-session";
186
+ import { Configuration, DealsApi, OAuth2Configuration } from "pipedrive";
187
+
188
+ const app = express();
189
+
190
+ app.use(cookieParser());
191
+ app.use(cookieSession({
192
+ name: "session",
193
+ keys: ["key1"]
194
+ }));
195
+
196
+ ...
197
+
198
+ // store access token in the session
199
+ // note that this is only the access token field value not the whole token object
200
+ req.session.accessToken = await oauth.getAccessToken();
201
+ ```
202
+
203
+ However, since the SDK will attempt to automatically refresh the access token when it expires,
204
+ it is recommended that you register a **token update callback** to detect any change to the access token.
205
+
206
+ ```typescript
207
+ oauth2.onTokenUpdate = function (token) {
208
+ // getting the updated token
209
+ // here the token is an object, you can store the whole object or extract fields into separate values
210
+ req.session.token = token;
211
+ };
212
+ ```
213
+
214
+ The token update callback will be fired upon authorization as well as token refresh.
215
+
216
+ ### Complete example
217
+
218
+ This example demonstrates an express application (which uses [cookie-parser](https://www.npmjs.com/package/cookie-parser) and [cookie-session](https://www.npmjs.com/package/cookie-session)) for handling session persistence.
219
+
220
+ In this example, there are 2 endpoints. The base endpoint `'/'` first checks if the token is stored in the session.
221
+ If it is, API endpoints can be called using the corresponding SDK controllers.
222
+
223
+ However, if the token is not set in the session, then authorization URL is built and opened up.
224
+ The response comes back at the `'/callback'` endpoint, which uses the code to authorize the client and store the token in the session.
225
+ It then redirects back to the base endpoint for calling endpoints from the SDK.
226
+
227
+ ```typescript
228
+
229
+ import express from "express";
230
+ import { Configuration, DealsApi, OAuth2Configuration } from "pipedrive";
231
+ import cookieParser from "cookie-parser";
232
+ import cookieSession from "cookie-session";
233
+
234
+ const app = express();
235
+
236
+ app.use(cookieParser());
237
+ app.use(cookieSession({
238
+ name: "session",
239
+ keys: ["key1"]
240
+ }));
241
+
242
+ const PORT = 3000;
243
+
244
+
245
+ const oauth2 = new OAuth2Configuration({
246
+ clientId: "clientId", // OAuth 2 Client ID
247
+ clientSecret: "clientSecret", // OAuth 2 Client Secret
248
+ redirectUri: 'redirectUri' // OAuth 2 Redirection endpoint or Callback Uri
249
+ });
250
+
251
+ app.listen(PORT, () => {
252
+ console.log(`Listening on port ${PORT}`);
253
+ });
254
+
255
+ app.get('/', async (req, res) => {
256
+ try {
257
+ // method will handle return null if token is not available in the session
258
+ const token = oauth2.updateToken(req.session?.accessToken);
259
+
260
+ if (!token) {
261
+ const authUrl = oauth2.authorizationUrl;
262
+ return res.redirect(authUrl);
263
+ }
264
+
265
+
266
+ const apiConfig = new Configuration({
267
+ accessToken: oauth2.getAccessToken,
268
+ basePath: oauth2.basePath,
269
+ });
270
+
271
+ const dealsApi = new DealsApi(apiConfig)
272
+
273
+ const response = await dealsApi.getDeals();
274
+ const { data: deals } = response;
275
+
276
+ return res.send(deals);
277
+ } catch (error){
278
+ console.error(error)
279
+ return res.status(500).send(error)
280
+ }
281
+ });
282
+
283
+ app.get('/callback', async (req, res) => {
284
+ try {
285
+ const authCode = req.query.code as string;
286
+ const newAccessToken = await oauth2.authorize(authCode);
287
+
288
+ req.session.accessToken = newAccessToken;
289
+ return res.redirect("/");
290
+ }catch (error) {
291
+ console.error(error)
292
+ return res.status(500).send(error)
293
+ }
294
+ });
295
+
296
+ ```
297
+
298
+
299
+
300
+
301
+
302
+
303
+
304
+
305
+
306
+
307
+
308
+
309
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pipedrive",
3
- "version": "22.3.1-rc.3",
3
+ "version": "22.3.1-rc.4",
4
4
  "description": "Pipedrive REST client for NodeJS",
5
5
  "license": "MIT",
6
6
  "homepage": "https://developers.pipedrive.com",