airbyte-agent-zendesk-chat 0.1.1__py3-none-any.whl
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.
Potentially problematic release.
This version of airbyte-agent-zendesk-chat might be problematic. Click here for more details.
- airbyte_agent_zendesk_chat/__init__.py +193 -0
- airbyte_agent_zendesk_chat/_vendored/__init__.py +1 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/__init__.py +82 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/auth_strategies.py +1120 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/auth_template.py +135 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/cloud_utils/__init__.py +5 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/cloud_utils/client.py +213 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/connector_model_loader.py +965 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/constants.py +78 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/exceptions.py +23 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/executor/__init__.py +31 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/executor/hosted_executor.py +196 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/executor/local_executor.py +1724 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/executor/models.py +190 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/extensions.py +693 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/http/__init__.py +37 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/http/adapters/__init__.py +9 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/http/adapters/httpx_adapter.py +251 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/http/config.py +98 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/http/exceptions.py +119 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/http/protocols.py +114 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/http/response.py +104 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/http_client.py +693 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/introspection.py +262 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/logging/__init__.py +11 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/logging/logger.py +273 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/logging/types.py +93 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/observability/__init__.py +11 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/observability/config.py +179 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/observability/models.py +19 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/observability/redactor.py +81 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/observability/session.py +103 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/performance/__init__.py +6 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/performance/instrumentation.py +57 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/performance/metrics.py +93 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/schema/__init__.py +75 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/schema/base.py +164 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/schema/components.py +239 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/schema/connector.py +120 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/schema/extensions.py +230 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/schema/operations.py +146 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/schema/security.py +223 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/secrets.py +182 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/telemetry/__init__.py +10 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/telemetry/config.py +32 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/telemetry/events.py +59 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/telemetry/tracker.py +155 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/types.py +245 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/utils.py +60 -0
- airbyte_agent_zendesk_chat/_vendored/connector_sdk/validation.py +828 -0
- airbyte_agent_zendesk_chat/connector.py +1465 -0
- airbyte_agent_zendesk_chat/connector_model.py +2424 -0
- airbyte_agent_zendesk_chat/models.py +582 -0
- airbyte_agent_zendesk_chat/types.py +984 -0
- airbyte_agent_zendesk_chat-0.1.1.dist-info/METADATA +130 -0
- airbyte_agent_zendesk_chat-0.1.1.dist-info/RECORD +57 -0
- airbyte_agent_zendesk_chat-0.1.1.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,1465 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Zendesk-Chat connector.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
from typing import TYPE_CHECKING, Any, Callable, TypeVar, overload
|
|
9
|
+
try:
|
|
10
|
+
from typing import Literal
|
|
11
|
+
except ImportError:
|
|
12
|
+
from typing_extensions import Literal
|
|
13
|
+
|
|
14
|
+
from .connector_model import ZendeskChatConnectorModel
|
|
15
|
+
from ._vendored.connector_sdk.introspection import describe_entities, generate_tool_description
|
|
16
|
+
from .types import (
|
|
17
|
+
AccountsGetParams,
|
|
18
|
+
AgentTimelineListParams,
|
|
19
|
+
AgentsGetParams,
|
|
20
|
+
AgentsListParams,
|
|
21
|
+
BansGetParams,
|
|
22
|
+
BansListParams,
|
|
23
|
+
ChatsGetParams,
|
|
24
|
+
ChatsListParams,
|
|
25
|
+
DepartmentsGetParams,
|
|
26
|
+
DepartmentsListParams,
|
|
27
|
+
GoalsGetParams,
|
|
28
|
+
GoalsListParams,
|
|
29
|
+
RolesGetParams,
|
|
30
|
+
RolesListParams,
|
|
31
|
+
RoutingSettingsGetParams,
|
|
32
|
+
ShortcutsGetParams,
|
|
33
|
+
ShortcutsListParams,
|
|
34
|
+
SkillsGetParams,
|
|
35
|
+
SkillsListParams,
|
|
36
|
+
TriggersListParams,
|
|
37
|
+
AirbyteSearchParams,
|
|
38
|
+
AgentsSearchFilter,
|
|
39
|
+
AgentsSearchQuery,
|
|
40
|
+
ChatsSearchFilter,
|
|
41
|
+
ChatsSearchQuery,
|
|
42
|
+
DepartmentsSearchFilter,
|
|
43
|
+
DepartmentsSearchQuery,
|
|
44
|
+
ShortcutsSearchFilter,
|
|
45
|
+
ShortcutsSearchQuery,
|
|
46
|
+
TriggersSearchFilter,
|
|
47
|
+
TriggersSearchQuery,
|
|
48
|
+
)
|
|
49
|
+
if TYPE_CHECKING:
|
|
50
|
+
from .models import ZendeskChatAuthConfig
|
|
51
|
+
# Import response models and envelope models at runtime
|
|
52
|
+
from .models import (
|
|
53
|
+
ZendeskChatExecuteResult,
|
|
54
|
+
ZendeskChatExecuteResultWithMeta,
|
|
55
|
+
AgentsListResult,
|
|
56
|
+
AgentTimelineListResult,
|
|
57
|
+
BansListResult,
|
|
58
|
+
ChatsListResult,
|
|
59
|
+
DepartmentsListResult,
|
|
60
|
+
GoalsListResult,
|
|
61
|
+
RolesListResult,
|
|
62
|
+
ShortcutsListResult,
|
|
63
|
+
SkillsListResult,
|
|
64
|
+
TriggersListResult,
|
|
65
|
+
Account,
|
|
66
|
+
Agent,
|
|
67
|
+
AgentTimeline,
|
|
68
|
+
Ban,
|
|
69
|
+
Chat,
|
|
70
|
+
Department,
|
|
71
|
+
Goal,
|
|
72
|
+
Role,
|
|
73
|
+
RoutingSettings,
|
|
74
|
+
Shortcut,
|
|
75
|
+
Skill,
|
|
76
|
+
Trigger,
|
|
77
|
+
AirbyteSearchHit,
|
|
78
|
+
AirbyteSearchResult,
|
|
79
|
+
AgentsSearchData,
|
|
80
|
+
AgentsSearchResult,
|
|
81
|
+
ChatsSearchData,
|
|
82
|
+
ChatsSearchResult,
|
|
83
|
+
DepartmentsSearchData,
|
|
84
|
+
DepartmentsSearchResult,
|
|
85
|
+
ShortcutsSearchData,
|
|
86
|
+
ShortcutsSearchResult,
|
|
87
|
+
TriggersSearchData,
|
|
88
|
+
TriggersSearchResult,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
# TypeVar for decorator type preservation
|
|
92
|
+
_F = TypeVar("_F", bound=Callable[..., Any])
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class ZendeskChatConnector:
|
|
97
|
+
"""
|
|
98
|
+
Type-safe Zendesk-Chat API connector.
|
|
99
|
+
|
|
100
|
+
Auto-generated from OpenAPI specification with full type safety.
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
connector_name = "zendesk-chat"
|
|
104
|
+
connector_version = "0.1.2"
|
|
105
|
+
vendored_sdk_version = "0.1.0" # Version of vendored connector-sdk
|
|
106
|
+
|
|
107
|
+
# Map of (entity, action) -> needs_envelope for envelope wrapping decision
|
|
108
|
+
_ENVELOPE_MAP = {
|
|
109
|
+
("accounts", "get"): None,
|
|
110
|
+
("agents", "list"): True,
|
|
111
|
+
("agents", "get"): None,
|
|
112
|
+
("agent_timeline", "list"): True,
|
|
113
|
+
("bans", "list"): True,
|
|
114
|
+
("bans", "get"): None,
|
|
115
|
+
("chats", "list"): True,
|
|
116
|
+
("chats", "get"): None,
|
|
117
|
+
("departments", "list"): True,
|
|
118
|
+
("departments", "get"): None,
|
|
119
|
+
("goals", "list"): True,
|
|
120
|
+
("goals", "get"): None,
|
|
121
|
+
("roles", "list"): True,
|
|
122
|
+
("roles", "get"): None,
|
|
123
|
+
("routing_settings", "get"): None,
|
|
124
|
+
("shortcuts", "list"): True,
|
|
125
|
+
("shortcuts", "get"): None,
|
|
126
|
+
("skills", "list"): True,
|
|
127
|
+
("skills", "get"): None,
|
|
128
|
+
("triggers", "list"): True,
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
# Map of (entity, action) -> {python_param_name: api_param_name}
|
|
132
|
+
# Used to convert snake_case TypedDict keys to API parameter names in execute()
|
|
133
|
+
_PARAM_MAP = {
|
|
134
|
+
('agents', 'list'): {'limit': 'limit', 'since_id': 'since_id'},
|
|
135
|
+
('agents', 'get'): {'agent_id': 'agent_id'},
|
|
136
|
+
('agent_timeline', 'list'): {'start_time': 'start_time', 'limit': 'limit', 'fields': 'fields'},
|
|
137
|
+
('bans', 'list'): {'limit': 'limit', 'since_id': 'since_id'},
|
|
138
|
+
('bans', 'get'): {'ban_id': 'ban_id'},
|
|
139
|
+
('chats', 'list'): {'start_time': 'start_time', 'limit': 'limit', 'fields': 'fields'},
|
|
140
|
+
('chats', 'get'): {'chat_id': 'chat_id'},
|
|
141
|
+
('departments', 'get'): {'department_id': 'department_id'},
|
|
142
|
+
('goals', 'get'): {'goal_id': 'goal_id'},
|
|
143
|
+
('roles', 'get'): {'role_id': 'role_id'},
|
|
144
|
+
('shortcuts', 'get'): {'shortcut_id': 'shortcut_id'},
|
|
145
|
+
('skills', 'get'): {'skill_id': 'skill_id'},
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
def __init__(
|
|
149
|
+
self,
|
|
150
|
+
auth_config: ZendeskChatAuthConfig | None = None,
|
|
151
|
+
external_user_id: str | None = None,
|
|
152
|
+
airbyte_client_id: str | None = None,
|
|
153
|
+
airbyte_client_secret: str | None = None,
|
|
154
|
+
on_token_refresh: Any | None = None,
|
|
155
|
+
subdomain: str | None = None ):
|
|
156
|
+
"""
|
|
157
|
+
Initialize a new zendesk-chat connector instance.
|
|
158
|
+
|
|
159
|
+
Supports both local and hosted execution modes:
|
|
160
|
+
- Local mode: Provide `auth_config` for direct API calls
|
|
161
|
+
- Hosted mode: Provide `external_user_id`, `airbyte_client_id`, and `airbyte_client_secret` for hosted execution
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
auth_config: Typed authentication configuration (required for local mode)
|
|
165
|
+
external_user_id: External user ID (required for hosted mode)
|
|
166
|
+
airbyte_client_id: Airbyte OAuth client ID (required for hosted mode)
|
|
167
|
+
airbyte_client_secret: Airbyte OAuth client secret (required for hosted mode)
|
|
168
|
+
on_token_refresh: Optional callback for OAuth2 token refresh persistence.
|
|
169
|
+
Called with new_tokens dict when tokens are refreshed. Can be sync or async.
|
|
170
|
+
Example: lambda tokens: save_to_database(tokens) subdomain: Your Zendesk subdomain (the part before .zendesk.com in your Zendesk URL)
|
|
171
|
+
Examples:
|
|
172
|
+
# Local mode (direct API calls)
|
|
173
|
+
connector = ZendeskChatConnector(auth_config=ZendeskChatAuthConfig(access_token="..."))
|
|
174
|
+
# Hosted mode (executed on Airbyte cloud)
|
|
175
|
+
connector = ZendeskChatConnector(
|
|
176
|
+
external_user_id="user-123",
|
|
177
|
+
airbyte_client_id="client_abc123",
|
|
178
|
+
airbyte_client_secret="secret_xyz789"
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
# Local mode with OAuth2 token refresh callback
|
|
182
|
+
def save_tokens(new_tokens: dict) -> None:
|
|
183
|
+
# Persist updated tokens to your storage (file, database, etc.)
|
|
184
|
+
with open("tokens.json", "w") as f:
|
|
185
|
+
json.dump(new_tokens, f)
|
|
186
|
+
|
|
187
|
+
connector = ZendeskChatConnector(
|
|
188
|
+
auth_config=ZendeskChatAuthConfig(access_token="...", refresh_token="..."),
|
|
189
|
+
on_token_refresh=save_tokens
|
|
190
|
+
)
|
|
191
|
+
"""
|
|
192
|
+
# Hosted mode: external_user_id, airbyte_client_id, and airbyte_client_secret provided
|
|
193
|
+
if external_user_id and airbyte_client_id and airbyte_client_secret:
|
|
194
|
+
from ._vendored.connector_sdk.executor import HostedExecutor
|
|
195
|
+
self._executor = HostedExecutor(
|
|
196
|
+
external_user_id=external_user_id,
|
|
197
|
+
airbyte_client_id=airbyte_client_id,
|
|
198
|
+
airbyte_client_secret=airbyte_client_secret,
|
|
199
|
+
connector_definition_id=str(ZendeskChatConnectorModel.id),
|
|
200
|
+
)
|
|
201
|
+
else:
|
|
202
|
+
# Local mode: auth_config required
|
|
203
|
+
if not auth_config:
|
|
204
|
+
raise ValueError(
|
|
205
|
+
"Either provide (external_user_id, airbyte_client_id, airbyte_client_secret) for hosted mode "
|
|
206
|
+
"or auth_config for local mode"
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
from ._vendored.connector_sdk.executor import LocalExecutor
|
|
210
|
+
|
|
211
|
+
# Build config_values dict from server variables
|
|
212
|
+
config_values: dict[str, str] = {}
|
|
213
|
+
if subdomain:
|
|
214
|
+
config_values["subdomain"] = subdomain
|
|
215
|
+
|
|
216
|
+
self._executor = LocalExecutor(
|
|
217
|
+
model=ZendeskChatConnectorModel,
|
|
218
|
+
auth_config=auth_config.model_dump() if auth_config else None,
|
|
219
|
+
config_values=config_values,
|
|
220
|
+
on_token_refresh=on_token_refresh
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
# Update base_url with server variables if provided
|
|
224
|
+
base_url = self._executor.http_client.base_url
|
|
225
|
+
if subdomain:
|
|
226
|
+
base_url = base_url.replace("{subdomain}", subdomain)
|
|
227
|
+
self._executor.http_client.base_url = base_url
|
|
228
|
+
|
|
229
|
+
# Initialize entity query objects
|
|
230
|
+
self.accounts = AccountsQuery(self)
|
|
231
|
+
self.agents = AgentsQuery(self)
|
|
232
|
+
self.agent_timeline = AgentTimelineQuery(self)
|
|
233
|
+
self.bans = BansQuery(self)
|
|
234
|
+
self.chats = ChatsQuery(self)
|
|
235
|
+
self.departments = DepartmentsQuery(self)
|
|
236
|
+
self.goals = GoalsQuery(self)
|
|
237
|
+
self.roles = RolesQuery(self)
|
|
238
|
+
self.routing_settings = RoutingSettingsQuery(self)
|
|
239
|
+
self.shortcuts = ShortcutsQuery(self)
|
|
240
|
+
self.skills = SkillsQuery(self)
|
|
241
|
+
self.triggers = TriggersQuery(self)
|
|
242
|
+
|
|
243
|
+
# ===== TYPED EXECUTE METHOD (Recommended Interface) =====
|
|
244
|
+
|
|
245
|
+
@overload
|
|
246
|
+
async def execute(
|
|
247
|
+
self,
|
|
248
|
+
entity: Literal["accounts"],
|
|
249
|
+
action: Literal["get"],
|
|
250
|
+
params: "AccountsGetParams"
|
|
251
|
+
) -> "Account": ...
|
|
252
|
+
|
|
253
|
+
@overload
|
|
254
|
+
async def execute(
|
|
255
|
+
self,
|
|
256
|
+
entity: Literal["agents"],
|
|
257
|
+
action: Literal["list"],
|
|
258
|
+
params: "AgentsListParams"
|
|
259
|
+
) -> "AgentsListResult": ...
|
|
260
|
+
|
|
261
|
+
@overload
|
|
262
|
+
async def execute(
|
|
263
|
+
self,
|
|
264
|
+
entity: Literal["agents"],
|
|
265
|
+
action: Literal["get"],
|
|
266
|
+
params: "AgentsGetParams"
|
|
267
|
+
) -> "Agent": ...
|
|
268
|
+
|
|
269
|
+
@overload
|
|
270
|
+
async def execute(
|
|
271
|
+
self,
|
|
272
|
+
entity: Literal["agent_timeline"],
|
|
273
|
+
action: Literal["list"],
|
|
274
|
+
params: "AgentTimelineListParams"
|
|
275
|
+
) -> "AgentTimelineListResult": ...
|
|
276
|
+
|
|
277
|
+
@overload
|
|
278
|
+
async def execute(
|
|
279
|
+
self,
|
|
280
|
+
entity: Literal["bans"],
|
|
281
|
+
action: Literal["list"],
|
|
282
|
+
params: "BansListParams"
|
|
283
|
+
) -> "BansListResult": ...
|
|
284
|
+
|
|
285
|
+
@overload
|
|
286
|
+
async def execute(
|
|
287
|
+
self,
|
|
288
|
+
entity: Literal["bans"],
|
|
289
|
+
action: Literal["get"],
|
|
290
|
+
params: "BansGetParams"
|
|
291
|
+
) -> "Ban": ...
|
|
292
|
+
|
|
293
|
+
@overload
|
|
294
|
+
async def execute(
|
|
295
|
+
self,
|
|
296
|
+
entity: Literal["chats"],
|
|
297
|
+
action: Literal["list"],
|
|
298
|
+
params: "ChatsListParams"
|
|
299
|
+
) -> "ChatsListResult": ...
|
|
300
|
+
|
|
301
|
+
@overload
|
|
302
|
+
async def execute(
|
|
303
|
+
self,
|
|
304
|
+
entity: Literal["chats"],
|
|
305
|
+
action: Literal["get"],
|
|
306
|
+
params: "ChatsGetParams"
|
|
307
|
+
) -> "Chat": ...
|
|
308
|
+
|
|
309
|
+
@overload
|
|
310
|
+
async def execute(
|
|
311
|
+
self,
|
|
312
|
+
entity: Literal["departments"],
|
|
313
|
+
action: Literal["list"],
|
|
314
|
+
params: "DepartmentsListParams"
|
|
315
|
+
) -> "DepartmentsListResult": ...
|
|
316
|
+
|
|
317
|
+
@overload
|
|
318
|
+
async def execute(
|
|
319
|
+
self,
|
|
320
|
+
entity: Literal["departments"],
|
|
321
|
+
action: Literal["get"],
|
|
322
|
+
params: "DepartmentsGetParams"
|
|
323
|
+
) -> "Department": ...
|
|
324
|
+
|
|
325
|
+
@overload
|
|
326
|
+
async def execute(
|
|
327
|
+
self,
|
|
328
|
+
entity: Literal["goals"],
|
|
329
|
+
action: Literal["list"],
|
|
330
|
+
params: "GoalsListParams"
|
|
331
|
+
) -> "GoalsListResult": ...
|
|
332
|
+
|
|
333
|
+
@overload
|
|
334
|
+
async def execute(
|
|
335
|
+
self,
|
|
336
|
+
entity: Literal["goals"],
|
|
337
|
+
action: Literal["get"],
|
|
338
|
+
params: "GoalsGetParams"
|
|
339
|
+
) -> "Goal": ...
|
|
340
|
+
|
|
341
|
+
@overload
|
|
342
|
+
async def execute(
|
|
343
|
+
self,
|
|
344
|
+
entity: Literal["roles"],
|
|
345
|
+
action: Literal["list"],
|
|
346
|
+
params: "RolesListParams"
|
|
347
|
+
) -> "RolesListResult": ...
|
|
348
|
+
|
|
349
|
+
@overload
|
|
350
|
+
async def execute(
|
|
351
|
+
self,
|
|
352
|
+
entity: Literal["roles"],
|
|
353
|
+
action: Literal["get"],
|
|
354
|
+
params: "RolesGetParams"
|
|
355
|
+
) -> "Role": ...
|
|
356
|
+
|
|
357
|
+
@overload
|
|
358
|
+
async def execute(
|
|
359
|
+
self,
|
|
360
|
+
entity: Literal["routing_settings"],
|
|
361
|
+
action: Literal["get"],
|
|
362
|
+
params: "RoutingSettingsGetParams"
|
|
363
|
+
) -> "RoutingSettings": ...
|
|
364
|
+
|
|
365
|
+
@overload
|
|
366
|
+
async def execute(
|
|
367
|
+
self,
|
|
368
|
+
entity: Literal["shortcuts"],
|
|
369
|
+
action: Literal["list"],
|
|
370
|
+
params: "ShortcutsListParams"
|
|
371
|
+
) -> "ShortcutsListResult": ...
|
|
372
|
+
|
|
373
|
+
@overload
|
|
374
|
+
async def execute(
|
|
375
|
+
self,
|
|
376
|
+
entity: Literal["shortcuts"],
|
|
377
|
+
action: Literal["get"],
|
|
378
|
+
params: "ShortcutsGetParams"
|
|
379
|
+
) -> "Shortcut": ...
|
|
380
|
+
|
|
381
|
+
@overload
|
|
382
|
+
async def execute(
|
|
383
|
+
self,
|
|
384
|
+
entity: Literal["skills"],
|
|
385
|
+
action: Literal["list"],
|
|
386
|
+
params: "SkillsListParams"
|
|
387
|
+
) -> "SkillsListResult": ...
|
|
388
|
+
|
|
389
|
+
@overload
|
|
390
|
+
async def execute(
|
|
391
|
+
self,
|
|
392
|
+
entity: Literal["skills"],
|
|
393
|
+
action: Literal["get"],
|
|
394
|
+
params: "SkillsGetParams"
|
|
395
|
+
) -> "Skill": ...
|
|
396
|
+
|
|
397
|
+
@overload
|
|
398
|
+
async def execute(
|
|
399
|
+
self,
|
|
400
|
+
entity: Literal["triggers"],
|
|
401
|
+
action: Literal["list"],
|
|
402
|
+
params: "TriggersListParams"
|
|
403
|
+
) -> "TriggersListResult": ...
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
@overload
|
|
407
|
+
async def execute(
|
|
408
|
+
self,
|
|
409
|
+
entity: str,
|
|
410
|
+
action: str,
|
|
411
|
+
params: dict[str, Any]
|
|
412
|
+
) -> ZendeskChatExecuteResult[Any] | ZendeskChatExecuteResultWithMeta[Any, Any] | Any: ...
|
|
413
|
+
|
|
414
|
+
async def execute(
|
|
415
|
+
self,
|
|
416
|
+
entity: str,
|
|
417
|
+
action: str,
|
|
418
|
+
params: dict[str, Any] | None = None
|
|
419
|
+
) -> Any:
|
|
420
|
+
"""
|
|
421
|
+
Execute an entity operation with full type safety.
|
|
422
|
+
|
|
423
|
+
This is the recommended interface for blessed connectors as it:
|
|
424
|
+
- Uses the same signature as non-blessed connectors
|
|
425
|
+
- Provides full IDE autocomplete for entity/action/params
|
|
426
|
+
- Makes migration from generic to blessed connectors seamless
|
|
427
|
+
|
|
428
|
+
Args:
|
|
429
|
+
entity: Entity name (e.g., "customers")
|
|
430
|
+
action: Operation action (e.g., "create", "get", "list")
|
|
431
|
+
params: Operation parameters (typed based on entity+action)
|
|
432
|
+
|
|
433
|
+
Returns:
|
|
434
|
+
Typed response based on the operation
|
|
435
|
+
|
|
436
|
+
Example:
|
|
437
|
+
customer = await connector.execute(
|
|
438
|
+
entity="customers",
|
|
439
|
+
action="get",
|
|
440
|
+
params={"id": "cus_123"}
|
|
441
|
+
)
|
|
442
|
+
"""
|
|
443
|
+
from ._vendored.connector_sdk.executor import ExecutionConfig
|
|
444
|
+
|
|
445
|
+
# Remap parameter names from snake_case (TypedDict keys) to API parameter names
|
|
446
|
+
if params:
|
|
447
|
+
param_map = self._PARAM_MAP.get((entity, action), {})
|
|
448
|
+
if param_map:
|
|
449
|
+
params = {param_map.get(k, k): v for k, v in params.items()}
|
|
450
|
+
|
|
451
|
+
# Use ExecutionConfig for both local and hosted executors
|
|
452
|
+
config = ExecutionConfig(
|
|
453
|
+
entity=entity,
|
|
454
|
+
action=action,
|
|
455
|
+
params=params
|
|
456
|
+
)
|
|
457
|
+
|
|
458
|
+
result = await self._executor.execute(config)
|
|
459
|
+
|
|
460
|
+
if not result.success:
|
|
461
|
+
raise RuntimeError(f"Execution failed: {result.error}")
|
|
462
|
+
|
|
463
|
+
# Check if this operation has extractors configured
|
|
464
|
+
has_extractors = self._ENVELOPE_MAP.get((entity, action), False)
|
|
465
|
+
|
|
466
|
+
if has_extractors:
|
|
467
|
+
# With extractors - return Pydantic envelope with data and meta
|
|
468
|
+
if result.meta is not None:
|
|
469
|
+
return ZendeskChatExecuteResultWithMeta[Any, Any](
|
|
470
|
+
data=result.data,
|
|
471
|
+
meta=result.meta
|
|
472
|
+
)
|
|
473
|
+
else:
|
|
474
|
+
return ZendeskChatExecuteResult[Any](data=result.data)
|
|
475
|
+
else:
|
|
476
|
+
# No extractors - return raw response data
|
|
477
|
+
return result.data
|
|
478
|
+
|
|
479
|
+
# ===== INTROSPECTION METHODS =====
|
|
480
|
+
|
|
481
|
+
@classmethod
|
|
482
|
+
def describe(cls, func: _F) -> _F:
|
|
483
|
+
"""
|
|
484
|
+
Decorator that populates a function's docstring with connector capabilities.
|
|
485
|
+
|
|
486
|
+
This class method can be used as a decorator to automatically generate
|
|
487
|
+
comprehensive documentation for AI tool functions.
|
|
488
|
+
|
|
489
|
+
Usage:
|
|
490
|
+
@mcp.tool()
|
|
491
|
+
@ZendeskChatConnector.describe
|
|
492
|
+
async def execute(entity: str, action: str, params: dict):
|
|
493
|
+
'''Execute operations.'''
|
|
494
|
+
...
|
|
495
|
+
|
|
496
|
+
The decorated function's __doc__ will be updated with:
|
|
497
|
+
- Available entities and their actions
|
|
498
|
+
- Parameter signatures with required (*) and optional (?) markers
|
|
499
|
+
- Response structure documentation
|
|
500
|
+
- Example questions (if available in OpenAPI spec)
|
|
501
|
+
|
|
502
|
+
Args:
|
|
503
|
+
func: The function to decorate
|
|
504
|
+
|
|
505
|
+
Returns:
|
|
506
|
+
The same function with updated __doc__
|
|
507
|
+
"""
|
|
508
|
+
description = generate_tool_description(ZendeskChatConnectorModel)
|
|
509
|
+
|
|
510
|
+
original_doc = func.__doc__ or ""
|
|
511
|
+
if original_doc.strip():
|
|
512
|
+
func.__doc__ = f"{original_doc.strip()}\n{description}"
|
|
513
|
+
else:
|
|
514
|
+
func.__doc__ = description
|
|
515
|
+
|
|
516
|
+
return func
|
|
517
|
+
|
|
518
|
+
def list_entities(self) -> list[dict[str, Any]]:
|
|
519
|
+
"""
|
|
520
|
+
Get structured data about available entities, actions, and parameters.
|
|
521
|
+
|
|
522
|
+
Returns a list of entity descriptions with:
|
|
523
|
+
- entity_name: Name of the entity (e.g., "contacts", "deals")
|
|
524
|
+
- description: Entity description from the first endpoint
|
|
525
|
+
- available_actions: List of actions (e.g., ["list", "get", "create"])
|
|
526
|
+
- parameters: Dict mapping action -> list of parameter dicts
|
|
527
|
+
|
|
528
|
+
Example:
|
|
529
|
+
entities = connector.list_entities()
|
|
530
|
+
for entity in entities:
|
|
531
|
+
print(f"{entity['entity_name']}: {entity['available_actions']}")
|
|
532
|
+
"""
|
|
533
|
+
return describe_entities(ZendeskChatConnectorModel)
|
|
534
|
+
|
|
535
|
+
def entity_schema(self, entity: str) -> dict[str, Any] | None:
|
|
536
|
+
"""
|
|
537
|
+
Get the JSON schema for an entity.
|
|
538
|
+
|
|
539
|
+
Args:
|
|
540
|
+
entity: Entity name (e.g., "contacts", "companies")
|
|
541
|
+
|
|
542
|
+
Returns:
|
|
543
|
+
JSON schema dict describing the entity structure, or None if not found.
|
|
544
|
+
|
|
545
|
+
Example:
|
|
546
|
+
schema = connector.entity_schema("contacts")
|
|
547
|
+
if schema:
|
|
548
|
+
print(f"Contact properties: {list(schema.get('properties', {}).keys())}")
|
|
549
|
+
"""
|
|
550
|
+
entity_def = next(
|
|
551
|
+
(e for e in ZendeskChatConnectorModel.entities if e.name == entity),
|
|
552
|
+
None
|
|
553
|
+
)
|
|
554
|
+
if entity_def is None:
|
|
555
|
+
logging.getLogger(__name__).warning(
|
|
556
|
+
f"Entity '{entity}' not found. Available entities: "
|
|
557
|
+
f"{[e.name for e in ZendeskChatConnectorModel.entities]}"
|
|
558
|
+
)
|
|
559
|
+
return entity_def.entity_schema if entity_def else None
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
class AccountsQuery:
|
|
564
|
+
"""
|
|
565
|
+
Query class for Accounts entity operations.
|
|
566
|
+
"""
|
|
567
|
+
|
|
568
|
+
def __init__(self, connector: ZendeskChatConnector):
|
|
569
|
+
"""Initialize query with connector reference."""
|
|
570
|
+
self._connector = connector
|
|
571
|
+
|
|
572
|
+
async def get(
|
|
573
|
+
self,
|
|
574
|
+
**kwargs
|
|
575
|
+
) -> Account:
|
|
576
|
+
"""
|
|
577
|
+
Returns the account information for the authenticated user
|
|
578
|
+
|
|
579
|
+
Returns:
|
|
580
|
+
Account
|
|
581
|
+
"""
|
|
582
|
+
params = {k: v for k, v in {
|
|
583
|
+
**kwargs
|
|
584
|
+
}.items() if v is not None}
|
|
585
|
+
|
|
586
|
+
result = await self._connector.execute("accounts", "get", params)
|
|
587
|
+
return result
|
|
588
|
+
|
|
589
|
+
|
|
590
|
+
|
|
591
|
+
class AgentsQuery:
|
|
592
|
+
"""
|
|
593
|
+
Query class for Agents entity operations.
|
|
594
|
+
"""
|
|
595
|
+
|
|
596
|
+
def __init__(self, connector: ZendeskChatConnector):
|
|
597
|
+
"""Initialize query with connector reference."""
|
|
598
|
+
self._connector = connector
|
|
599
|
+
|
|
600
|
+
async def list(
|
|
601
|
+
self,
|
|
602
|
+
limit: int | None = None,
|
|
603
|
+
since_id: int | None = None,
|
|
604
|
+
**kwargs
|
|
605
|
+
) -> AgentsListResult:
|
|
606
|
+
"""
|
|
607
|
+
List all agents
|
|
608
|
+
|
|
609
|
+
Args:
|
|
610
|
+
limit: Parameter limit
|
|
611
|
+
since_id: Parameter since_id
|
|
612
|
+
**kwargs: Additional parameters
|
|
613
|
+
|
|
614
|
+
Returns:
|
|
615
|
+
AgentsListResult
|
|
616
|
+
"""
|
|
617
|
+
params = {k: v for k, v in {
|
|
618
|
+
"limit": limit,
|
|
619
|
+
"since_id": since_id,
|
|
620
|
+
**kwargs
|
|
621
|
+
}.items() if v is not None}
|
|
622
|
+
|
|
623
|
+
result = await self._connector.execute("agents", "list", params)
|
|
624
|
+
# Cast generic envelope to concrete typed result
|
|
625
|
+
return AgentsListResult(
|
|
626
|
+
data=result.data
|
|
627
|
+
)
|
|
628
|
+
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
async def get(
|
|
632
|
+
self,
|
|
633
|
+
agent_id: str,
|
|
634
|
+
**kwargs
|
|
635
|
+
) -> Agent:
|
|
636
|
+
"""
|
|
637
|
+
Get an agent
|
|
638
|
+
|
|
639
|
+
Args:
|
|
640
|
+
agent_id: Parameter agent_id
|
|
641
|
+
**kwargs: Additional parameters
|
|
642
|
+
|
|
643
|
+
Returns:
|
|
644
|
+
Agent
|
|
645
|
+
"""
|
|
646
|
+
params = {k: v for k, v in {
|
|
647
|
+
"agent_id": agent_id,
|
|
648
|
+
**kwargs
|
|
649
|
+
}.items() if v is not None}
|
|
650
|
+
|
|
651
|
+
result = await self._connector.execute("agents", "get", params)
|
|
652
|
+
return result
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
async def search(
|
|
657
|
+
self,
|
|
658
|
+
query: AgentsSearchQuery,
|
|
659
|
+
limit: int | None = None,
|
|
660
|
+
cursor: str | None = None,
|
|
661
|
+
fields: list[list[str]] | None = None,
|
|
662
|
+
) -> AgentsSearchResult:
|
|
663
|
+
"""
|
|
664
|
+
Search agents records from Airbyte cache.
|
|
665
|
+
|
|
666
|
+
This operation searches cached data from Airbyte syncs.
|
|
667
|
+
Only available in hosted execution mode.
|
|
668
|
+
|
|
669
|
+
Available filter fields (AgentsSearchFilter):
|
|
670
|
+
- id: Unique agent identifier
|
|
671
|
+
- email: Agent email address
|
|
672
|
+
- display_name: Agent display name
|
|
673
|
+
- first_name: Agent first name
|
|
674
|
+
- last_name: Agent last name
|
|
675
|
+
- enabled: Whether agent is enabled
|
|
676
|
+
- role_id: Agent role ID
|
|
677
|
+
- departments: Department IDs agent belongs to
|
|
678
|
+
- create_date: When agent was created
|
|
679
|
+
|
|
680
|
+
Args:
|
|
681
|
+
query: Filter and sort conditions. Supports operators like eq, neq, gt, gte, lt, lte,
|
|
682
|
+
in, like, fuzzy, keyword, not, and, or. Example: {"filter": {"eq": {"status": "active"}}}
|
|
683
|
+
limit: Maximum results to return (default 1000)
|
|
684
|
+
cursor: Pagination cursor from previous response's next_cursor
|
|
685
|
+
fields: Field paths to include in results. Each path is a list of keys for nested access.
|
|
686
|
+
Example: [["id"], ["user", "name"]] returns id and user.name fields.
|
|
687
|
+
|
|
688
|
+
Returns:
|
|
689
|
+
AgentsSearchResult with hits (list of AirbyteSearchHit[AgentsSearchData]) and pagination info
|
|
690
|
+
|
|
691
|
+
Raises:
|
|
692
|
+
NotImplementedError: If called in local execution mode
|
|
693
|
+
"""
|
|
694
|
+
params: dict[str, Any] = {"query": query}
|
|
695
|
+
if limit is not None:
|
|
696
|
+
params["limit"] = limit
|
|
697
|
+
if cursor is not None:
|
|
698
|
+
params["cursor"] = cursor
|
|
699
|
+
if fields is not None:
|
|
700
|
+
params["fields"] = fields
|
|
701
|
+
|
|
702
|
+
result = await self._connector.execute("agents", "search", params)
|
|
703
|
+
|
|
704
|
+
# Parse response into typed result
|
|
705
|
+
return AgentsSearchResult(
|
|
706
|
+
hits=[
|
|
707
|
+
AirbyteSearchHit[AgentsSearchData](
|
|
708
|
+
id=hit.get("id"),
|
|
709
|
+
score=hit.get("score"),
|
|
710
|
+
data=AgentsSearchData(**hit.get("data", {}))
|
|
711
|
+
)
|
|
712
|
+
for hit in result.get("hits", [])
|
|
713
|
+
],
|
|
714
|
+
next_cursor=result.get("next_cursor"),
|
|
715
|
+
took_ms=result.get("took_ms")
|
|
716
|
+
)
|
|
717
|
+
|
|
718
|
+
class AgentTimelineQuery:
|
|
719
|
+
"""
|
|
720
|
+
Query class for AgentTimeline entity operations.
|
|
721
|
+
"""
|
|
722
|
+
|
|
723
|
+
def __init__(self, connector: ZendeskChatConnector):
|
|
724
|
+
"""Initialize query with connector reference."""
|
|
725
|
+
self._connector = connector
|
|
726
|
+
|
|
727
|
+
async def list(
|
|
728
|
+
self,
|
|
729
|
+
start_time: int | None = None,
|
|
730
|
+
limit: int | None = None,
|
|
731
|
+
fields: str | None = None,
|
|
732
|
+
**kwargs
|
|
733
|
+
) -> AgentTimelineListResult:
|
|
734
|
+
"""
|
|
735
|
+
List agent timeline (incremental export)
|
|
736
|
+
|
|
737
|
+
Args:
|
|
738
|
+
start_time: Parameter start_time
|
|
739
|
+
limit: Parameter limit
|
|
740
|
+
fields: Parameter fields
|
|
741
|
+
**kwargs: Additional parameters
|
|
742
|
+
|
|
743
|
+
Returns:
|
|
744
|
+
AgentTimelineListResult
|
|
745
|
+
"""
|
|
746
|
+
params = {k: v for k, v in {
|
|
747
|
+
"start_time": start_time,
|
|
748
|
+
"limit": limit,
|
|
749
|
+
"fields": fields,
|
|
750
|
+
**kwargs
|
|
751
|
+
}.items() if v is not None}
|
|
752
|
+
|
|
753
|
+
result = await self._connector.execute("agent_timeline", "list", params)
|
|
754
|
+
# Cast generic envelope to concrete typed result
|
|
755
|
+
return AgentTimelineListResult(
|
|
756
|
+
data=result.data,
|
|
757
|
+
meta=result.meta
|
|
758
|
+
)
|
|
759
|
+
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
class BansQuery:
|
|
763
|
+
"""
|
|
764
|
+
Query class for Bans entity operations.
|
|
765
|
+
"""
|
|
766
|
+
|
|
767
|
+
def __init__(self, connector: ZendeskChatConnector):
|
|
768
|
+
"""Initialize query with connector reference."""
|
|
769
|
+
self._connector = connector
|
|
770
|
+
|
|
771
|
+
async def list(
|
|
772
|
+
self,
|
|
773
|
+
limit: int | None = None,
|
|
774
|
+
since_id: int | None = None,
|
|
775
|
+
**kwargs
|
|
776
|
+
) -> BansListResult:
|
|
777
|
+
"""
|
|
778
|
+
List all bans
|
|
779
|
+
|
|
780
|
+
Args:
|
|
781
|
+
limit: Parameter limit
|
|
782
|
+
since_id: Parameter since_id
|
|
783
|
+
**kwargs: Additional parameters
|
|
784
|
+
|
|
785
|
+
Returns:
|
|
786
|
+
BansListResult
|
|
787
|
+
"""
|
|
788
|
+
params = {k: v for k, v in {
|
|
789
|
+
"limit": limit,
|
|
790
|
+
"since_id": since_id,
|
|
791
|
+
**kwargs
|
|
792
|
+
}.items() if v is not None}
|
|
793
|
+
|
|
794
|
+
result = await self._connector.execute("bans", "list", params)
|
|
795
|
+
# Cast generic envelope to concrete typed result
|
|
796
|
+
return BansListResult(
|
|
797
|
+
data=result.data
|
|
798
|
+
)
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
async def get(
|
|
803
|
+
self,
|
|
804
|
+
ban_id: str,
|
|
805
|
+
**kwargs
|
|
806
|
+
) -> Ban:
|
|
807
|
+
"""
|
|
808
|
+
Get a ban
|
|
809
|
+
|
|
810
|
+
Args:
|
|
811
|
+
ban_id: Parameter ban_id
|
|
812
|
+
**kwargs: Additional parameters
|
|
813
|
+
|
|
814
|
+
Returns:
|
|
815
|
+
Ban
|
|
816
|
+
"""
|
|
817
|
+
params = {k: v for k, v in {
|
|
818
|
+
"ban_id": ban_id,
|
|
819
|
+
**kwargs
|
|
820
|
+
}.items() if v is not None}
|
|
821
|
+
|
|
822
|
+
result = await self._connector.execute("bans", "get", params)
|
|
823
|
+
return result
|
|
824
|
+
|
|
825
|
+
|
|
826
|
+
|
|
827
|
+
class ChatsQuery:
|
|
828
|
+
"""
|
|
829
|
+
Query class for Chats entity operations.
|
|
830
|
+
"""
|
|
831
|
+
|
|
832
|
+
def __init__(self, connector: ZendeskChatConnector):
|
|
833
|
+
"""Initialize query with connector reference."""
|
|
834
|
+
self._connector = connector
|
|
835
|
+
|
|
836
|
+
async def list(
|
|
837
|
+
self,
|
|
838
|
+
start_time: int | None = None,
|
|
839
|
+
limit: int | None = None,
|
|
840
|
+
fields: str | None = None,
|
|
841
|
+
**kwargs
|
|
842
|
+
) -> ChatsListResult:
|
|
843
|
+
"""
|
|
844
|
+
List chats (incremental export)
|
|
845
|
+
|
|
846
|
+
Args:
|
|
847
|
+
start_time: Parameter start_time
|
|
848
|
+
limit: Parameter limit
|
|
849
|
+
fields: Parameter fields
|
|
850
|
+
**kwargs: Additional parameters
|
|
851
|
+
|
|
852
|
+
Returns:
|
|
853
|
+
ChatsListResult
|
|
854
|
+
"""
|
|
855
|
+
params = {k: v for k, v in {
|
|
856
|
+
"start_time": start_time,
|
|
857
|
+
"limit": limit,
|
|
858
|
+
"fields": fields,
|
|
859
|
+
**kwargs
|
|
860
|
+
}.items() if v is not None}
|
|
861
|
+
|
|
862
|
+
result = await self._connector.execute("chats", "list", params)
|
|
863
|
+
# Cast generic envelope to concrete typed result
|
|
864
|
+
return ChatsListResult(
|
|
865
|
+
data=result.data,
|
|
866
|
+
meta=result.meta
|
|
867
|
+
)
|
|
868
|
+
|
|
869
|
+
|
|
870
|
+
|
|
871
|
+
async def get(
|
|
872
|
+
self,
|
|
873
|
+
chat_id: str,
|
|
874
|
+
**kwargs
|
|
875
|
+
) -> Chat:
|
|
876
|
+
"""
|
|
877
|
+
Get a chat
|
|
878
|
+
|
|
879
|
+
Args:
|
|
880
|
+
chat_id: Parameter chat_id
|
|
881
|
+
**kwargs: Additional parameters
|
|
882
|
+
|
|
883
|
+
Returns:
|
|
884
|
+
Chat
|
|
885
|
+
"""
|
|
886
|
+
params = {k: v for k, v in {
|
|
887
|
+
"chat_id": chat_id,
|
|
888
|
+
**kwargs
|
|
889
|
+
}.items() if v is not None}
|
|
890
|
+
|
|
891
|
+
result = await self._connector.execute("chats", "get", params)
|
|
892
|
+
return result
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
|
|
896
|
+
async def search(
|
|
897
|
+
self,
|
|
898
|
+
query: ChatsSearchQuery,
|
|
899
|
+
limit: int | None = None,
|
|
900
|
+
cursor: str | None = None,
|
|
901
|
+
fields: list[list[str]] | None = None,
|
|
902
|
+
) -> ChatsSearchResult:
|
|
903
|
+
"""
|
|
904
|
+
Search chats records from Airbyte cache.
|
|
905
|
+
|
|
906
|
+
This operation searches cached data from Airbyte syncs.
|
|
907
|
+
Only available in hosted execution mode.
|
|
908
|
+
|
|
909
|
+
Available filter fields (ChatsSearchFilter):
|
|
910
|
+
- id: Unique chat identifier
|
|
911
|
+
- timestamp: Chat start timestamp
|
|
912
|
+
- update_timestamp: Last update timestamp
|
|
913
|
+
- department_id: Department ID
|
|
914
|
+
- department_name: Department name
|
|
915
|
+
- duration: Chat duration in seconds
|
|
916
|
+
- rating: Satisfaction rating
|
|
917
|
+
- missed: Whether chat was missed
|
|
918
|
+
- agent_ids: IDs of agents in chat
|
|
919
|
+
|
|
920
|
+
Args:
|
|
921
|
+
query: Filter and sort conditions. Supports operators like eq, neq, gt, gte, lt, lte,
|
|
922
|
+
in, like, fuzzy, keyword, not, and, or. Example: {"filter": {"eq": {"status": "active"}}}
|
|
923
|
+
limit: Maximum results to return (default 1000)
|
|
924
|
+
cursor: Pagination cursor from previous response's next_cursor
|
|
925
|
+
fields: Field paths to include in results. Each path is a list of keys for nested access.
|
|
926
|
+
Example: [["id"], ["user", "name"]] returns id and user.name fields.
|
|
927
|
+
|
|
928
|
+
Returns:
|
|
929
|
+
ChatsSearchResult with hits (list of AirbyteSearchHit[ChatsSearchData]) and pagination info
|
|
930
|
+
|
|
931
|
+
Raises:
|
|
932
|
+
NotImplementedError: If called in local execution mode
|
|
933
|
+
"""
|
|
934
|
+
params: dict[str, Any] = {"query": query}
|
|
935
|
+
if limit is not None:
|
|
936
|
+
params["limit"] = limit
|
|
937
|
+
if cursor is not None:
|
|
938
|
+
params["cursor"] = cursor
|
|
939
|
+
if fields is not None:
|
|
940
|
+
params["fields"] = fields
|
|
941
|
+
|
|
942
|
+
result = await self._connector.execute("chats", "search", params)
|
|
943
|
+
|
|
944
|
+
# Parse response into typed result
|
|
945
|
+
return ChatsSearchResult(
|
|
946
|
+
hits=[
|
|
947
|
+
AirbyteSearchHit[ChatsSearchData](
|
|
948
|
+
id=hit.get("id"),
|
|
949
|
+
score=hit.get("score"),
|
|
950
|
+
data=ChatsSearchData(**hit.get("data", {}))
|
|
951
|
+
)
|
|
952
|
+
for hit in result.get("hits", [])
|
|
953
|
+
],
|
|
954
|
+
next_cursor=result.get("next_cursor"),
|
|
955
|
+
took_ms=result.get("took_ms")
|
|
956
|
+
)
|
|
957
|
+
|
|
958
|
+
class DepartmentsQuery:
|
|
959
|
+
"""
|
|
960
|
+
Query class for Departments entity operations.
|
|
961
|
+
"""
|
|
962
|
+
|
|
963
|
+
def __init__(self, connector: ZendeskChatConnector):
|
|
964
|
+
"""Initialize query with connector reference."""
|
|
965
|
+
self._connector = connector
|
|
966
|
+
|
|
967
|
+
async def list(
|
|
968
|
+
self,
|
|
969
|
+
**kwargs
|
|
970
|
+
) -> DepartmentsListResult:
|
|
971
|
+
"""
|
|
972
|
+
List all departments
|
|
973
|
+
|
|
974
|
+
Returns:
|
|
975
|
+
DepartmentsListResult
|
|
976
|
+
"""
|
|
977
|
+
params = {k: v for k, v in {
|
|
978
|
+
**kwargs
|
|
979
|
+
}.items() if v is not None}
|
|
980
|
+
|
|
981
|
+
result = await self._connector.execute("departments", "list", params)
|
|
982
|
+
# Cast generic envelope to concrete typed result
|
|
983
|
+
return DepartmentsListResult(
|
|
984
|
+
data=result.data
|
|
985
|
+
)
|
|
986
|
+
|
|
987
|
+
|
|
988
|
+
|
|
989
|
+
async def get(
|
|
990
|
+
self,
|
|
991
|
+
department_id: str,
|
|
992
|
+
**kwargs
|
|
993
|
+
) -> Department:
|
|
994
|
+
"""
|
|
995
|
+
Get a department
|
|
996
|
+
|
|
997
|
+
Args:
|
|
998
|
+
department_id: Parameter department_id
|
|
999
|
+
**kwargs: Additional parameters
|
|
1000
|
+
|
|
1001
|
+
Returns:
|
|
1002
|
+
Department
|
|
1003
|
+
"""
|
|
1004
|
+
params = {k: v for k, v in {
|
|
1005
|
+
"department_id": department_id,
|
|
1006
|
+
**kwargs
|
|
1007
|
+
}.items() if v is not None}
|
|
1008
|
+
|
|
1009
|
+
result = await self._connector.execute("departments", "get", params)
|
|
1010
|
+
return result
|
|
1011
|
+
|
|
1012
|
+
|
|
1013
|
+
|
|
1014
|
+
async def search(
|
|
1015
|
+
self,
|
|
1016
|
+
query: DepartmentsSearchQuery,
|
|
1017
|
+
limit: int | None = None,
|
|
1018
|
+
cursor: str | None = None,
|
|
1019
|
+
fields: list[list[str]] | None = None,
|
|
1020
|
+
) -> DepartmentsSearchResult:
|
|
1021
|
+
"""
|
|
1022
|
+
Search departments records from Airbyte cache.
|
|
1023
|
+
|
|
1024
|
+
This operation searches cached data from Airbyte syncs.
|
|
1025
|
+
Only available in hosted execution mode.
|
|
1026
|
+
|
|
1027
|
+
Available filter fields (DepartmentsSearchFilter):
|
|
1028
|
+
- id: Department ID
|
|
1029
|
+
- name: Department name
|
|
1030
|
+
- enabled: Whether department is enabled
|
|
1031
|
+
- members: Agent IDs in department
|
|
1032
|
+
|
|
1033
|
+
Args:
|
|
1034
|
+
query: Filter and sort conditions. Supports operators like eq, neq, gt, gte, lt, lte,
|
|
1035
|
+
in, like, fuzzy, keyword, not, and, or. Example: {"filter": {"eq": {"status": "active"}}}
|
|
1036
|
+
limit: Maximum results to return (default 1000)
|
|
1037
|
+
cursor: Pagination cursor from previous response's next_cursor
|
|
1038
|
+
fields: Field paths to include in results. Each path is a list of keys for nested access.
|
|
1039
|
+
Example: [["id"], ["user", "name"]] returns id and user.name fields.
|
|
1040
|
+
|
|
1041
|
+
Returns:
|
|
1042
|
+
DepartmentsSearchResult with hits (list of AirbyteSearchHit[DepartmentsSearchData]) and pagination info
|
|
1043
|
+
|
|
1044
|
+
Raises:
|
|
1045
|
+
NotImplementedError: If called in local execution mode
|
|
1046
|
+
"""
|
|
1047
|
+
params: dict[str, Any] = {"query": query}
|
|
1048
|
+
if limit is not None:
|
|
1049
|
+
params["limit"] = limit
|
|
1050
|
+
if cursor is not None:
|
|
1051
|
+
params["cursor"] = cursor
|
|
1052
|
+
if fields is not None:
|
|
1053
|
+
params["fields"] = fields
|
|
1054
|
+
|
|
1055
|
+
result = await self._connector.execute("departments", "search", params)
|
|
1056
|
+
|
|
1057
|
+
# Parse response into typed result
|
|
1058
|
+
return DepartmentsSearchResult(
|
|
1059
|
+
hits=[
|
|
1060
|
+
AirbyteSearchHit[DepartmentsSearchData](
|
|
1061
|
+
id=hit.get("id"),
|
|
1062
|
+
score=hit.get("score"),
|
|
1063
|
+
data=DepartmentsSearchData(**hit.get("data", {}))
|
|
1064
|
+
)
|
|
1065
|
+
for hit in result.get("hits", [])
|
|
1066
|
+
],
|
|
1067
|
+
next_cursor=result.get("next_cursor"),
|
|
1068
|
+
took_ms=result.get("took_ms")
|
|
1069
|
+
)
|
|
1070
|
+
|
|
1071
|
+
class GoalsQuery:
|
|
1072
|
+
"""
|
|
1073
|
+
Query class for Goals entity operations.
|
|
1074
|
+
"""
|
|
1075
|
+
|
|
1076
|
+
def __init__(self, connector: ZendeskChatConnector):
|
|
1077
|
+
"""Initialize query with connector reference."""
|
|
1078
|
+
self._connector = connector
|
|
1079
|
+
|
|
1080
|
+
async def list(
|
|
1081
|
+
self,
|
|
1082
|
+
**kwargs
|
|
1083
|
+
) -> GoalsListResult:
|
|
1084
|
+
"""
|
|
1085
|
+
List all goals
|
|
1086
|
+
|
|
1087
|
+
Returns:
|
|
1088
|
+
GoalsListResult
|
|
1089
|
+
"""
|
|
1090
|
+
params = {k: v for k, v in {
|
|
1091
|
+
**kwargs
|
|
1092
|
+
}.items() if v is not None}
|
|
1093
|
+
|
|
1094
|
+
result = await self._connector.execute("goals", "list", params)
|
|
1095
|
+
# Cast generic envelope to concrete typed result
|
|
1096
|
+
return GoalsListResult(
|
|
1097
|
+
data=result.data
|
|
1098
|
+
)
|
|
1099
|
+
|
|
1100
|
+
|
|
1101
|
+
|
|
1102
|
+
async def get(
|
|
1103
|
+
self,
|
|
1104
|
+
goal_id: str,
|
|
1105
|
+
**kwargs
|
|
1106
|
+
) -> Goal:
|
|
1107
|
+
"""
|
|
1108
|
+
Get a goal
|
|
1109
|
+
|
|
1110
|
+
Args:
|
|
1111
|
+
goal_id: Parameter goal_id
|
|
1112
|
+
**kwargs: Additional parameters
|
|
1113
|
+
|
|
1114
|
+
Returns:
|
|
1115
|
+
Goal
|
|
1116
|
+
"""
|
|
1117
|
+
params = {k: v for k, v in {
|
|
1118
|
+
"goal_id": goal_id,
|
|
1119
|
+
**kwargs
|
|
1120
|
+
}.items() if v is not None}
|
|
1121
|
+
|
|
1122
|
+
result = await self._connector.execute("goals", "get", params)
|
|
1123
|
+
return result
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
|
|
1127
|
+
class RolesQuery:
|
|
1128
|
+
"""
|
|
1129
|
+
Query class for Roles entity operations.
|
|
1130
|
+
"""
|
|
1131
|
+
|
|
1132
|
+
def __init__(self, connector: ZendeskChatConnector):
|
|
1133
|
+
"""Initialize query with connector reference."""
|
|
1134
|
+
self._connector = connector
|
|
1135
|
+
|
|
1136
|
+
async def list(
|
|
1137
|
+
self,
|
|
1138
|
+
**kwargs
|
|
1139
|
+
) -> RolesListResult:
|
|
1140
|
+
"""
|
|
1141
|
+
List all roles
|
|
1142
|
+
|
|
1143
|
+
Returns:
|
|
1144
|
+
RolesListResult
|
|
1145
|
+
"""
|
|
1146
|
+
params = {k: v for k, v in {
|
|
1147
|
+
**kwargs
|
|
1148
|
+
}.items() if v is not None}
|
|
1149
|
+
|
|
1150
|
+
result = await self._connector.execute("roles", "list", params)
|
|
1151
|
+
# Cast generic envelope to concrete typed result
|
|
1152
|
+
return RolesListResult(
|
|
1153
|
+
data=result.data
|
|
1154
|
+
)
|
|
1155
|
+
|
|
1156
|
+
|
|
1157
|
+
|
|
1158
|
+
async def get(
|
|
1159
|
+
self,
|
|
1160
|
+
role_id: str,
|
|
1161
|
+
**kwargs
|
|
1162
|
+
) -> Role:
|
|
1163
|
+
"""
|
|
1164
|
+
Get a role
|
|
1165
|
+
|
|
1166
|
+
Args:
|
|
1167
|
+
role_id: Parameter role_id
|
|
1168
|
+
**kwargs: Additional parameters
|
|
1169
|
+
|
|
1170
|
+
Returns:
|
|
1171
|
+
Role
|
|
1172
|
+
"""
|
|
1173
|
+
params = {k: v for k, v in {
|
|
1174
|
+
"role_id": role_id,
|
|
1175
|
+
**kwargs
|
|
1176
|
+
}.items() if v is not None}
|
|
1177
|
+
|
|
1178
|
+
result = await self._connector.execute("roles", "get", params)
|
|
1179
|
+
return result
|
|
1180
|
+
|
|
1181
|
+
|
|
1182
|
+
|
|
1183
|
+
class RoutingSettingsQuery:
|
|
1184
|
+
"""
|
|
1185
|
+
Query class for RoutingSettings entity operations.
|
|
1186
|
+
"""
|
|
1187
|
+
|
|
1188
|
+
def __init__(self, connector: ZendeskChatConnector):
|
|
1189
|
+
"""Initialize query with connector reference."""
|
|
1190
|
+
self._connector = connector
|
|
1191
|
+
|
|
1192
|
+
async def get(
|
|
1193
|
+
self,
|
|
1194
|
+
**kwargs
|
|
1195
|
+
) -> RoutingSettings:
|
|
1196
|
+
"""
|
|
1197
|
+
Get routing settings
|
|
1198
|
+
|
|
1199
|
+
Returns:
|
|
1200
|
+
RoutingSettings
|
|
1201
|
+
"""
|
|
1202
|
+
params = {k: v for k, v in {
|
|
1203
|
+
**kwargs
|
|
1204
|
+
}.items() if v is not None}
|
|
1205
|
+
|
|
1206
|
+
result = await self._connector.execute("routing_settings", "get", params)
|
|
1207
|
+
return result
|
|
1208
|
+
|
|
1209
|
+
|
|
1210
|
+
|
|
1211
|
+
class ShortcutsQuery:
|
|
1212
|
+
"""
|
|
1213
|
+
Query class for Shortcuts entity operations.
|
|
1214
|
+
"""
|
|
1215
|
+
|
|
1216
|
+
def __init__(self, connector: ZendeskChatConnector):
|
|
1217
|
+
"""Initialize query with connector reference."""
|
|
1218
|
+
self._connector = connector
|
|
1219
|
+
|
|
1220
|
+
async def list(
|
|
1221
|
+
self,
|
|
1222
|
+
**kwargs
|
|
1223
|
+
) -> ShortcutsListResult:
|
|
1224
|
+
"""
|
|
1225
|
+
List all shortcuts
|
|
1226
|
+
|
|
1227
|
+
Returns:
|
|
1228
|
+
ShortcutsListResult
|
|
1229
|
+
"""
|
|
1230
|
+
params = {k: v for k, v in {
|
|
1231
|
+
**kwargs
|
|
1232
|
+
}.items() if v is not None}
|
|
1233
|
+
|
|
1234
|
+
result = await self._connector.execute("shortcuts", "list", params)
|
|
1235
|
+
# Cast generic envelope to concrete typed result
|
|
1236
|
+
return ShortcutsListResult(
|
|
1237
|
+
data=result.data
|
|
1238
|
+
)
|
|
1239
|
+
|
|
1240
|
+
|
|
1241
|
+
|
|
1242
|
+
async def get(
|
|
1243
|
+
self,
|
|
1244
|
+
shortcut_id: str,
|
|
1245
|
+
**kwargs
|
|
1246
|
+
) -> Shortcut:
|
|
1247
|
+
"""
|
|
1248
|
+
Get a shortcut
|
|
1249
|
+
|
|
1250
|
+
Args:
|
|
1251
|
+
shortcut_id: Parameter shortcut_id
|
|
1252
|
+
**kwargs: Additional parameters
|
|
1253
|
+
|
|
1254
|
+
Returns:
|
|
1255
|
+
Shortcut
|
|
1256
|
+
"""
|
|
1257
|
+
params = {k: v for k, v in {
|
|
1258
|
+
"shortcut_id": shortcut_id,
|
|
1259
|
+
**kwargs
|
|
1260
|
+
}.items() if v is not None}
|
|
1261
|
+
|
|
1262
|
+
result = await self._connector.execute("shortcuts", "get", params)
|
|
1263
|
+
return result
|
|
1264
|
+
|
|
1265
|
+
|
|
1266
|
+
|
|
1267
|
+
async def search(
|
|
1268
|
+
self,
|
|
1269
|
+
query: ShortcutsSearchQuery,
|
|
1270
|
+
limit: int | None = None,
|
|
1271
|
+
cursor: str | None = None,
|
|
1272
|
+
fields: list[list[str]] | None = None,
|
|
1273
|
+
) -> ShortcutsSearchResult:
|
|
1274
|
+
"""
|
|
1275
|
+
Search shortcuts records from Airbyte cache.
|
|
1276
|
+
|
|
1277
|
+
This operation searches cached data from Airbyte syncs.
|
|
1278
|
+
Only available in hosted execution mode.
|
|
1279
|
+
|
|
1280
|
+
Available filter fields (ShortcutsSearchFilter):
|
|
1281
|
+
- id: Shortcut ID
|
|
1282
|
+
- name: Shortcut name/trigger
|
|
1283
|
+
- message: Shortcut message content
|
|
1284
|
+
- tags: Tags applied when shortcut is used
|
|
1285
|
+
|
|
1286
|
+
Args:
|
|
1287
|
+
query: Filter and sort conditions. Supports operators like eq, neq, gt, gte, lt, lte,
|
|
1288
|
+
in, like, fuzzy, keyword, not, and, or. Example: {"filter": {"eq": {"status": "active"}}}
|
|
1289
|
+
limit: Maximum results to return (default 1000)
|
|
1290
|
+
cursor: Pagination cursor from previous response's next_cursor
|
|
1291
|
+
fields: Field paths to include in results. Each path is a list of keys for nested access.
|
|
1292
|
+
Example: [["id"], ["user", "name"]] returns id and user.name fields.
|
|
1293
|
+
|
|
1294
|
+
Returns:
|
|
1295
|
+
ShortcutsSearchResult with hits (list of AirbyteSearchHit[ShortcutsSearchData]) and pagination info
|
|
1296
|
+
|
|
1297
|
+
Raises:
|
|
1298
|
+
NotImplementedError: If called in local execution mode
|
|
1299
|
+
"""
|
|
1300
|
+
params: dict[str, Any] = {"query": query}
|
|
1301
|
+
if limit is not None:
|
|
1302
|
+
params["limit"] = limit
|
|
1303
|
+
if cursor is not None:
|
|
1304
|
+
params["cursor"] = cursor
|
|
1305
|
+
if fields is not None:
|
|
1306
|
+
params["fields"] = fields
|
|
1307
|
+
|
|
1308
|
+
result = await self._connector.execute("shortcuts", "search", params)
|
|
1309
|
+
|
|
1310
|
+
# Parse response into typed result
|
|
1311
|
+
return ShortcutsSearchResult(
|
|
1312
|
+
hits=[
|
|
1313
|
+
AirbyteSearchHit[ShortcutsSearchData](
|
|
1314
|
+
id=hit.get("id"),
|
|
1315
|
+
score=hit.get("score"),
|
|
1316
|
+
data=ShortcutsSearchData(**hit.get("data", {}))
|
|
1317
|
+
)
|
|
1318
|
+
for hit in result.get("hits", [])
|
|
1319
|
+
],
|
|
1320
|
+
next_cursor=result.get("next_cursor"),
|
|
1321
|
+
took_ms=result.get("took_ms")
|
|
1322
|
+
)
|
|
1323
|
+
|
|
1324
|
+
class SkillsQuery:
|
|
1325
|
+
"""
|
|
1326
|
+
Query class for Skills entity operations.
|
|
1327
|
+
"""
|
|
1328
|
+
|
|
1329
|
+
def __init__(self, connector: ZendeskChatConnector):
|
|
1330
|
+
"""Initialize query with connector reference."""
|
|
1331
|
+
self._connector = connector
|
|
1332
|
+
|
|
1333
|
+
async def list(
|
|
1334
|
+
self,
|
|
1335
|
+
**kwargs
|
|
1336
|
+
) -> SkillsListResult:
|
|
1337
|
+
"""
|
|
1338
|
+
List all skills
|
|
1339
|
+
|
|
1340
|
+
Returns:
|
|
1341
|
+
SkillsListResult
|
|
1342
|
+
"""
|
|
1343
|
+
params = {k: v for k, v in {
|
|
1344
|
+
**kwargs
|
|
1345
|
+
}.items() if v is not None}
|
|
1346
|
+
|
|
1347
|
+
result = await self._connector.execute("skills", "list", params)
|
|
1348
|
+
# Cast generic envelope to concrete typed result
|
|
1349
|
+
return SkillsListResult(
|
|
1350
|
+
data=result.data
|
|
1351
|
+
)
|
|
1352
|
+
|
|
1353
|
+
|
|
1354
|
+
|
|
1355
|
+
async def get(
|
|
1356
|
+
self,
|
|
1357
|
+
skill_id: str,
|
|
1358
|
+
**kwargs
|
|
1359
|
+
) -> Skill:
|
|
1360
|
+
"""
|
|
1361
|
+
Get a skill
|
|
1362
|
+
|
|
1363
|
+
Args:
|
|
1364
|
+
skill_id: Parameter skill_id
|
|
1365
|
+
**kwargs: Additional parameters
|
|
1366
|
+
|
|
1367
|
+
Returns:
|
|
1368
|
+
Skill
|
|
1369
|
+
"""
|
|
1370
|
+
params = {k: v for k, v in {
|
|
1371
|
+
"skill_id": skill_id,
|
|
1372
|
+
**kwargs
|
|
1373
|
+
}.items() if v is not None}
|
|
1374
|
+
|
|
1375
|
+
result = await self._connector.execute("skills", "get", params)
|
|
1376
|
+
return result
|
|
1377
|
+
|
|
1378
|
+
|
|
1379
|
+
|
|
1380
|
+
class TriggersQuery:
|
|
1381
|
+
"""
|
|
1382
|
+
Query class for Triggers entity operations.
|
|
1383
|
+
"""
|
|
1384
|
+
|
|
1385
|
+
def __init__(self, connector: ZendeskChatConnector):
|
|
1386
|
+
"""Initialize query with connector reference."""
|
|
1387
|
+
self._connector = connector
|
|
1388
|
+
|
|
1389
|
+
async def list(
|
|
1390
|
+
self,
|
|
1391
|
+
**kwargs
|
|
1392
|
+
) -> TriggersListResult:
|
|
1393
|
+
"""
|
|
1394
|
+
List all triggers
|
|
1395
|
+
|
|
1396
|
+
Returns:
|
|
1397
|
+
TriggersListResult
|
|
1398
|
+
"""
|
|
1399
|
+
params = {k: v for k, v in {
|
|
1400
|
+
**kwargs
|
|
1401
|
+
}.items() if v is not None}
|
|
1402
|
+
|
|
1403
|
+
result = await self._connector.execute("triggers", "list", params)
|
|
1404
|
+
# Cast generic envelope to concrete typed result
|
|
1405
|
+
return TriggersListResult(
|
|
1406
|
+
data=result.data
|
|
1407
|
+
)
|
|
1408
|
+
|
|
1409
|
+
|
|
1410
|
+
|
|
1411
|
+
async def search(
|
|
1412
|
+
self,
|
|
1413
|
+
query: TriggersSearchQuery,
|
|
1414
|
+
limit: int | None = None,
|
|
1415
|
+
cursor: str | None = None,
|
|
1416
|
+
fields: list[list[str]] | None = None,
|
|
1417
|
+
) -> TriggersSearchResult:
|
|
1418
|
+
"""
|
|
1419
|
+
Search triggers records from Airbyte cache.
|
|
1420
|
+
|
|
1421
|
+
This operation searches cached data from Airbyte syncs.
|
|
1422
|
+
Only available in hosted execution mode.
|
|
1423
|
+
|
|
1424
|
+
Available filter fields (TriggersSearchFilter):
|
|
1425
|
+
- id: Trigger ID
|
|
1426
|
+
- name: Trigger name
|
|
1427
|
+
- enabled: Whether trigger is enabled
|
|
1428
|
+
|
|
1429
|
+
Args:
|
|
1430
|
+
query: Filter and sort conditions. Supports operators like eq, neq, gt, gte, lt, lte,
|
|
1431
|
+
in, like, fuzzy, keyword, not, and, or. Example: {"filter": {"eq": {"status": "active"}}}
|
|
1432
|
+
limit: Maximum results to return (default 1000)
|
|
1433
|
+
cursor: Pagination cursor from previous response's next_cursor
|
|
1434
|
+
fields: Field paths to include in results. Each path is a list of keys for nested access.
|
|
1435
|
+
Example: [["id"], ["user", "name"]] returns id and user.name fields.
|
|
1436
|
+
|
|
1437
|
+
Returns:
|
|
1438
|
+
TriggersSearchResult with hits (list of AirbyteSearchHit[TriggersSearchData]) and pagination info
|
|
1439
|
+
|
|
1440
|
+
Raises:
|
|
1441
|
+
NotImplementedError: If called in local execution mode
|
|
1442
|
+
"""
|
|
1443
|
+
params: dict[str, Any] = {"query": query}
|
|
1444
|
+
if limit is not None:
|
|
1445
|
+
params["limit"] = limit
|
|
1446
|
+
if cursor is not None:
|
|
1447
|
+
params["cursor"] = cursor
|
|
1448
|
+
if fields is not None:
|
|
1449
|
+
params["fields"] = fields
|
|
1450
|
+
|
|
1451
|
+
result = await self._connector.execute("triggers", "search", params)
|
|
1452
|
+
|
|
1453
|
+
# Parse response into typed result
|
|
1454
|
+
return TriggersSearchResult(
|
|
1455
|
+
hits=[
|
|
1456
|
+
AirbyteSearchHit[TriggersSearchData](
|
|
1457
|
+
id=hit.get("id"),
|
|
1458
|
+
score=hit.get("score"),
|
|
1459
|
+
data=TriggersSearchData(**hit.get("data", {}))
|
|
1460
|
+
)
|
|
1461
|
+
for hit in result.get("hits", [])
|
|
1462
|
+
],
|
|
1463
|
+
next_cursor=result.get("next_cursor"),
|
|
1464
|
+
took_ms=result.get("took_ms")
|
|
1465
|
+
)
|