airbyte-agent-slack 0.1.15__py3-none-any.whl → 0.1.24__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.
- airbyte_agent_slack/__init__.py +32 -4
- airbyte_agent_slack/_vendored/connector_sdk/auth_strategies.py +1 -3
- airbyte_agent_slack/_vendored/connector_sdk/connector_model_loader.py +138 -0
- airbyte_agent_slack/_vendored/connector_sdk/executor/local_executor.py +4 -4
- airbyte_agent_slack/_vendored/connector_sdk/introspection.py +222 -10
- airbyte_agent_slack/_vendored/connector_sdk/schema/base.py +34 -2
- airbyte_agent_slack/_vendored/connector_sdk/schema/components.py +5 -0
- airbyte_agent_slack/_vendored/connector_sdk/schema/extensions.py +71 -0
- airbyte_agent_slack/_vendored/connector_sdk/types.py +1 -0
- airbyte_agent_slack/connector.py +266 -33
- airbyte_agent_slack/connector_model.py +106 -6
- airbyte_agent_slack/models.py +169 -9
- airbyte_agent_slack/types.py +785 -0
- {airbyte_agent_slack-0.1.15.dist-info → airbyte_agent_slack-0.1.24.dist-info}/METADATA +12 -8
- {airbyte_agent_slack-0.1.15.dist-info → airbyte_agent_slack-0.1.24.dist-info}/RECORD +16 -16
- {airbyte_agent_slack-0.1.15.dist-info → airbyte_agent_slack-0.1.24.dist-info}/WHEEL +0 -0
|
@@ -182,6 +182,77 @@ class CacheEntityConfig(BaseModel):
|
|
|
182
182
|
return self.x_airbyte_name or self.entity
|
|
183
183
|
|
|
184
184
|
|
|
185
|
+
class ReplicationConfigProperty(BaseModel):
|
|
186
|
+
"""
|
|
187
|
+
Property definition for replication configuration fields.
|
|
188
|
+
|
|
189
|
+
Defines a single field in the replication configuration with its type,
|
|
190
|
+
description, and optional default value.
|
|
191
|
+
|
|
192
|
+
Example YAML usage:
|
|
193
|
+
x-airbyte-replication-config:
|
|
194
|
+
properties:
|
|
195
|
+
start_date:
|
|
196
|
+
type: string
|
|
197
|
+
title: Start Date
|
|
198
|
+
description: UTC date and time from which to replicate data
|
|
199
|
+
format: date-time
|
|
200
|
+
"""
|
|
201
|
+
|
|
202
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
203
|
+
|
|
204
|
+
type: str
|
|
205
|
+
title: str | None = None
|
|
206
|
+
description: str | None = None
|
|
207
|
+
format: str | None = None
|
|
208
|
+
default: str | int | float | bool | None = None
|
|
209
|
+
enum: list[str] | None = None
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
class ReplicationConfig(BaseModel):
|
|
213
|
+
"""
|
|
214
|
+
Replication configuration extension (x-airbyte-replication-config).
|
|
215
|
+
|
|
216
|
+
Defines replication-specific settings for MULTI mode connectors that need
|
|
217
|
+
to configure the underlying replication connector. This allows users who
|
|
218
|
+
use the direct-style API (credentials + environment) to also specify
|
|
219
|
+
replication settings like start_date, lookback_window, etc.
|
|
220
|
+
|
|
221
|
+
This extension is added to the Info model and provides field definitions
|
|
222
|
+
for replication configuration that gets merged into the source config
|
|
223
|
+
when creating sources.
|
|
224
|
+
|
|
225
|
+
Example YAML usage:
|
|
226
|
+
info:
|
|
227
|
+
title: HubSpot API
|
|
228
|
+
x-airbyte-replication-config:
|
|
229
|
+
title: Replication Configuration
|
|
230
|
+
description: Settings for data replication
|
|
231
|
+
properties:
|
|
232
|
+
start_date:
|
|
233
|
+
type: string
|
|
234
|
+
title: Start Date
|
|
235
|
+
description: UTC date and time from which to replicate data
|
|
236
|
+
format: date-time
|
|
237
|
+
required:
|
|
238
|
+
- start_date
|
|
239
|
+
replication_config_key_mapping:
|
|
240
|
+
start_date: start_date
|
|
241
|
+
"""
|
|
242
|
+
|
|
243
|
+
model_config = ConfigDict(populate_by_name=True, extra="forbid")
|
|
244
|
+
|
|
245
|
+
title: str | None = None
|
|
246
|
+
description: str | None = None
|
|
247
|
+
properties: dict[str, ReplicationConfigProperty] = Field(default_factory=dict)
|
|
248
|
+
required: list[str] = Field(default_factory=list)
|
|
249
|
+
replication_config_key_mapping: dict[str, str] = Field(
|
|
250
|
+
default_factory=dict,
|
|
251
|
+
alias="replication_config_key_mapping",
|
|
252
|
+
description="Mapping from replication_config field names to source_config field names",
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
|
|
185
256
|
class CacheConfig(BaseModel):
|
|
186
257
|
"""
|
|
187
258
|
Cache configuration extension (x-airbyte-cache).
|
|
@@ -252,3 +252,4 @@ class ConnectorModel(BaseModel):
|
|
|
252
252
|
entities: list[EntityDefinition]
|
|
253
253
|
openapi_spec: Any | None = None # Optional reference to OpenAPIConnector
|
|
254
254
|
retry_config: RetryConfig | None = None # Optional retry configuration
|
|
255
|
+
search_field_paths: dict[str, list[str]] | None = None
|
airbyte_agent_slack/connector.py
CHANGED
|
@@ -4,8 +4,11 @@ Slack connector.
|
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
|
+
import inspect
|
|
8
|
+
import json
|
|
7
9
|
import logging
|
|
8
|
-
from
|
|
10
|
+
from functools import wraps
|
|
11
|
+
from typing import TYPE_CHECKING, Any, Callable, Mapping, TypeVar, overload
|
|
9
12
|
try:
|
|
10
13
|
from typing import Literal
|
|
11
14
|
except ImportError:
|
|
@@ -27,6 +30,11 @@ from .types import (
|
|
|
27
30
|
ThreadsListParams,
|
|
28
31
|
UsersGetParams,
|
|
29
32
|
UsersListParams,
|
|
33
|
+
AirbyteSearchParams,
|
|
34
|
+
ChannelsSearchFilter,
|
|
35
|
+
ChannelsSearchQuery,
|
|
36
|
+
UsersSearchFilter,
|
|
37
|
+
UsersSearchQuery,
|
|
30
38
|
)
|
|
31
39
|
if TYPE_CHECKING:
|
|
32
40
|
from .models import SlackAuthConfig
|
|
@@ -46,11 +54,49 @@ from .models import (
|
|
|
46
54
|
ReactionAddResponse,
|
|
47
55
|
Thread,
|
|
48
56
|
User,
|
|
57
|
+
AirbyteSearchHit,
|
|
58
|
+
AirbyteSearchResult,
|
|
59
|
+
ChannelsSearchData,
|
|
60
|
+
ChannelsSearchResult,
|
|
61
|
+
UsersSearchData,
|
|
62
|
+
UsersSearchResult,
|
|
49
63
|
)
|
|
50
64
|
|
|
51
65
|
# TypeVar for decorator type preservation
|
|
52
66
|
_F = TypeVar("_F", bound=Callable[..., Any])
|
|
53
67
|
|
|
68
|
+
DEFAULT_MAX_OUTPUT_CHARS = 50_000 # ~50KB default, configurable per-tool
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _raise_output_too_large(message: str) -> None:
|
|
72
|
+
try:
|
|
73
|
+
from pydantic_ai import ModelRetry # type: ignore[import-not-found]
|
|
74
|
+
except Exception as exc:
|
|
75
|
+
raise RuntimeError(message) from exc
|
|
76
|
+
raise ModelRetry(message)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _check_output_size(result: Any, max_chars: int | None, tool_name: str) -> Any:
|
|
80
|
+
if max_chars is None or max_chars <= 0:
|
|
81
|
+
return result
|
|
82
|
+
|
|
83
|
+
try:
|
|
84
|
+
serialized = json.dumps(result, default=str)
|
|
85
|
+
except (TypeError, ValueError):
|
|
86
|
+
return result
|
|
87
|
+
|
|
88
|
+
if len(serialized) > max_chars:
|
|
89
|
+
truncated_preview = serialized[:500] + "..." if len(serialized) > 500 else serialized
|
|
90
|
+
_raise_output_too_large(
|
|
91
|
+
f"Tool '{tool_name}' output too large ({len(serialized):,} chars, limit {max_chars:,}). "
|
|
92
|
+
"Please narrow your query by: using the 'fields' parameter to select only needed fields, "
|
|
93
|
+
"adding filters, or reducing the 'limit'. "
|
|
94
|
+
f"Preview: {truncated_preview}"
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
return result
|
|
98
|
+
|
|
99
|
+
|
|
54
100
|
|
|
55
101
|
|
|
56
102
|
class SlackConnector:
|
|
@@ -61,7 +107,7 @@ class SlackConnector:
|
|
|
61
107
|
"""
|
|
62
108
|
|
|
63
109
|
connector_name = "slack"
|
|
64
|
-
connector_version = "0.1.
|
|
110
|
+
connector_version = "0.1.8"
|
|
65
111
|
vendored_sdk_version = "0.1.0" # Version of vendored connector-sdk
|
|
66
112
|
|
|
67
113
|
# Map of (entity, action) -> needs_envelope for envelope wrapping decision
|
|
@@ -123,7 +169,7 @@ class SlackConnector:
|
|
|
123
169
|
Example: lambda tokens: save_to_database(tokens)
|
|
124
170
|
Examples:
|
|
125
171
|
# Local mode (direct API calls)
|
|
126
|
-
connector = SlackConnector(auth_config=SlackAuthConfig(
|
|
172
|
+
connector = SlackConnector(auth_config=SlackAuthConfig(api_token="..."))
|
|
127
173
|
# Hosted mode (executed on Airbyte cloud)
|
|
128
174
|
connector = SlackConnector(
|
|
129
175
|
external_user_id="user-123",
|
|
@@ -303,15 +349,15 @@ class SlackConnector:
|
|
|
303
349
|
async def execute(
|
|
304
350
|
self,
|
|
305
351
|
entity: str,
|
|
306
|
-
action:
|
|
307
|
-
params:
|
|
352
|
+
action: Literal["list", "get", "create", "update", "search"],
|
|
353
|
+
params: Mapping[str, Any]
|
|
308
354
|
) -> SlackExecuteResult[Any] | SlackExecuteResultWithMeta[Any, Any] | Any: ...
|
|
309
355
|
|
|
310
356
|
async def execute(
|
|
311
357
|
self,
|
|
312
358
|
entity: str,
|
|
313
|
-
action:
|
|
314
|
-
params:
|
|
359
|
+
action: Literal["list", "get", "create", "update", "search"],
|
|
360
|
+
params: Mapping[str, Any] | None = None
|
|
315
361
|
) -> Any:
|
|
316
362
|
"""
|
|
317
363
|
Execute an entity operation with full type safety.
|
|
@@ -339,16 +385,17 @@ class SlackConnector:
|
|
|
339
385
|
from ._vendored.connector_sdk.executor import ExecutionConfig
|
|
340
386
|
|
|
341
387
|
# Remap parameter names from snake_case (TypedDict keys) to API parameter names
|
|
342
|
-
if params
|
|
388
|
+
resolved_params = dict(params) if params is not None else None
|
|
389
|
+
if resolved_params:
|
|
343
390
|
param_map = self._PARAM_MAP.get((entity, action), {})
|
|
344
391
|
if param_map:
|
|
345
|
-
|
|
392
|
+
resolved_params = {param_map.get(k, k): v for k, v in resolved_params.items()}
|
|
346
393
|
|
|
347
394
|
# Use ExecutionConfig for both local and hosted executors
|
|
348
395
|
config = ExecutionConfig(
|
|
349
396
|
entity=entity,
|
|
350
397
|
action=action,
|
|
351
|
-
params=
|
|
398
|
+
params=resolved_params
|
|
352
399
|
)
|
|
353
400
|
|
|
354
401
|
result = await self._executor.execute(config)
|
|
@@ -375,41 +422,67 @@ class SlackConnector:
|
|
|
375
422
|
# ===== INTROSPECTION METHODS =====
|
|
376
423
|
|
|
377
424
|
@classmethod
|
|
378
|
-
def
|
|
425
|
+
def tool_utils(
|
|
426
|
+
cls,
|
|
427
|
+
func: _F | None = None,
|
|
428
|
+
*,
|
|
429
|
+
update_docstring: bool = True,
|
|
430
|
+
max_output_chars: int | None = DEFAULT_MAX_OUTPUT_CHARS,
|
|
431
|
+
) -> _F | Callable[[_F], _F]:
|
|
379
432
|
"""
|
|
380
|
-
Decorator that
|
|
381
|
-
|
|
382
|
-
This class method can be used as a decorator to automatically generate
|
|
383
|
-
comprehensive documentation for AI tool functions.
|
|
433
|
+
Decorator that adds tool utilities like docstring augmentation and output limits.
|
|
384
434
|
|
|
385
435
|
Usage:
|
|
386
436
|
@mcp.tool()
|
|
387
|
-
@SlackConnector.
|
|
437
|
+
@SlackConnector.tool_utils
|
|
388
438
|
async def execute(entity: str, action: str, params: dict):
|
|
389
|
-
'''Execute operations.'''
|
|
390
439
|
...
|
|
391
440
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
- Example questions (if available in OpenAPI spec)
|
|
441
|
+
@mcp.tool()
|
|
442
|
+
@SlackConnector.tool_utils(update_docstring=False, max_output_chars=None)
|
|
443
|
+
async def execute(entity: str, action: str, params: dict):
|
|
444
|
+
...
|
|
397
445
|
|
|
398
446
|
Args:
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
Returns:
|
|
402
|
-
The same function with updated __doc__
|
|
447
|
+
update_docstring: When True, append connector capabilities to __doc__.
|
|
448
|
+
max_output_chars: Max serialized output size before raising. Use None to disable.
|
|
403
449
|
"""
|
|
404
|
-
description = generate_tool_description(SlackConnectorModel)
|
|
405
450
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
451
|
+
def decorate(inner: _F) -> _F:
|
|
452
|
+
if update_docstring:
|
|
453
|
+
description = generate_tool_description(SlackConnectorModel)
|
|
454
|
+
original_doc = inner.__doc__ or ""
|
|
455
|
+
if original_doc.strip():
|
|
456
|
+
full_doc = f"{original_doc.strip()}\n{description}"
|
|
457
|
+
else:
|
|
458
|
+
full_doc = description
|
|
459
|
+
else:
|
|
460
|
+
full_doc = ""
|
|
461
|
+
|
|
462
|
+
if inspect.iscoroutinefunction(inner):
|
|
463
|
+
|
|
464
|
+
@wraps(inner)
|
|
465
|
+
async def aw(*args: Any, **kwargs: Any) -> Any:
|
|
466
|
+
result = await inner(*args, **kwargs)
|
|
467
|
+
return _check_output_size(result, max_output_chars, inner.__name__)
|
|
468
|
+
|
|
469
|
+
wrapped = aw
|
|
470
|
+
else:
|
|
471
|
+
|
|
472
|
+
@wraps(inner)
|
|
473
|
+
def sw(*args: Any, **kwargs: Any) -> Any:
|
|
474
|
+
result = inner(*args, **kwargs)
|
|
475
|
+
return _check_output_size(result, max_output_chars, inner.__name__)
|
|
476
|
+
|
|
477
|
+
wrapped = sw
|
|
478
|
+
|
|
479
|
+
if update_docstring:
|
|
480
|
+
wrapped.__doc__ = full_doc
|
|
481
|
+
return wrapped # type: ignore[return-value]
|
|
411
482
|
|
|
412
|
-
|
|
483
|
+
if func is not None:
|
|
484
|
+
return decorate(func)
|
|
485
|
+
return decorate
|
|
413
486
|
|
|
414
487
|
def list_entities(self) -> list[dict[str, Any]]:
|
|
415
488
|
"""
|
|
@@ -522,6 +595,82 @@ class UsersQuery:
|
|
|
522
595
|
|
|
523
596
|
|
|
524
597
|
|
|
598
|
+
async def search(
|
|
599
|
+
self,
|
|
600
|
+
query: UsersSearchQuery,
|
|
601
|
+
limit: int | None = None,
|
|
602
|
+
cursor: str | None = None,
|
|
603
|
+
fields: list[list[str]] | None = None,
|
|
604
|
+
) -> UsersSearchResult:
|
|
605
|
+
"""
|
|
606
|
+
Search users records from Airbyte cache.
|
|
607
|
+
|
|
608
|
+
This operation searches cached data from Airbyte syncs.
|
|
609
|
+
Only available in hosted execution mode.
|
|
610
|
+
|
|
611
|
+
Available filter fields (UsersSearchFilter):
|
|
612
|
+
- color: The color assigned to the user for visual purposes.
|
|
613
|
+
- deleted: Indicates if the user is deleted or not.
|
|
614
|
+
- has_2fa: Flag indicating if the user has two-factor authentication enabled.
|
|
615
|
+
- id: Unique identifier for the user.
|
|
616
|
+
- is_admin: Flag specifying if the user is an admin or not.
|
|
617
|
+
- is_app_user: Specifies if the user is an app user.
|
|
618
|
+
- is_bot: Indicates if the user is a bot account.
|
|
619
|
+
- is_email_confirmed: Flag indicating if the user's email is confirmed.
|
|
620
|
+
- is_forgotten: Specifies if the user is marked as forgotten.
|
|
621
|
+
- is_invited_user: Indicates if the user is invited or not.
|
|
622
|
+
- is_owner: Flag indicating if the user is an owner.
|
|
623
|
+
- is_primary_owner: Specifies if the user is the primary owner.
|
|
624
|
+
- is_restricted: Flag specifying if the user is restricted.
|
|
625
|
+
- is_ultra_restricted: Indicates if the user has ultra-restricted access.
|
|
626
|
+
- name: The username of the user.
|
|
627
|
+
- profile: User's profile information containing detailed details.
|
|
628
|
+
- real_name: The real name of the user.
|
|
629
|
+
- team_id: Unique identifier for the team the user belongs to.
|
|
630
|
+
- tz: Timezone of the user.
|
|
631
|
+
- tz_label: Label representing the timezone of the user.
|
|
632
|
+
- tz_offset: Offset of the user's timezone.
|
|
633
|
+
- updated: Timestamp of when the user's information was last updated.
|
|
634
|
+
- who_can_share_contact_card: Specifies who can share the user's contact card.
|
|
635
|
+
|
|
636
|
+
Args:
|
|
637
|
+
query: Filter and sort conditions. Supports operators like eq, neq, gt, gte, lt, lte,
|
|
638
|
+
in, like, fuzzy, keyword, not, and, or. Example: {"filter": {"eq": {"status": "active"}}}
|
|
639
|
+
limit: Maximum results to return (default 1000)
|
|
640
|
+
cursor: Pagination cursor from previous response's next_cursor
|
|
641
|
+
fields: Field paths to include in results. Each path is a list of keys for nested access.
|
|
642
|
+
Example: [["id"], ["user", "name"]] returns id and user.name fields.
|
|
643
|
+
|
|
644
|
+
Returns:
|
|
645
|
+
UsersSearchResult with hits (list of AirbyteSearchHit[UsersSearchData]) and pagination info
|
|
646
|
+
|
|
647
|
+
Raises:
|
|
648
|
+
NotImplementedError: If called in local execution mode
|
|
649
|
+
"""
|
|
650
|
+
params: dict[str, Any] = {"query": query}
|
|
651
|
+
if limit is not None:
|
|
652
|
+
params["limit"] = limit
|
|
653
|
+
if cursor is not None:
|
|
654
|
+
params["cursor"] = cursor
|
|
655
|
+
if fields is not None:
|
|
656
|
+
params["fields"] = fields
|
|
657
|
+
|
|
658
|
+
result = await self._connector.execute("users", "search", params)
|
|
659
|
+
|
|
660
|
+
# Parse response into typed result
|
|
661
|
+
return UsersSearchResult(
|
|
662
|
+
hits=[
|
|
663
|
+
AirbyteSearchHit[UsersSearchData](
|
|
664
|
+
id=hit.get("id"),
|
|
665
|
+
score=hit.get("score"),
|
|
666
|
+
data=UsersSearchData(**hit.get("data", {}))
|
|
667
|
+
)
|
|
668
|
+
for hit in result.get("hits", [])
|
|
669
|
+
],
|
|
670
|
+
next_cursor=result.get("next_cursor"),
|
|
671
|
+
took_ms=result.get("took_ms")
|
|
672
|
+
)
|
|
673
|
+
|
|
525
674
|
class ChannelsQuery:
|
|
526
675
|
"""
|
|
527
676
|
Query class for Channels entity operations.
|
|
@@ -650,6 +799,90 @@ class ChannelsQuery:
|
|
|
650
799
|
|
|
651
800
|
|
|
652
801
|
|
|
802
|
+
async def search(
|
|
803
|
+
self,
|
|
804
|
+
query: ChannelsSearchQuery,
|
|
805
|
+
limit: int | None = None,
|
|
806
|
+
cursor: str | None = None,
|
|
807
|
+
fields: list[list[str]] | None = None,
|
|
808
|
+
) -> ChannelsSearchResult:
|
|
809
|
+
"""
|
|
810
|
+
Search channels records from Airbyte cache.
|
|
811
|
+
|
|
812
|
+
This operation searches cached data from Airbyte syncs.
|
|
813
|
+
Only available in hosted execution mode.
|
|
814
|
+
|
|
815
|
+
Available filter fields (ChannelsSearchFilter):
|
|
816
|
+
- context_team_id: The unique identifier of the team context in which the channel exists.
|
|
817
|
+
- created: The timestamp when the channel was created.
|
|
818
|
+
- creator: The ID of the user who created the channel.
|
|
819
|
+
- id: The unique identifier of the channel.
|
|
820
|
+
- is_archived: Indicates if the channel is archived.
|
|
821
|
+
- is_channel: Indicates if the entity is a channel.
|
|
822
|
+
- is_ext_shared: Indicates if the channel is externally shared.
|
|
823
|
+
- is_general: Indicates if the channel is a general channel in the workspace.
|
|
824
|
+
- is_group: Indicates if the channel is a group (private channel) rather than a regular channel.
|
|
825
|
+
- is_im: Indicates if the entity is a direct message (IM) channel.
|
|
826
|
+
- is_member: Indicates if the calling user is a member of the channel.
|
|
827
|
+
- is_mpim: Indicates if the entity is a multiple person direct message (MPIM) channel.
|
|
828
|
+
- is_org_shared: Indicates if the channel is organization-wide shared.
|
|
829
|
+
- is_pending_ext_shared: Indicates if the channel is pending external shared.
|
|
830
|
+
- is_private: Indicates if the channel is a private channel.
|
|
831
|
+
- is_read_only: Indicates if the channel is read-only.
|
|
832
|
+
- is_shared: Indicates if the channel is shared.
|
|
833
|
+
- last_read: The timestamp of the user's last read message in the channel.
|
|
834
|
+
- locale: The locale of the channel.
|
|
835
|
+
- name: The name of the channel.
|
|
836
|
+
- name_normalized: The normalized name of the channel.
|
|
837
|
+
- num_members: The number of members in the channel.
|
|
838
|
+
- parent_conversation: The parent conversation of the channel.
|
|
839
|
+
- pending_connected_team_ids: The IDs of teams that are pending to be connected to the channel.
|
|
840
|
+
- pending_shared: The list of pending shared items of the channel.
|
|
841
|
+
- previous_names: The previous names of the channel.
|
|
842
|
+
- purpose: The purpose of the channel.
|
|
843
|
+
- shared_team_ids: The IDs of teams with which the channel is shared.
|
|
844
|
+
- topic: The topic of the channel.
|
|
845
|
+
- unlinked: Indicates if the channel is unlinked.
|
|
846
|
+
- updated: The timestamp when the channel was last updated.
|
|
847
|
+
|
|
848
|
+
Args:
|
|
849
|
+
query: Filter and sort conditions. Supports operators like eq, neq, gt, gte, lt, lte,
|
|
850
|
+
in, like, fuzzy, keyword, not, and, or. Example: {"filter": {"eq": {"status": "active"}}}
|
|
851
|
+
limit: Maximum results to return (default 1000)
|
|
852
|
+
cursor: Pagination cursor from previous response's next_cursor
|
|
853
|
+
fields: Field paths to include in results. Each path is a list of keys for nested access.
|
|
854
|
+
Example: [["id"], ["user", "name"]] returns id and user.name fields.
|
|
855
|
+
|
|
856
|
+
Returns:
|
|
857
|
+
ChannelsSearchResult with hits (list of AirbyteSearchHit[ChannelsSearchData]) and pagination info
|
|
858
|
+
|
|
859
|
+
Raises:
|
|
860
|
+
NotImplementedError: If called in local execution mode
|
|
861
|
+
"""
|
|
862
|
+
params: dict[str, Any] = {"query": query}
|
|
863
|
+
if limit is not None:
|
|
864
|
+
params["limit"] = limit
|
|
865
|
+
if cursor is not None:
|
|
866
|
+
params["cursor"] = cursor
|
|
867
|
+
if fields is not None:
|
|
868
|
+
params["fields"] = fields
|
|
869
|
+
|
|
870
|
+
result = await self._connector.execute("channels", "search", params)
|
|
871
|
+
|
|
872
|
+
# Parse response into typed result
|
|
873
|
+
return ChannelsSearchResult(
|
|
874
|
+
hits=[
|
|
875
|
+
AirbyteSearchHit[ChannelsSearchData](
|
|
876
|
+
id=hit.get("id"),
|
|
877
|
+
score=hit.get("score"),
|
|
878
|
+
data=ChannelsSearchData(**hit.get("data", {}))
|
|
879
|
+
)
|
|
880
|
+
for hit in result.get("hits", [])
|
|
881
|
+
],
|
|
882
|
+
next_cursor=result.get("next_cursor"),
|
|
883
|
+
took_ms=result.get("took_ms")
|
|
884
|
+
)
|
|
885
|
+
|
|
653
886
|
class ChannelMessagesQuery:
|
|
654
887
|
"""
|
|
655
888
|
Query class for ChannelMessages entity operations.
|
|
@@ -27,7 +27,7 @@ from uuid import (
|
|
|
27
27
|
SlackConnectorModel: ConnectorModel = ConnectorModel(
|
|
28
28
|
id=UUID('c2281cee-86f9-4a86-bb48-d23286b4c7bd'),
|
|
29
29
|
name='slack',
|
|
30
|
-
version='0.1.
|
|
30
|
+
version='0.1.8',
|
|
31
31
|
base_url='https://slack.com/api',
|
|
32
32
|
auth=AuthConfig(
|
|
33
33
|
options=[
|
|
@@ -38,16 +38,16 @@ SlackConnectorModel: ConnectorModel = ConnectorModel(
|
|
|
38
38
|
user_config_spec=AirbyteAuthConfig(
|
|
39
39
|
title='Token Authentication',
|
|
40
40
|
type='object',
|
|
41
|
-
required=['
|
|
41
|
+
required=['api_token'],
|
|
42
42
|
properties={
|
|
43
|
-
'
|
|
44
|
-
title='
|
|
43
|
+
'api_token': AuthConfigFieldSpec(
|
|
44
|
+
title='API Token',
|
|
45
45
|
description='Your Slack Bot Token (xoxb-) or User Token (xoxp-)',
|
|
46
46
|
airbyte_secret=True,
|
|
47
47
|
),
|
|
48
48
|
},
|
|
49
|
-
auth_mapping={'token': '${
|
|
50
|
-
replication_auth_key_mapping={'credentials.api_token': '
|
|
49
|
+
auth_mapping={'token': '${api_token}'},
|
|
50
|
+
replication_auth_key_mapping={'credentials.api_token': 'api_token'},
|
|
51
51
|
replication_auth_key_constants={'credentials.option_title': 'API Token Credentials'},
|
|
52
52
|
),
|
|
53
53
|
),
|
|
@@ -3192,4 +3192,104 @@ SlackConnectorModel: ConnectorModel = ConnectorModel(
|
|
|
3192
3192
|
},
|
|
3193
3193
|
),
|
|
3194
3194
|
],
|
|
3195
|
+
search_field_paths={
|
|
3196
|
+
'channel_members': ['channel_id', 'member_id'],
|
|
3197
|
+
'channels': [
|
|
3198
|
+
'context_team_id',
|
|
3199
|
+
'created',
|
|
3200
|
+
'creator',
|
|
3201
|
+
'id',
|
|
3202
|
+
'is_archived',
|
|
3203
|
+
'is_channel',
|
|
3204
|
+
'is_ext_shared',
|
|
3205
|
+
'is_general',
|
|
3206
|
+
'is_group',
|
|
3207
|
+
'is_im',
|
|
3208
|
+
'is_member',
|
|
3209
|
+
'is_mpim',
|
|
3210
|
+
'is_org_shared',
|
|
3211
|
+
'is_pending_ext_shared',
|
|
3212
|
+
'is_private',
|
|
3213
|
+
'is_read_only',
|
|
3214
|
+
'is_shared',
|
|
3215
|
+
'last_read',
|
|
3216
|
+
'locale',
|
|
3217
|
+
'name',
|
|
3218
|
+
'name_normalized',
|
|
3219
|
+
'num_members',
|
|
3220
|
+
'parent_conversation',
|
|
3221
|
+
'pending_connected_team_ids',
|
|
3222
|
+
'pending_connected_team_ids[]',
|
|
3223
|
+
'pending_shared',
|
|
3224
|
+
'pending_shared[]',
|
|
3225
|
+
'previous_names',
|
|
3226
|
+
'previous_names[]',
|
|
3227
|
+
'purpose',
|
|
3228
|
+
'purpose.creator',
|
|
3229
|
+
'purpose.last_set',
|
|
3230
|
+
'purpose.value',
|
|
3231
|
+
'shared_team_ids',
|
|
3232
|
+
'shared_team_ids[]',
|
|
3233
|
+
'topic',
|
|
3234
|
+
'topic.creator',
|
|
3235
|
+
'topic.last_set',
|
|
3236
|
+
'topic.value',
|
|
3237
|
+
'unlinked',
|
|
3238
|
+
'updated',
|
|
3239
|
+
],
|
|
3240
|
+
'users': [
|
|
3241
|
+
'color',
|
|
3242
|
+
'deleted',
|
|
3243
|
+
'has_2fa',
|
|
3244
|
+
'id',
|
|
3245
|
+
'is_admin',
|
|
3246
|
+
'is_app_user',
|
|
3247
|
+
'is_bot',
|
|
3248
|
+
'is_email_confirmed',
|
|
3249
|
+
'is_forgotten',
|
|
3250
|
+
'is_invited_user',
|
|
3251
|
+
'is_owner',
|
|
3252
|
+
'is_primary_owner',
|
|
3253
|
+
'is_restricted',
|
|
3254
|
+
'is_ultra_restricted',
|
|
3255
|
+
'name',
|
|
3256
|
+
'profile',
|
|
3257
|
+
'profile.always_active',
|
|
3258
|
+
'profile.avatar_hash',
|
|
3259
|
+
'profile.display_name',
|
|
3260
|
+
'profile.display_name_normalized',
|
|
3261
|
+
'profile.email',
|
|
3262
|
+
'profile.fields',
|
|
3263
|
+
'profile.first_name',
|
|
3264
|
+
'profile.huddle_state',
|
|
3265
|
+
'profile.image_1024',
|
|
3266
|
+
'profile.image_192',
|
|
3267
|
+
'profile.image_24',
|
|
3268
|
+
'profile.image_32',
|
|
3269
|
+
'profile.image_48',
|
|
3270
|
+
'profile.image_512',
|
|
3271
|
+
'profile.image_72',
|
|
3272
|
+
'profile.image_original',
|
|
3273
|
+
'profile.last_name',
|
|
3274
|
+
'profile.phone',
|
|
3275
|
+
'profile.real_name',
|
|
3276
|
+
'profile.real_name_normalized',
|
|
3277
|
+
'profile.skype',
|
|
3278
|
+
'profile.status_emoji',
|
|
3279
|
+
'profile.status_emoji_display_info',
|
|
3280
|
+
'profile.status_emoji_display_info[]',
|
|
3281
|
+
'profile.status_expiration',
|
|
3282
|
+
'profile.status_text',
|
|
3283
|
+
'profile.status_text_canonical',
|
|
3284
|
+
'profile.team',
|
|
3285
|
+
'profile.title',
|
|
3286
|
+
'real_name',
|
|
3287
|
+
'team_id',
|
|
3288
|
+
'tz',
|
|
3289
|
+
'tz_label',
|
|
3290
|
+
'tz_offset',
|
|
3291
|
+
'updated',
|
|
3292
|
+
'who_can_share_contact_card',
|
|
3293
|
+
],
|
|
3294
|
+
},
|
|
3195
3295
|
)
|