@slates-integrations/zoho 0.2.0-rc.5

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/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # <img src="logo.png" height="20"> Zoho
2
+
3
+ Manage core Zoho workflows across CRM, Desk, Books, People, and Projects with one OAuth connection. Retrieve, search, create, update, delete, and inspect related CRM records; manage Desk tickets and contacts; work with Books organizations, invoices, contacts, and expenses; list People forms and manage form/employee, leave, and attendance data; and discover Projects portals while managing projects, tasks, and milestones.
4
+
5
+ ## License
6
+
7
+ This integration is licensed under the [FSL-1.1](https://github.com/metorial/metorial-platform/blob/dev/LICENSE).
8
+
9
+ <div align="center">
10
+ <sub>Built with ❤️ by <a href="https://metorial.com">Metorial</a></sub>
11
+ </div>
package/docs/SPEC.md ADDED
@@ -0,0 +1,155 @@
1
+ # Slates Specification for Zoho
2
+
3
+ ## Overview
4
+
5
+ Zoho is an Indian multinational technology company offering a suite of over 55 cloud-based software products covering CRM, accounting, HR, project management, helpdesk, email, marketing, analytics, and more. Zoho has over 45 integrated applications, mainly designed for small and medium-sized businesses (SMBs), but scalable for larger enterprises, spanning categories including customer relationship management, marketing, sales, customer support, finance, human resources, collaboration, productivity, operations, IT management, and analytics. All Zoho products share a unified authentication system through Zoho Accounts.
6
+
7
+ ## Authentication
8
+
9
+ Zoho uses **OAuth 2.0** as its authentication protocol across all products. OAuth 2.0 allows you to grant a third-party application delegated access to the protected resources of Zoho via Zoho APIs.
10
+
11
+ ### Registration
12
+
13
+ To access the resources of Zoho using the various Zoho APIs, you will need to register your application with Zoho first. On successful registration, you will get a Client ID and Client secret, which you can use to get the access token needed to make API calls.
14
+
15
+ Register at the **Zoho API Console**: `https://api-console.zoho.com/`
16
+
17
+ Client types supported:
18
+
19
+ - **Server-based Applications**: Web apps running on a dedicated HTTP server (standard for integrations).
20
+ - **Client-based Applications**: Browser-only apps independent of a web server.
21
+ - **Mobile Applications**: Apps installed on smartphones and tablets.
22
+ - **Non-browser Mobile Applications**: Devices without browser provisioning (smart TVs, printers).
23
+ - **Self Client**: Stand-alone applications that perform only back-end jobs (without any manual intervention) like data sync.
24
+
25
+ ### OAuth 2.0 Flow (Authorization Code Grant)
26
+
27
+ Zoho uses the **authorization code grant type**. The flow is:
28
+
29
+ 1. **Authorization Request**: Redirect user to:
30
+
31
+ ```
32
+ https://accounts.zoho.com/oauth/v2/auth?client_id={client_id}&response_type=code&redirect_uri={redirect_uri}&scope={scope}&access_type=offline
33
+ ```
34
+
35
+ 2. **Exchange Code for Tokens**: POST to:
36
+
37
+ ```
38
+ https://accounts.zoho.com/oauth/v2/token
39
+ ```
40
+
41
+ With parameters: `client_id`, `client_secret`, `grant_type=authorization_code`, `code`, `redirect_uri`.
42
+
43
+ 3. **Use Access Token**: Zoho's OAuth implementation uses Bearer authentication scheme; the access token must be passed in the Authorization header with the prefix `Zoho-oauthtoken`.
44
+
45
+ ```
46
+ Authorization: Zoho-oauthtoken {access_token}
47
+ ```
48
+
49
+ 4. **Refresh Token**: Access tokens are valid for only 1 hour. A refresh token can be retrieved and stored, and allows the app to generate a new access token whenever required. A refresh token does not expire. Set `access_type=offline` in the authorization request to receive a refresh token.
50
+
51
+ ### Scopes
52
+
53
+ Scope limits the level of access the application can have. For example, if the client only needs to access the Invoices module in Zoho Books, that can be defined in the scope. The resource server will provide access only to that module. It can also be defined what kind of operations (create/read/update/delete) are permissible.
54
+
55
+ Scope format: `ServiceName.ScopeName.OperationType`
56
+
57
+ - **ServiceName**: The Zoho product (e.g., `ZohoCRM`, `ZohoBooks`, `ZohoDesk`, `ZohoPeople`, `ZohoProjects`, `ZohoMail`, etc.)
58
+ - **ScopeName**: The module within the service (e.g., `modules`, `contacts`, `users`, `settings`)
59
+ - **OperationType**: Can be ALL, READ, UPDATE, DELETE (ALL gives access to perform all operations).
60
+
61
+ Examples: `ZohoCRM.modules.leads.READ`, `ZohoBooks.purchaseorders.UPDATE`, `ZohoCRM.settings.ALL`
62
+
63
+ Multiple scopes should be separated by commas.
64
+
65
+ ### Data Centers / Multi-DC
66
+
67
+ Data protection and privacy laws in multiple countries state that user data can only be stored in data centers located on that country's soil. In compliance, Zoho has set up data centers in multiple countries. Each data center only holds the data of users who have registered at that domain.
68
+
69
+ The authorization and API base URLs differ by data center:
70
+
71
+ | Region | Accounts URL | API Domain |
72
+ | --------- | ---------------------- | --------------------- |
73
+ | US | `accounts.zoho.com` | `www.zohoapis.com` |
74
+ | EU | `accounts.zoho.eu` | `www.zohoapis.eu` |
75
+ | India | `accounts.zoho.in` | `www.zohoapis.in` |
76
+ | Australia | `accounts.zoho.com.au` | `www.zohoapis.com.au` |
77
+ | Japan | `accounts.zoho.jp` | `www.zohoapis.jp` |
78
+ | Canada | `accounts.zoho.ca` | `www.zohoapis.ca` |
79
+
80
+ In the authorization request, you send calls to `https://accounts.zoho.com`. In the response, the location of the user's DC will be included as the parameter `location`. Once you have identified the user's data center, you need to make the access token request to the server URL corresponding to that location. For example, if location=eu, you will need to make access token request to `https://accounts.zoho.eu`.
81
+
82
+ ## Features
83
+
84
+ ### CRM (Zoho CRM)
85
+
86
+ Manage the full sales lifecycle including leads, contacts, accounts, deals, tasks, events, and calls. Access and work with almost all of Zoho CRM's components using REST API. Fetch, create, update or delete any sort of information stored in your account. Use simple HTTP methods to fetch components like records, modules, and custom views.
87
+
88
+ - Supports custom modules and fields.
89
+ - CRM Object Query Language (COQL) allows constructing queries to fetch data, similar to MySQL SELECT queries.
90
+ - Bulk API for retrieving or uploading large amounts of data asynchronously, useful for migration, data backup, and initial sync.
91
+
92
+ ### Helpdesk (Zoho Desk)
93
+
94
+ Manage support tickets, contacts, accounts, tasks, calls, and events. A webhook pushes relevant information to the callback URL whenever an event, such as adding a ticket or updating a contact, occurs in the help desk.
95
+
96
+ - Supports department-based filtering.
97
+ - Includes instant messaging session and message management.
98
+
99
+ ### Accounting & Finance (Zoho Books)
100
+
101
+ The Zoho Books API allows you to perform many accounting operations that you do with the web client. This generic Zoho package currently implements organizations, invoices, contacts, and expenses.
102
+
103
+ - There are 8 different domains for Zoho Books' APIs, and you must use the one applicable to your organization.
104
+ - Requires an Organization ID for API calls.
105
+
106
+ ### HR Management (Zoho People)
107
+
108
+ Manage employee records, forms, leave, attendance, timesheets, and HR processes. Zoho People APIs use selected scopes, which control the type of resource that the client application can access.
109
+
110
+ - Supports custom forms and fields.
111
+
112
+ ### Project Management (Zoho Projects)
113
+
114
+ Zoho Projects provides REST APIs to manage projects, connect third party applications, and transfer or retrieve data. This generic Zoho package currently implements portal discovery, project management, task management, and milestone listing.
115
+
116
+ - Supports custom modules with configurable layouts.
117
+ - Requires a Portal ID in API calls.
118
+
119
+ ### Out Of Scope For This Generic Package
120
+
121
+ Zoho Mail, Campaigns, Analytics, Creator, Billing, Sign, ZeptoMail, and other product-specific APIs are not implemented in this package. Use dedicated Zoho service integrations when those surfaces are needed.
122
+
123
+ ## Events
124
+
125
+ Zoho supports webhooks and notification subscriptions across several products, though the mechanism varies by product. This package implements CRM notification registration and Desk event request handling.
126
+
127
+ ### Zoho CRM — Notification API (Watch API)
128
+
129
+ On trigger of any notification-enabled event in a module, Zoho CRM sends a notification to the user through the notify URL. You can set up webhooks for most CRM primary modules, such as Leads, Accounts, Contacts, Potentials (Opportunities), Events, and Tasks.
130
+
131
+ - Events: Record creation, update, deletion (subscribe using `.all`, `.create`, `.edit`, `.delete` suffixes per module).
132
+ - Supports field-level notification conditions to filter which field changes trigger notifications.
133
+ - Channel subscriptions expire and must be renewed periodically.
134
+ - Optionally return affected field values in the notification payload.
135
+
136
+ ### Zoho CRM — Workflow Webhooks
137
+
138
+ Webhooks in Zoho CRM allow you to send real-time data from Zoho CRM to external applications or services when specific events occur such as record creation, update, or deletion.
139
+
140
+ - Configured per module (Leads, Contacts, etc.) and tied to workflow rules.
141
+ - You can associate up to 6 (1 Instant Action and 5 Time-Based Actions) webhooks per workflow rule.
142
+
143
+ ### Zoho Desk — Webhook Subscriptions
144
+
145
+ These APIs help you programmatically create, view, update, or delete webhooks that subscribe to event information from Zoho Desk.
146
+
147
+ - **Ticket events**: Add, update, delete, attachment update. Supports department ID filtering and field-level tracking (up to 5 fields).
148
+ - **Contact events**: Add, update.
149
+ - **Account events**: Add, update.
150
+ - **Task events**: Add, update, delete.
151
+ - **Call events**: Add, update, delete. Supports department ID filtering.
152
+ - **Event events**: Add, update, delete.
153
+ - **IM events**: Message add, session status, message status.
154
+ - **Department events**: Add, update.
155
+ - Optionally include previous state of resource in update payloads.
package/logo.png ADDED
Binary file
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "@slates-integrations/zoho",
3
+ "main": "src/index.ts",
4
+ "type": "module",
5
+ "scripts": {
6
+ "build": "bunx @vercel/ncc build src/index.ts -o dist -m -s",
7
+ "typecheck": "tsc --noEmit"
8
+ },
9
+ "dependencies": {
10
+ "@lowerdeck/error": "^1.1.0",
11
+ "@types/node": "^20",
12
+ "slates": "1.0.0-rc.10",
13
+ "zod": "^4.2"
14
+ },
15
+ "devDependencies": {
16
+ "typescript": "^5"
17
+ },
18
+ "version": "0.2.0-rc.5"
19
+ }
package/slate.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "@metorial/zoho",
3
+ "description": "Manage core Zoho workflows across CRM, Desk, Books, People, and Projects. Retrieve, search, create, update, delete, and inspect related CRM records. Manage Desk tickets and contacts. Work with Books organizations, invoices, contacts, and expenses. List People forms and manage form/employee, leave, and attendance data. Discover Projects portals and manage projects, tasks, and milestones.",
4
+ "categories": ["crm-and-sales-tools", "financial-data-and-stock-market"],
5
+ "skills": [
6
+ "manage CRM records",
7
+ "create and track invoices",
8
+ "manage support tickets",
9
+ "manage employee HR records",
10
+ "organize projects and tasks",
11
+ "discover Zoho organization and portal IDs",
12
+ "query CRM data using COQL",
13
+ "subscribe to CRM and Desk event webhooks"
14
+ ],
15
+ "logoUrl": "https://provider-logos.metorial-cdn.com/zoho.png",
16
+ "version": "0.1.2"
17
+ }
package/src/auth.ts ADDED
@@ -0,0 +1,339 @@
1
+ import { SlateAuth, axios } from 'slates';
2
+ import { z } from 'zod';
3
+ import { getAccountsUrl, datacenterFromLocation, datacenterFromApiDomain } from './lib/urls';
4
+ import type { Datacenter } from './lib/urls';
5
+ import { zohoApiError, zohoServiceError } from './lib/errors';
6
+
7
+ let scopes = [
8
+ // CRM scopes
9
+ {
10
+ title: 'CRM - Full Access',
11
+ description: 'Full access to all CRM modules',
12
+ scope: 'ZohoCRM.modules.ALL'
13
+ },
14
+ {
15
+ title: 'CRM - Read Records',
16
+ description: 'Read access to CRM records',
17
+ scope: 'ZohoCRM.modules.READ'
18
+ },
19
+ {
20
+ title: 'CRM - Settings',
21
+ description: 'Access CRM settings including modules metadata',
22
+ scope: 'ZohoCRM.settings.ALL'
23
+ },
24
+ {
25
+ title: 'CRM - Notifications',
26
+ description: 'Manage CRM notification/watch subscriptions',
27
+ scope: 'ZohoCRM.notifications.ALL'
28
+ },
29
+ {
30
+ title: 'CRM - COQL',
31
+ description: 'Execute COQL queries against CRM data',
32
+ scope: 'ZohoCRM.coql.READ'
33
+ },
34
+ {
35
+ title: 'CRM - Secure Search',
36
+ description: 'Search CRM records using the current secure search scope',
37
+ scope: 'ZohoSearch.securesearch.READ'
38
+ },
39
+ { title: 'CRM - Bulk Read', description: 'Bulk read CRM data', scope: 'ZohoCRM.bulk.READ' },
40
+ {
41
+ title: 'CRM - Users',
42
+ description: 'Access CRM user information',
43
+ scope: 'ZohoCRM.users.READ'
44
+ },
45
+
46
+ // Desk scopes
47
+ {
48
+ title: 'Desk - Tickets',
49
+ description: 'Full access to support tickets',
50
+ scope: 'Desk.tickets.ALL'
51
+ },
52
+ {
53
+ title: 'Desk - Read Tickets',
54
+ description: 'Read access to support tickets',
55
+ scope: 'Desk.tickets.READ'
56
+ },
57
+ {
58
+ title: 'Desk - Contacts',
59
+ description: 'Full access to Desk contacts',
60
+ scope: 'Desk.contacts.ALL'
61
+ },
62
+ {
63
+ title: 'Desk - Settings',
64
+ description: 'Access Desk settings and departments',
65
+ scope: 'Desk.settings.ALL'
66
+ },
67
+ {
68
+ title: 'Desk - Events',
69
+ description: 'Manage Desk webhook subscriptions',
70
+ scope: 'Desk.events.ALL'
71
+ },
72
+ {
73
+ title: 'Desk - Search',
74
+ description: 'Search across Desk resources',
75
+ scope: 'Desk.search.READ'
76
+ },
77
+ { title: 'Desk - Basic', description: 'Basic Desk access', scope: 'Desk.basic.ALL' },
78
+
79
+ // Books scopes
80
+ {
81
+ title: 'Books - Full Access',
82
+ description: 'Full access to Zoho Books',
83
+ scope: 'ZohoBooks.fullaccess.all'
84
+ },
85
+ {
86
+ title: 'Books - Invoices',
87
+ description: 'Manage invoices in Zoho Books',
88
+ scope: 'ZohoBooks.invoices.ALL'
89
+ },
90
+ {
91
+ title: 'Books - Read Invoices',
92
+ description: 'Read invoices in Zoho Books',
93
+ scope: 'ZohoBooks.invoices.READ'
94
+ },
95
+ {
96
+ title: 'Books - Contacts',
97
+ description: 'Manage contacts in Zoho Books',
98
+ scope: 'ZohoBooks.contacts.ALL'
99
+ },
100
+ {
101
+ title: 'Books - Expenses',
102
+ description: 'Manage expenses in Zoho Books',
103
+ scope: 'ZohoBooks.expenses.ALL'
104
+ },
105
+ {
106
+ title: 'Books - Settings',
107
+ description: 'Access Zoho Books settings and organizations',
108
+ scope: 'ZohoBooks.settings.READ'
109
+ },
110
+
111
+ // People scopes
112
+ {
113
+ title: 'People - Full Access',
114
+ description: 'Full access to Zoho People data',
115
+ scope: 'ZOHOPEOPLE.forms.ALL'
116
+ },
117
+ {
118
+ title: 'People - Read',
119
+ description: 'Read access to Zoho People data',
120
+ scope: 'ZOHOPEOPLE.forms.READ'
121
+ },
122
+ {
123
+ title: 'People - Attendance',
124
+ description: 'Manage attendance records',
125
+ scope: 'ZOHOPEOPLE.attendance.ALL'
126
+ },
127
+ {
128
+ title: 'People - Leave',
129
+ description: 'Manage leave records',
130
+ scope: 'ZOHOPEOPLE.leave.ALL'
131
+ },
132
+ {
133
+ title: 'People - Timesheet',
134
+ description: 'Manage timesheets',
135
+ scope: 'ZOHOPEOPLE.timetracker.ALL'
136
+ },
137
+
138
+ // Projects scopes
139
+ {
140
+ title: 'Projects - Full Access',
141
+ description: 'Full access to Zoho Projects',
142
+ scope: 'ZohoProjects.portals.ALL'
143
+ },
144
+ {
145
+ title: 'Projects - Manage Projects',
146
+ description: 'Create, read, update, and delete Zoho Projects projects',
147
+ scope: 'ZohoProjects.projects.ALL'
148
+ },
149
+ {
150
+ title: 'Projects - Read',
151
+ description: 'Read access to Zoho Projects',
152
+ scope: 'ZohoProjects.portals.READ'
153
+ },
154
+ {
155
+ title: 'Projects - Tasks',
156
+ description: 'Manage tasks in Zoho Projects',
157
+ scope: 'ZohoProjects.tasks.ALL'
158
+ },
159
+ {
160
+ title: 'Projects - Timesheets',
161
+ description: 'Manage project timesheets',
162
+ scope: 'ZohoProjects.timesheets.ALL'
163
+ },
164
+ {
165
+ title: 'Projects - Bugs',
166
+ description: 'Manage bugs in Zoho Projects',
167
+ scope: 'ZohoProjects.bugs.ALL'
168
+ },
169
+
170
+ // Profile scope
171
+ {
172
+ title: 'Profile',
173
+ description: 'Access user profile information',
174
+ scope: 'AaaServer.profile.READ'
175
+ }
176
+ ];
177
+
178
+ function createZohoOauth(name: string, key: string, dc: Datacenter) {
179
+ return {
180
+ type: 'auth.oauth' as const,
181
+ name,
182
+ key,
183
+ scopes,
184
+
185
+ getAuthorizationUrl: async (ctx: any) => {
186
+ let accountsUrl = getAccountsUrl(dc);
187
+ let scopeString = ctx.scopes.join(',');
188
+
189
+ let params = new URLSearchParams({
190
+ client_id: ctx.clientId,
191
+ response_type: 'code',
192
+ redirect_uri: ctx.redirectUri,
193
+ scope: scopeString,
194
+ access_type: 'offline',
195
+ state: ctx.state,
196
+ prompt: 'consent'
197
+ });
198
+
199
+ return {
200
+ url: `${accountsUrl}/oauth/v2/auth?${params.toString()}`
201
+ };
202
+ },
203
+
204
+ handleCallback: async (ctx: any) => {
205
+ let accountsUrl = getAccountsUrl(dc);
206
+
207
+ let response;
208
+ try {
209
+ response = await axios.post(`${accountsUrl}/oauth/v2/token`, null, {
210
+ params: {
211
+ client_id: ctx.clientId,
212
+ client_secret: ctx.clientSecret,
213
+ grant_type: 'authorization_code',
214
+ code: ctx.code,
215
+ redirect_uri: ctx.redirectUri
216
+ }
217
+ });
218
+ } catch (error) {
219
+ throw zohoApiError(error, 'OAuth token exchange');
220
+ }
221
+
222
+ let data = response.data;
223
+
224
+ // Prefer the location returned by Zoho -- user may have picked a different DC for login.
225
+ let resolvedDc: Datacenter = data.location
226
+ ? datacenterFromLocation(data.location)
227
+ : (datacenterFromApiDomain(data.api_domain) ?? dc);
228
+
229
+ let expiresAt = data.expires_in
230
+ ? new Date(Date.now() + data.expires_in * 1000).toISOString()
231
+ : undefined;
232
+
233
+ if (!data.access_token) {
234
+ throw zohoServiceError('Zoho OAuth token response did not include an access token.');
235
+ }
236
+
237
+ if (!data.refresh_token) {
238
+ throw zohoServiceError(
239
+ 'Zoho OAuth token response did not include a refresh token. Reconnect and approve offline access.'
240
+ );
241
+ }
242
+
243
+ return {
244
+ output: {
245
+ token: data.access_token,
246
+ refreshToken: data.refresh_token,
247
+ expiresAt,
248
+ datacenter: resolvedDc
249
+ }
250
+ };
251
+ },
252
+
253
+ handleTokenRefresh: async (ctx: any) => {
254
+ let resolvedDc = (ctx.output.datacenter || dc) as Datacenter;
255
+ let accountsUrl = getAccountsUrl(resolvedDc);
256
+
257
+ if (!ctx.output.refreshToken) {
258
+ throw zohoServiceError(
259
+ 'Zoho OAuth profile is missing a refresh token. Reconnect the Zoho account to restore automatic refresh.'
260
+ );
261
+ }
262
+
263
+ let response;
264
+ try {
265
+ response = await axios.post(`${accountsUrl}/oauth/v2/token`, null, {
266
+ params: {
267
+ client_id: ctx.clientId,
268
+ client_secret: ctx.clientSecret,
269
+ grant_type: 'refresh_token',
270
+ refresh_token: ctx.output.refreshToken
271
+ }
272
+ });
273
+ } catch (error) {
274
+ throw zohoApiError(error, 'OAuth token refresh');
275
+ }
276
+
277
+ let data = response.data;
278
+
279
+ let expiresAt = data.expires_in
280
+ ? new Date(Date.now() + data.expires_in * 1000).toISOString()
281
+ : undefined;
282
+
283
+ if (!data.access_token) {
284
+ throw zohoServiceError('Zoho OAuth refresh response did not include an access token.');
285
+ }
286
+
287
+ return {
288
+ output: {
289
+ token: data.access_token,
290
+ refreshToken: data.refresh_token || ctx.output.refreshToken,
291
+ expiresAt,
292
+ datacenter: resolvedDc
293
+ }
294
+ };
295
+ },
296
+
297
+ getProfile: async (ctx: any) => {
298
+ let resolvedDc = (ctx.output.datacenter || dc) as Datacenter;
299
+ let accountsUrl = getAccountsUrl(resolvedDc);
300
+
301
+ let response;
302
+ try {
303
+ response = await axios.get(`${accountsUrl}/oauth/user/info`, {
304
+ headers: {
305
+ Authorization: `Zoho-oauthtoken ${ctx.output.token}`
306
+ }
307
+ });
308
+ } catch (error) {
309
+ throw zohoApiError(error, 'profile request');
310
+ }
311
+
312
+ let data = response.data;
313
+
314
+ return {
315
+ profile: {
316
+ id: data.ZUID?.toString(),
317
+ email: data.Email,
318
+ name: data.Display_Name || `${data.First_Name || ''} ${data.Last_Name || ''}`.trim()
319
+ }
320
+ };
321
+ }
322
+ };
323
+ }
324
+
325
+ export let auth = SlateAuth.create()
326
+ .output(
327
+ z.object({
328
+ token: z.string(),
329
+ refreshToken: z.string().optional(),
330
+ expiresAt: z.string().optional(),
331
+ datacenter: z.string()
332
+ })
333
+ )
334
+ .addOauth(createZohoOauth('United States (zoho.com)', 'oauth_us', 'us'))
335
+ .addOauth(createZohoOauth('Europe (zoho.eu)', 'oauth_eu', 'eu'))
336
+ .addOauth(createZohoOauth('India (zoho.in)', 'oauth_in', 'in'))
337
+ .addOauth(createZohoOauth('Australia (zoho.com.au)', 'oauth_au', 'au'))
338
+ .addOauth(createZohoOauth('Japan (zoho.jp)', 'oauth_jp', 'jp'))
339
+ .addOauth(createZohoOauth('Canada (zoho.ca)', 'oauth_ca', 'ca'));
package/src/config.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { SlateConfig } from 'slates';
2
+ import { z } from 'zod';
3
+
4
+ export let config = SlateConfig.create(
5
+ z.object({
6
+ datacenter: z
7
+ .enum(['us', 'eu', 'in', 'au', 'jp', 'ca'])
8
+ .default('us')
9
+ .describe('Zoho data center region. Determines the API base URL and accounts URL.')
10
+ })
11
+ );
package/src/index.ts ADDED
@@ -0,0 +1,44 @@
1
+ import { Slate } from 'slates';
2
+ import { spec } from './spec';
3
+ import {
4
+ crmGetRecords,
5
+ crmManageRecord,
6
+ crmSearchRecords,
7
+ crmGetModules,
8
+ crmGetRelatedRecords,
9
+ deskGetTickets,
10
+ deskManageTicket,
11
+ deskManageContact,
12
+ booksGetInvoices,
13
+ booksManageInvoice,
14
+ booksManageContact,
15
+ booksManageExpense,
16
+ peopleManageEmployee,
17
+ projectsGetPortals,
18
+ projectsManageProject,
19
+ projectsManageTask
20
+ } from './tools';
21
+ import { crmRecordEvents, deskEvents } from './triggers';
22
+
23
+ export let provider = Slate.create({
24
+ spec,
25
+ tools: [
26
+ crmGetRecords,
27
+ crmManageRecord,
28
+ crmSearchRecords,
29
+ crmGetModules,
30
+ crmGetRelatedRecords,
31
+ deskGetTickets,
32
+ deskManageTicket,
33
+ deskManageContact,
34
+ booksGetInvoices,
35
+ booksManageInvoice,
36
+ booksManageContact,
37
+ booksManageExpense,
38
+ peopleManageEmployee,
39
+ projectsGetPortals,
40
+ projectsManageProject,
41
+ projectsManageTask
42
+ ],
43
+ triggers: [crmRecordEvents, deskEvents]
44
+ });