@friggframework/api-module-zoho-crm 2.0.0-next.5 → 2.0.0-next.7

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/dist/api.d.ts CHANGED
@@ -3,22 +3,12 @@ import { ZohoConfig, ZohoLocation, QueryParams, SearchParams, UsersResponse, Rol
3
3
  export declare class Api extends OAuth2Requester {
4
4
  URLs: Record<string, string | ((id: string) => string)>;
5
5
  location: ZohoLocation;
6
- accountsServer: string | null;
7
6
  private static readonly CONTACTS_DEFAULT_FIELDS;
8
7
  private static readonly LEADS_DEFAULT_FIELDS;
9
8
  private static readonly ACCOUNTS_DEFAULT_FIELDS;
10
9
  constructor(params: ZohoConfig);
11
10
  getAuthUri(): string;
12
- /**
13
- * Sets the datacenter location and updates URLs accordingly.
14
- * Note: tokenUri is only updated if accountsServer is not set.
15
- */
16
11
  setLocation(location: ZohoLocation): void;
17
- /**
18
- * Sets the accounts server URL for token operations.
19
- * Call this when accounts-server is provided in OAuth callback.
20
- */
21
- setAccountsServer(accountsServer: string): void;
22
12
  getTokenFromCode(code: string): Promise<TokenResponse>;
23
13
  _delete(options: any): Promise<any>;
24
14
  /**
@@ -97,6 +87,14 @@ export declare class Api extends OAuth2Requester {
97
87
  * @see https://www.zoho.com/crm/developer/docs/api/v8/notifications/enable.html
98
88
  */
99
89
  enableNotification(body: NotificationWatchConfig): Promise<NotificationResponse>;
90
+ /**
91
+ * Update/renew notification channel configuration
92
+ * Use this to extend the channel_expiry before it expires (max 7 days from now)
93
+ * @param body - Notification configuration with watch items to update
94
+ * @returns Promise<NotificationResponse> Response with updated channel details
95
+ * @see https://www.zoho.com/crm/developer/docs/api/v8/notifications/update.html
96
+ */
97
+ updateNotification(body: NotificationWatchConfig): Promise<NotificationResponse>;
100
98
  /**
101
99
  * Disable notification channels
102
100
  * @param channelIds - Array of channel IDs to disable
package/dist/api.js CHANGED
@@ -13,24 +13,30 @@ const LOCATION_CONFIG = {
13
13
  in: { accounts: 'https://accounts.zoho.in', api: 'https://www.zohoapis.in' },
14
14
  au: { accounts: 'https://accounts.zoho.com.au', api: 'https://www.zohoapis.com.au' },
15
15
  cn: { accounts: 'https://accounts.zoho.com.cn', api: 'https://www.zohoapis.com.cn' },
16
- ca: { accounts: 'https://accounts.zoho.ca', api: 'https://www.zohoapis.ca' },
16
+ ca: { accounts: 'https://accounts.zohocloud.ca', api: 'https://www.zohoapis.ca' },
17
17
  jp: { accounts: 'https://accounts.zoho.jp', api: 'https://www.zohoapis.jp' },
18
18
  sa: { accounts: 'https://accounts.zoho.sa', api: 'https://www.zohoapis.sa' },
19
19
  };
20
20
  const DEFAULT_LOCATION = 'us';
21
+ /**
22
+ * Formats datetime for Zoho API (removes milliseconds, converts Z to +00:00)
23
+ * Zoho expects format: 2019-05-02T15:00:00+05:30
24
+ */
25
+ function formatDateTimeForZoho(dateStr) {
26
+ if (!dateStr)
27
+ return dateStr;
28
+ return dateStr.replace(/\.\d{3}Z$/, '+00:00').replace(/Z$/, '+00:00');
29
+ }
21
30
  class Api extends core_1.OAuth2Requester {
22
31
  constructor(params) {
23
32
  super(params);
24
- this.accountsServer = (0, core_1.get)(params, 'accountsServer', null);
25
33
  this.location = (0, core_1.get)(params, 'location', DEFAULT_LOCATION);
26
34
  if (!LOCATION_CONFIG[this.location]) {
27
35
  this.location = DEFAULT_LOCATION;
28
36
  }
29
37
  const locationConfig = LOCATION_CONFIG[this.location];
30
38
  this.baseUrl = `${locationConfig.api}/crm/v8`;
31
- this.tokenUri = this.accountsServer
32
- ? `${this.accountsServer}/oauth/v2/token`
33
- : `${locationConfig.accounts}/oauth/v2/token`;
39
+ this.tokenUri = `${locationConfig.accounts}/oauth/v2/token`;
34
40
  this.authorizationUri = encodeURI(`${locationConfig.accounts}/oauth/v2/auth?scope=${this.scope}&client_id=${this.client_id}&redirect_uri=${this.redirect_uri}&response_type=code&access_type=offline`);
35
41
  this.access_token = (0, core_1.get)(params, 'access_token', null);
36
42
  this.refresh_token = (0, core_1.get)(params, 'refresh_token', null);
@@ -57,10 +63,6 @@ class Api extends core_1.OAuth2Requester {
57
63
  getAuthUri() {
58
64
  return this.authorizationUri;
59
65
  }
60
- /**
61
- * Sets the datacenter location and updates URLs accordingly.
62
- * Note: tokenUri is only updated if accountsServer is not set.
63
- */
64
66
  setLocation(location) {
65
67
  if (!LOCATION_CONFIG[location]) {
66
68
  throw new Error(`Invalid Zoho location: ${location}. Must be one of: ${Object.keys(LOCATION_CONFIG).join(', ')}`);
@@ -68,19 +70,9 @@ class Api extends core_1.OAuth2Requester {
68
70
  this.location = location;
69
71
  const locationConfig = LOCATION_CONFIG[location];
70
72
  this.baseUrl = `${locationConfig.api}/crm/v8`;
71
- if (!this.accountsServer) {
72
- this.tokenUri = `${locationConfig.accounts}/oauth/v2/token`;
73
- }
73
+ this.tokenUri = `${locationConfig.accounts}/oauth/v2/token`;
74
74
  this.authorizationUri = encodeURI(`${locationConfig.accounts}/oauth/v2/auth?scope=${this.scope}&client_id=${this.client_id}&redirect_uri=${this.redirect_uri}&response_type=code&access_type=offline`);
75
75
  }
76
- /**
77
- * Sets the accounts server URL for token operations.
78
- * Call this when accounts-server is provided in OAuth callback.
79
- */
80
- setAccountsServer(accountsServer) {
81
- this.accountsServer = accountsServer;
82
- this.tokenUri = `${accountsServer}/oauth/v2/token`;
83
- }
84
76
  async getTokenFromCode(code) {
85
77
  const formData = new FormData();
86
78
  formData.append('grant_type', 'authorization_code');
@@ -532,10 +524,60 @@ class Api extends core_1.OAuth2Requester {
532
524
  throw new Error(`watch[${index}].token must be 50 characters or less`);
533
525
  }
534
526
  });
527
+ const formattedBody = {
528
+ ...body,
529
+ watch: body.watch.map(item => ({
530
+ ...item,
531
+ ...(item.channel_expiry && { channel_expiry: formatDateTimeForZoho(item.channel_expiry) })
532
+ }))
533
+ };
535
534
  try {
536
535
  return await this._post({
537
536
  url: this.baseUrl + this.URLs.notificationsWatch,
538
- body: body,
537
+ body: formattedBody,
538
+ });
539
+ }
540
+ catch (error) {
541
+ throw error;
542
+ }
543
+ }
544
+ /**
545
+ * Update/renew notification channel configuration
546
+ * Use this to extend the channel_expiry before it expires (max 7 days from now)
547
+ * @param body - Notification configuration with watch items to update
548
+ * @returns Promise<NotificationResponse> Response with updated channel details
549
+ * @see https://www.zoho.com/crm/developer/docs/api/v8/notifications/update.html
550
+ */
551
+ async updateNotification(body) {
552
+ if (!body || !body.watch || !Array.isArray(body.watch)) {
553
+ throw new Error('Body must contain watch array');
554
+ }
555
+ // Validate each watch item
556
+ body.watch.forEach((item, index) => {
557
+ if (!item.channel_id) {
558
+ throw new Error(`watch[${index}].channel_id is required`);
559
+ }
560
+ if (!item.events || !Array.isArray(item.events) || item.events.length === 0) {
561
+ throw new Error(`watch[${index}].events must be a non-empty array`);
562
+ }
563
+ if (!item.notify_url) {
564
+ throw new Error(`watch[${index}].notify_url is required`);
565
+ }
566
+ if (item.token && item.token.length > 50) {
567
+ throw new Error(`watch[${index}].token must be 50 characters or less`);
568
+ }
569
+ });
570
+ const formattedBody = {
571
+ ...body,
572
+ watch: body.watch.map(item => ({
573
+ ...item,
574
+ ...(item.channel_expiry && { channel_expiry: formatDateTimeForZoho(item.channel_expiry) })
575
+ }))
576
+ };
577
+ try {
578
+ return await this._patch({
579
+ url: this.baseUrl + this.URLs.notificationsWatch,
580
+ body: formattedBody,
539
581
  });
540
582
  }
541
583
  catch (error) {
@@ -39,18 +39,14 @@ exports.Definition = {
39
39
  getToken: async function (api, params) {
40
40
  const code = (0, core_1.get)(params, 'code');
41
41
  const location = (0, core_1.get)(params, 'location', null);
42
- const accountsServer = (0, core_1.get)(params, 'accounts-server', null);
43
42
  if (location) {
44
43
  api.setLocation(location);
45
44
  }
46
- if (accountsServer) {
47
- api.setAccountsServer(accountsServer);
48
- }
49
45
  await api.getTokenFromCode(code);
50
46
  },
51
47
  apiPropertiesToPersist: {
52
48
  credential: ['access_token', 'refresh_token'],
53
- entity: ['location', 'accountsServer'],
49
+ entity: ['location'],
54
50
  },
55
51
  getCredentialDetails: async function (api, userId) {
56
52
  const response = await api.listUsers({ type: 'CurrentUser' });
@@ -68,7 +64,6 @@ exports.Definition = {
68
64
  details: {
69
65
  name: currentUser.email,
70
66
  location: api.location,
71
- accountsServer: api.accountsServer,
72
67
  },
73
68
  };
74
69
  },
package/dist/types.d.ts CHANGED
@@ -11,7 +11,6 @@ export interface ZohoConfig {
11
11
  access_token?: string | null;
12
12
  refresh_token?: string | null;
13
13
  location?: ZohoLocation;
14
- accountsServer?: string | null;
15
14
  }
16
15
  export interface PaginationInfo {
17
16
  per_page: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@friggframework/api-module-zoho-crm",
3
- "version": "2.0.0-next.5",
3
+ "version": "2.0.0-next.7",
4
4
  "prettier": "@friggframework/prettier-config",
5
5
  "description": "Zoho CRM API module that lets the Frigg Framework interact with Zoho CRM",
6
6
  "main": "dist/index.js",
@@ -36,5 +36,5 @@
36
36
  "publishConfig": {
37
37
  "access": "public"
38
38
  },
39
- "gitHead": "6976db7ea821bb6e15e171d51c3e1938b6c566f9"
39
+ "gitHead": "9b4b29bd95d682debc41a8d0c67ee756e8c151e0"
40
40
  }