@dereekb/zoho 13.0.6 → 13.0.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/index.cjs.js +2164 -231
- package/index.esm.js +2143 -232
- package/nestjs/LICENSE +21 -0
- package/nestjs/README.md +11 -0
- package/nestjs/docs/configuration.md +165 -0
- package/nestjs/docs/crm-getting-started.md +296 -0
- package/nestjs/index.cjs.js +653 -5
- package/nestjs/index.esm.js +647 -7
- package/nestjs/package.json +3 -3
- package/nestjs/src/lib/crm/crm.api.d.ts +46 -0
- package/nestjs/src/lib/crm/crm.config.d.ts +16 -1
- package/nestjs/src/lib/crm/crm.module.d.ts +77 -8
- package/nestjs/src/lib/index.d.ts +2 -0
- package/nestjs/src/lib/recruit/recruit.api.d.ts +50 -0
- package/nestjs/src/lib/recruit/recruit.config.d.ts +16 -1
- package/nestjs/src/lib/recruit/recruit.module.d.ts +77 -8
- package/nestjs/src/lib/sign/index.d.ts +3 -0
- package/nestjs/src/lib/sign/sign.api.d.ts +54 -0
- package/nestjs/src/lib/sign/sign.config.d.ts +10 -0
- package/nestjs/src/lib/sign/sign.module.d.ts +94 -0
- package/package.json +2 -2
- package/src/lib/accounts/accounts.api.d.ts +149 -3
- package/src/lib/accounts/accounts.factory.d.ts +73 -6
- package/src/lib/crm/crm.api.d.ts +599 -62
- package/src/lib/crm/crm.api.notes.d.ts +46 -3
- package/src/lib/crm/crm.api.tags.d.ts +65 -2
- package/src/lib/crm/crm.config.d.ts +30 -0
- package/src/lib/crm/crm.criteria.d.ts +60 -3
- package/src/lib/crm/crm.error.api.d.ts +42 -0
- package/src/lib/crm/crm.factory.d.ts +39 -3
- package/src/lib/crm/crm.notes.d.ts +36 -0
- package/src/lib/crm/crm.tags.d.ts +3 -0
- package/src/lib/index.d.ts +1 -0
- package/src/lib/recruit/recruit.api.candidates.d.ts +44 -3
- package/src/lib/recruit/recruit.api.d.ts +719 -57
- package/src/lib/recruit/recruit.api.notes.d.ts +140 -0
- package/src/lib/recruit/recruit.api.tags.d.ts +122 -14
- package/src/lib/recruit/recruit.config.d.ts +30 -0
- package/src/lib/recruit/recruit.criteria.d.ts +55 -3
- package/src/lib/recruit/recruit.error.api.d.ts +39 -0
- package/src/lib/recruit/recruit.factory.d.ts +39 -3
- package/src/lib/recruit/recruit.notes.d.ts +21 -0
- package/src/lib/recruit/recruit.tags.d.ts +3 -0
- package/src/lib/shared/criteria.d.ts +95 -11
- package/src/lib/shared/criteria.util.d.ts +19 -4
- package/src/lib/sign/index.d.ts +6 -0
- package/src/lib/sign/sign.api.d.ts +397 -0
- package/src/lib/sign/sign.api.page.d.ts +109 -0
- package/src/lib/sign/sign.config.d.ts +24 -0
- package/src/lib/sign/sign.d.ts +225 -0
- package/src/lib/sign/sign.error.api.d.ts +7 -0
- package/src/lib/sign/sign.factory.d.ts +58 -0
- package/src/lib/zoho.api.page.d.ts +41 -10
- package/src/lib/zoho.config.d.ts +24 -9
- package/src/lib/zoho.limit.d.ts +41 -9
- package/src/lib/zoho.type.d.ts +24 -8
package/nestjs/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Hapier Creative LLC.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/nestjs/README.md
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Zoho NestJS Configuration
|
|
2
|
+
|
|
3
|
+
This document describes the environment variables used by `@dereekb/zoho/nestjs` and shows how to wire up the Zoho CRM and Zoho Recruit modules in a NestJS application.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Environment Variables
|
|
8
|
+
|
|
9
|
+
Configuration is read from a NestJS `ConfigService` (typically backed by process environment variables). Two naming conventions are supported for every credential: a **shared** variable that applies to all services, and a **service-specific** variable that takes precedence when present.
|
|
10
|
+
|
|
11
|
+
### Variable Naming Convention
|
|
12
|
+
|
|
13
|
+
The service-specific prefix is `ZOHO_<SERVICE>_`, where `<SERVICE>` is the uppercase `serviceAccessTokenKey` (e.g. `CRM` or `RECRUIT`). For each credential the lookup order is:
|
|
14
|
+
|
|
15
|
+
1. `ZOHO_<SERVICE>_<KEY>` – service-specific (highest priority)
|
|
16
|
+
2. `ZOHO_<KEY>` – shared fallback
|
|
17
|
+
|
|
18
|
+
### Zoho Accounts (OAuth) Variables
|
|
19
|
+
|
|
20
|
+
These credentials are shared across all Zoho services and are used to obtain access tokens via the Zoho Accounts API.
|
|
21
|
+
|
|
22
|
+
| Variable | Service-specific (CRM) | Service-specific (Recruit) | Description |
|
|
23
|
+
|---|---|---|---|
|
|
24
|
+
| `ZOHO_ACCOUNTS_URL` | `ZOHO_CRM_ACCOUNTS_URL` | `ZOHO_RECRUIT_ACCOUNTS_URL` | Base URL of the Zoho Accounts API (e.g. `https://accounts.zoho.com`) |
|
|
25
|
+
| `ZOHO_ACCOUNTS_REFRESH_TOKEN` | `ZOHO_CRM_ACCOUNTS_REFRESH_TOKEN` | `ZOHO_RECRUIT_ACCOUNTS_REFRESH_TOKEN` | OAuth refresh token for the service client |
|
|
26
|
+
| `ZOHO_ACCOUNTS_CLIENT_ID` | `ZOHO_CRM_ACCOUNTS_CLIENT_ID` | `ZOHO_RECRUIT_ACCOUNTS_CLIENT_ID` | OAuth client ID for the service client |
|
|
27
|
+
| `ZOHO_ACCOUNTS_CLIENT_SECRET` | `ZOHO_CRM_ACCOUNTS_CLIENT_SECRET` | `ZOHO_RECRUIT_ACCOUNTS_CLIENT_SECRET` | OAuth client secret for the service client |
|
|
28
|
+
|
|
29
|
+
### Zoho API URL Variables
|
|
30
|
+
|
|
31
|
+
Each service also needs to know the base URL of its own REST API.
|
|
32
|
+
|
|
33
|
+
| Variable | Description |
|
|
34
|
+
|---|---|
|
|
35
|
+
| `ZOHO_CRM_API_URL` | Base URL of the Zoho CRM API (e.g. `https://www.zohoapis.com/crm/v2`) |
|
|
36
|
+
| `ZOHO_RECRUIT_API_URL` | Base URL of the Zoho Recruit API (e.g. `https://recruit.zoho.com/recruit/v2`) |
|
|
37
|
+
|
|
38
|
+
> **Note:** The shared fallback `ZOHO_API_URL` can also be used if both services share the same base URL.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Setting Up Zoho CRM
|
|
43
|
+
|
|
44
|
+
`appZohoCrmModuleMetadata()` generates the NestJS `ModuleMetadata` needed to bootstrap the Zoho CRM integration. It registers `ZohoCrmApi` and `ZohoAccountsApi` as providers and reads credentials from the environment automatically.
|
|
45
|
+
|
|
46
|
+
### Required environment variables
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
ZOHO_ACCOUNTS_URL=https://accounts.zoho.com
|
|
50
|
+
ZOHO_ACCOUNTS_REFRESH_TOKEN=<your-refresh-token>
|
|
51
|
+
ZOHO_ACCOUNTS_CLIENT_ID=<your-client-id>
|
|
52
|
+
ZOHO_ACCOUNTS_CLIENT_SECRET=<your-client-secret>
|
|
53
|
+
ZOHO_CRM_API_URL=https://www.zohoapis.com/crm/v2
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Example
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import {
|
|
60
|
+
ZohoAccountsAccessTokenCacheService,
|
|
61
|
+
appZohoCrmModuleMetadata
|
|
62
|
+
} from '@dereekb/zoho/nestjs';
|
|
63
|
+
import { Module } from '@nestjs/common';
|
|
64
|
+
|
|
65
|
+
// 1. Create a dependency module that provides ZohoAccountsAccessTokenCacheService.
|
|
66
|
+
// Here we use a simple in-memory cache. For production, consider also layering
|
|
67
|
+
// in a file-based or Redis-backed cache.
|
|
68
|
+
@Module({
|
|
69
|
+
providers: [
|
|
70
|
+
{
|
|
71
|
+
provide: ZohoAccountsAccessTokenCacheService,
|
|
72
|
+
useFactory: () => memoryZohoAccountsAccessTokenCacheService()
|
|
73
|
+
}
|
|
74
|
+
],
|
|
75
|
+
exports: [ZohoAccountsAccessTokenCacheService]
|
|
76
|
+
})
|
|
77
|
+
export class AppZohoCrmDependencyModule {}
|
|
78
|
+
|
|
79
|
+
// 2. Declare the CRM module using the helper. Pass the dependency module so that
|
|
80
|
+
// ZohoAccountsAccessTokenCacheService is available to the internal providers.
|
|
81
|
+
@Module(appZohoCrmModuleMetadata({ dependencyModule: AppZohoCrmDependencyModule }))
|
|
82
|
+
export class AppZohoCrmModule {}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`ZohoCrmApi` is exported by `AppZohoCrmModule` and can be injected into any service that imports it.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Setting Up Zoho Recruit
|
|
90
|
+
|
|
91
|
+
`appZohoRecruitModuleMetadata()` mirrors the CRM helper for the Zoho Recruit API.
|
|
92
|
+
|
|
93
|
+
### Required environment variables
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
ZOHO_ACCOUNTS_URL=https://accounts.zoho.com
|
|
97
|
+
ZOHO_ACCOUNTS_REFRESH_TOKEN=<your-refresh-token>
|
|
98
|
+
ZOHO_ACCOUNTS_CLIENT_ID=<your-client-id>
|
|
99
|
+
ZOHO_ACCOUNTS_CLIENT_SECRET=<your-client-secret>
|
|
100
|
+
ZOHO_RECRUIT_API_URL=https://recruit.zoho.com/recruit/v2
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Or, if Recruit uses its own dedicated OAuth client, use the service-specific variables:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
ZOHO_RECRUIT_ACCOUNTS_URL=https://accounts.zoho.com
|
|
107
|
+
ZOHO_RECRUIT_ACCOUNTS_REFRESH_TOKEN=<recruit-refresh-token>
|
|
108
|
+
ZOHO_RECRUIT_ACCOUNTS_CLIENT_ID=<recruit-client-id>
|
|
109
|
+
ZOHO_RECRUIT_ACCOUNTS_CLIENT_SECRET=<recruit-client-secret>
|
|
110
|
+
ZOHO_RECRUIT_API_URL=https://recruit.zoho.com/recruit/v2
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Example
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import {
|
|
117
|
+
ZohoAccountsAccessTokenCacheService,
|
|
118
|
+
appZohoRecruitModuleMetadata
|
|
119
|
+
} from '@dereekb/zoho/nestjs';
|
|
120
|
+
import { Module } from '@nestjs/common';
|
|
121
|
+
|
|
122
|
+
@Module({
|
|
123
|
+
providers: [
|
|
124
|
+
{
|
|
125
|
+
provide: ZohoAccountsAccessTokenCacheService,
|
|
126
|
+
useFactory: () => memoryZohoAccountsAccessTokenCacheService()
|
|
127
|
+
}
|
|
128
|
+
],
|
|
129
|
+
exports: [ZohoAccountsAccessTokenCacheService]
|
|
130
|
+
})
|
|
131
|
+
export class AppZohoRecruitDependencyModule {}
|
|
132
|
+
|
|
133
|
+
@Module(appZohoRecruitModuleMetadata({ dependencyModule: AppZohoRecruitDependencyModule }))
|
|
134
|
+
export class AppZohoRecruitModule {}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
`ZohoRecruitApi` is exported by `AppZohoRecruitModule` and can be injected into any service that imports it.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Using Both CRM and Recruit Together
|
|
142
|
+
|
|
143
|
+
If your application uses both APIs, you can share or separate the token cache depending on whether the same OAuth client is used:
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
// Shared dependency module (single OAuth client for both services)
|
|
147
|
+
@Module({
|
|
148
|
+
providers: [
|
|
149
|
+
{
|
|
150
|
+
provide: ZohoAccountsAccessTokenCacheService,
|
|
151
|
+
useFactory: () => memoryZohoAccountsAccessTokenCacheService()
|
|
152
|
+
}
|
|
153
|
+
],
|
|
154
|
+
exports: [ZohoAccountsAccessTokenCacheService]
|
|
155
|
+
})
|
|
156
|
+
export class AppZohoDependencyModule {}
|
|
157
|
+
|
|
158
|
+
@Module(appZohoCrmModuleMetadata({ dependencyModule: AppZohoDependencyModule }))
|
|
159
|
+
export class AppZohoCrmModule {}
|
|
160
|
+
|
|
161
|
+
@Module(appZohoRecruitModuleMetadata({ dependencyModule: AppZohoDependencyModule }))
|
|
162
|
+
export class AppZohoRecruitModule {}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
When different OAuth clients are used for CRM and Recruit, set the service-specific environment variables (e.g. `ZOHO_CRM_ACCOUNTS_CLIENT_ID` vs `ZOHO_RECRUIT_ACCOUNTS_CLIENT_ID`) and use separate dependency modules with their own cache instances.
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
# Zoho CRM - Getting Started with NestJS
|
|
2
|
+
|
|
3
|
+
This guide walks through setting up Zoho CRM in a new NestJS project using `@dereekb/zoho` and `@dereekb/zoho-nestjs`.
|
|
4
|
+
|
|
5
|
+
## 1. Install Dependencies
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @dereekb/zoho @dereekb/zoho-nestjs
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 2. Module & Authentication Setup
|
|
12
|
+
|
|
13
|
+
The NestJS integration wires up OAuth authentication, token caching, rate limiting, and the CRM client in a single module declaration. All you need to provide is:
|
|
14
|
+
|
|
15
|
+
- Environment variables for OAuth credentials and API URLs
|
|
16
|
+
- A `ZohoAccountsAccessTokenCacheService` implementation for token persistence
|
|
17
|
+
|
|
18
|
+
### Environment Variables
|
|
19
|
+
|
|
20
|
+
```env
|
|
21
|
+
# OAuth credentials (shared across all Zoho services)
|
|
22
|
+
ZOHO_ACCOUNTS_URL=https://accounts.zoho.com
|
|
23
|
+
ZOHO_ACCOUNTS_REFRESH_TOKEN=<your-refresh-token>
|
|
24
|
+
ZOHO_ACCOUNTS_CLIENT_ID=<your-client-id>
|
|
25
|
+
ZOHO_ACCOUNTS_CLIENT_SECRET=<your-client-secret>
|
|
26
|
+
|
|
27
|
+
# CRM API endpoint
|
|
28
|
+
ZOHO_API_URL=https://www.zohoapis.com
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
> You can also use CRM-specific env vars (e.g. `ZOHO_CRM_ACCOUNTS_REFRESH_TOKEN`) to override the shared values. This is useful when your app integrates multiple Zoho services (CRM, Recruit, Sign) with different credentials.
|
|
32
|
+
|
|
33
|
+
### Token Cache
|
|
34
|
+
|
|
35
|
+
You must provide a `ZohoAccountsAccessTokenCacheService` that persists OAuth access tokens. The library includes three built-in implementations:
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import {
|
|
39
|
+
memoryZohoAccountsAccessTokenCacheService,
|
|
40
|
+
fileZohoAccountsAccessTokenCacheService,
|
|
41
|
+
mergeZohoAccountsAccessTokenCacheServices
|
|
42
|
+
} from '@dereekb/zoho-nestjs';
|
|
43
|
+
|
|
44
|
+
// In-memory only (good for testing)
|
|
45
|
+
const cacheService = memoryZohoAccountsAccessTokenCacheService();
|
|
46
|
+
|
|
47
|
+
// File-based (good for local development, persists across restarts)
|
|
48
|
+
const cacheService = fileZohoAccountsAccessTokenCacheService('.tmp/zoho-tokens.json');
|
|
49
|
+
|
|
50
|
+
// Merged (fault-tolerant, tries multiple sources in sequence)
|
|
51
|
+
const cacheService = mergeZohoAccountsAccessTokenCacheServices([cacheA, cacheB]);
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Module Declaration
|
|
55
|
+
|
|
56
|
+
Create a dependency module that provides the token cache, then use `appZohoCrmModuleMetadata()` to wire everything together:
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { Module } from '@nestjs/common';
|
|
60
|
+
import {
|
|
61
|
+
ZohoAccountsAccessTokenCacheService,
|
|
62
|
+
ZohoCrmApi,
|
|
63
|
+
appZohoCrmModuleMetadata,
|
|
64
|
+
fileZohoAccountsAccessTokenCacheService
|
|
65
|
+
} from '@dereekb/zoho-nestjs';
|
|
66
|
+
|
|
67
|
+
@Module({
|
|
68
|
+
providers: [
|
|
69
|
+
{
|
|
70
|
+
provide: ZohoAccountsAccessTokenCacheService,
|
|
71
|
+
useValue: fileZohoAccountsAccessTokenCacheService()
|
|
72
|
+
}
|
|
73
|
+
],
|
|
74
|
+
exports: [ZohoAccountsAccessTokenCacheService]
|
|
75
|
+
})
|
|
76
|
+
export class ZohoCrmDependencyModule {}
|
|
77
|
+
|
|
78
|
+
@Module(appZohoCrmModuleMetadata({ dependencyModule: ZohoCrmDependencyModule }))
|
|
79
|
+
export class AppZohoCrmModule {}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`appZohoCrmModuleMetadata()` automatically registers:
|
|
83
|
+
- `ZohoAccountsServiceConfig` (reads OAuth env vars via `ConfigService`)
|
|
84
|
+
- `ZohoAccountsApi` (manages token refresh and caching)
|
|
85
|
+
- `ZohoCrmServiceConfig` (reads CRM API URL from env vars)
|
|
86
|
+
- `ZohoCrmApi` (the injectable service you'll use everywhere)
|
|
87
|
+
|
|
88
|
+
Import `AppZohoCrmModule` in your app module and inject `ZohoCrmApi` wherever needed.
|
|
89
|
+
|
|
90
|
+
### Non-NestJS Setup
|
|
91
|
+
|
|
92
|
+
If you're not using NestJS, create the accounts context and CRM client manually:
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
import { zohoAccountsFactory, zohoCrmFactory } from '@dereekb/zoho';
|
|
96
|
+
|
|
97
|
+
const accounts = zohoAccountsFactory({})({
|
|
98
|
+
apiUrl: 'us',
|
|
99
|
+
clientId: 'your-client-id',
|
|
100
|
+
clientSecret: 'your-client-secret',
|
|
101
|
+
refreshToken: 'your-refresh-token',
|
|
102
|
+
accessTokenCache: myOptionalCache
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const crm = zohoCrmFactory({
|
|
106
|
+
accountsContext: accounts.accountsContext
|
|
107
|
+
})({
|
|
108
|
+
apiUrl: 'production' // or 'sandbox'
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
const { crmContext } = crm;
|
|
112
|
+
// Pass crmContext to all zohoCrmXxx() functions
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## 3. CRUD Operations
|
|
116
|
+
|
|
117
|
+
`ZohoCrmApi` exposes all CRM operations as getter properties. Each returns a pre-bound async function.
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
import { Injectable } from '@nestjs/common';
|
|
121
|
+
import { ZohoCrmApi } from '@dereekb/zoho-nestjs';
|
|
122
|
+
|
|
123
|
+
@Injectable()
|
|
124
|
+
export class ContactsService {
|
|
125
|
+
constructor(private readonly zohoCrmApi: ZohoCrmApi) {}
|
|
126
|
+
|
|
127
|
+
async createContact() {
|
|
128
|
+
return this.zohoCrmApi.insertRecord({
|
|
129
|
+
module: 'Contacts',
|
|
130
|
+
data: { First_Name: 'Jane', Last_Name: 'Doe', Email: 'jane@example.com' }
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async getContact(id: string) {
|
|
135
|
+
return this.zohoCrmApi.getRecordById({ module: 'Contacts', id });
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async updateContact(id: string, lastName: string) {
|
|
139
|
+
return this.zohoCrmApi.updateRecord({
|
|
140
|
+
module: 'Contacts',
|
|
141
|
+
data: { id, Last_Name: lastName }
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async deleteContact(id: string) {
|
|
146
|
+
return this.zohoCrmApi.deleteRecord({ module: 'Contacts', ids: id });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
When passing a **single record**, the function returns the result directly or throws on error. When passing an **array** (up to 100 records), it returns `{ successItems, errorItems }`.
|
|
152
|
+
|
|
153
|
+
## 4. Search with Criteria
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
// Simple criteria (all AND-joined):
|
|
157
|
+
const results = await this.zohoCrmApi.searchRecords({
|
|
158
|
+
module: 'Contacts',
|
|
159
|
+
criteria: [
|
|
160
|
+
{ field: 'Last_Name', filter: 'starts_with', value: 'Sm' },
|
|
161
|
+
{ field: 'Email', filter: 'contains', value: 'example.com' }
|
|
162
|
+
]
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// OR logic using a criteria tree:
|
|
166
|
+
const results = await this.zohoCrmApi.searchRecords({
|
|
167
|
+
module: 'Contacts',
|
|
168
|
+
criteria: {
|
|
169
|
+
or: [
|
|
170
|
+
[{ field: 'Status', filter: 'equals', value: 'Active' }],
|
|
171
|
+
[{ field: 'Status', filter: 'equals', value: 'Pending' }]
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Filter operators: `equals`, `starts_with`, `contains`. Maximum 10 criteria entries per search.
|
|
178
|
+
|
|
179
|
+
## 5. Pagination
|
|
180
|
+
|
|
181
|
+
All list/search results return `{ data, info: { more_records, page, per_page } }`. Use page factories for automatic chaining:
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
const fetchPage = this.zohoCrmApi.searchRecordsPageFactory({
|
|
185
|
+
module: 'Contacts',
|
|
186
|
+
criteria: [{ field: 'Last_Name', filter: 'starts_with', value: 'A' }]
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
const page1 = await fetchPage.fetchNext();
|
|
190
|
+
const page2 = await page1.fetchNext(); // auto-follows pagination
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## 6. Notes, Tags, and Attachments
|
|
194
|
+
|
|
195
|
+
### Notes
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
// Create notes for a record
|
|
199
|
+
await this.zohoCrmApi.createNotesForRecord({
|
|
200
|
+
module: 'Contacts',
|
|
201
|
+
id: contactId,
|
|
202
|
+
notes: [{ Note_Title: 'Call Log', Note_Content: 'Left voicemail' }]
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// Get notes (paginated)
|
|
206
|
+
const notes = await this.zohoCrmApi.getNotesForRecord({
|
|
207
|
+
module: 'Contacts',
|
|
208
|
+
id: contactId,
|
|
209
|
+
fields: 'Note_Title,Note_Content'
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// Delete notes
|
|
213
|
+
await this.zohoCrmApi.deleteNotes({ ids: [noteId1, noteId2] });
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Tags
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
// Create tags for a module
|
|
220
|
+
await this.zohoCrmApi.createTagsForModule({
|
|
221
|
+
module: 'Contacts',
|
|
222
|
+
tags: [{ name: 'VIP' }, { name: 'Hot Lead', color_code: '#FF0000' }]
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
// Add/remove tags on records
|
|
226
|
+
await this.zohoCrmApi.addTagsToRecords({
|
|
227
|
+
module: 'Contacts',
|
|
228
|
+
ids: [contactId],
|
|
229
|
+
tag_names: ['VIP']
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
await this.zohoCrmApi.removeTagsFromRecords({
|
|
233
|
+
module: 'Contacts',
|
|
234
|
+
ids: [contactId],
|
|
235
|
+
tag_names: ['VIP']
|
|
236
|
+
});
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Attachments
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
// Upload (max 20MB)
|
|
243
|
+
await this.zohoCrmApi.uploadAttachmentForRecord({
|
|
244
|
+
module: 'Contacts',
|
|
245
|
+
id: contactId,
|
|
246
|
+
file: myFile,
|
|
247
|
+
attachmentCategoryName: 'Resume'
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
// List attachments
|
|
251
|
+
const attachments = await this.zohoCrmApi.getAttachmentsForRecord({
|
|
252
|
+
module: 'Contacts',
|
|
253
|
+
id: contactId
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
// Download
|
|
257
|
+
const fileResponse = await this.zohoCrmApi.downloadAttachmentForRecord({
|
|
258
|
+
module: 'Contacts',
|
|
259
|
+
id: contactId,
|
|
260
|
+
attachment_id: attachmentId
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// Delete
|
|
264
|
+
await this.zohoCrmApi.deleteAttachmentFromRecord({
|
|
265
|
+
module: 'Contacts',
|
|
266
|
+
id: contactId,
|
|
267
|
+
attachment_id: attachmentId
|
|
268
|
+
});
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## 7. Serverless Functions
|
|
272
|
+
|
|
273
|
+
Call Zoho CRM serverless functions via REST API:
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
// OAuth-authenticated call
|
|
277
|
+
const result = await this.zohoCrmApi.executeRestApiFunction({
|
|
278
|
+
functionName: 'my_custom_function',
|
|
279
|
+
params: { contact_id: '123' }
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// API key-authenticated call (cross-environment)
|
|
283
|
+
const result = await this.zohoCrmApi.executeRestApiFunction({
|
|
284
|
+
functionName: 'my_custom_function',
|
|
285
|
+
apiKey: 'your-zapikey',
|
|
286
|
+
apiUrl: 'production'
|
|
287
|
+
});
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Key Design Details
|
|
291
|
+
|
|
292
|
+
- **Rate limiting** is built-in (default 100 req/min), auto-adjusts from `X-RATELIMIT-LIMIT` response headers, and retries on HTTP 429.
|
|
293
|
+
- **Token refresh** is automatic. On `ZohoInvalidTokenError`, the token is cleared and re-fetched transparently.
|
|
294
|
+
- **Error classes** are specific and catchable: `ZohoCrmRecordNoContentError`, `ZohoCrmRecordCrudDuplicateDataError`, `ZohoCrmRecordCrudMandatoryFieldNotFoundError`, etc.
|
|
295
|
+
- **Module constants** are provided for common modules: `ZOHO_CRM_LEADS_MODULE`, `ZOHO_CRM_CONTACTS_MODULE`, `ZOHO_CRM_TASKS_MODULE`, etc.
|
|
296
|
+
- Uses the **Zoho CRM v8 API**.
|