Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions pybotx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
ChatCreationError,
ChatCreationProhibitedError,
InvalidUsersListError,
ThreadCreationError,
ThreadCreationProhibitedError,
)
from pybotx.client.exceptions.common import (
ChatNotFoundError,
Expand Down Expand Up @@ -260,6 +262,9 @@
"SyncSmartAppEventHandlerFunc",
"SyncSmartAppEventHandlerNotFoundError",
"SyncSourceTypes",
"ThreadCreationError",
"ThreadCreationEventNotFoundError",
"ThreadCreationProhibitedError",
"UnknownBotAccountError",
"UnknownSystemEventError",
"UnsupportedBotAPIVersionError",
Expand Down
31 changes: 26 additions & 5 deletions pybotx/bot/bot.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
from asyncio import Task
from collections.abc import AsyncIterable, AsyncIterator, Iterator, Mapping, Sequence
from contextlib import asynccontextmanager
from datetime import datetime
from types import SimpleNamespace
from typing import (
Any,
AsyncIterable,
AsyncIterator,
Dict,
Iterator,
List,
Mapping,
Optional,
Sequence,
Set,
Tuple,
Union,
Expand Down Expand Up @@ -57,6 +53,10 @@
BotXAPICreateChatRequestPayload,
CreateChatMethod,
)
from pybotx.client.chats_api.create_thread import (
BotXAPICreateThreadRequestPayload,
CreateThreadMethod,
)
from pybotx.client.chats_api.disable_stealth import (
BotXAPIDisableStealthRequestPayload,
DisableStealthMethod,
Expand Down Expand Up @@ -1176,6 +1176,27 @@ async def create_chat(

return botx_api_chat_id.to_domain()

async def create_thread(self, bot_id: UUID, sync_id: UUID) -> UUID:
"""
Create thread.

:param bot_id: Bot which should perform the request.
:param sync_id: Message for which thread should be created

:return: Created thread uuid.
"""

method = CreateThreadMethod(
bot_id,
self._httpx_client,
self._bot_accounts_storage,
)

payload = BotXAPICreateThreadRequestPayload.from_domain(sync_id=sync_id)
botx_api_thread_id = await method.execute(payload)

return botx_api_thread_id.to_domain()

async def pin_message(
self,
*,
Expand Down
57 changes: 57 additions & 0 deletions pybotx/client/chats_api/create_thread.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from typing import Literal
from uuid import UUID

from pybotx.client.authorized_botx_method import AuthorizedBotXMethod
from pybotx.client.botx_method import response_exception_thrower
from pybotx.client.exceptions.chats import (
ThreadCreationError,
ThreadCreationProhibitedError,
)
from pybotx.client.exceptions.event import EventNotFoundError
from pybotx.models.api_base import UnverifiedPayloadBaseModel, VerifiedPayloadBaseModel


class BotXAPICreateThreadRequestPayload(UnverifiedPayloadBaseModel):
sync_id: UUID

@classmethod
def from_domain(cls, sync_id: UUID) -> "BotXAPICreateThreadRequestPayload":
return cls(sync_id=sync_id)


class BotXAPIThreadIdResult(VerifiedPayloadBaseModel):
thread_id: UUID


class BotXAPICreateThreadResponsePayload(VerifiedPayloadBaseModel):
status: Literal["ok"]
result: BotXAPIThreadIdResult

def to_domain(self) -> UUID:
return self.result.thread_id


class CreateThreadMethod(AuthorizedBotXMethod):
status_handlers = {
**AuthorizedBotXMethod.status_handlers,
403: response_exception_thrower(ThreadCreationProhibitedError),
404: response_exception_thrower(EventNotFoundError),
422: response_exception_thrower(ThreadCreationError),
}

async def execute(
self,
payload: BotXAPICreateThreadRequestPayload,
) -> BotXAPICreateThreadResponsePayload:
path = "/api/v3/botx/chats/create_thread"

response = await self._botx_method_call(
"POST",
self._build_url(path),
json=payload.jsonable_dict(),
)

return self._verify_and_extract_api_model(
BotXAPICreateThreadResponsePayload,
response,
)
21 changes: 21 additions & 0 deletions pybotx/client/exceptions/chats.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,24 @@ class ChatCreationProhibitedError(BaseClientError):

class ChatCreationError(BaseClientError):
"""Error while chat creation."""


class ThreadCreationError(BaseClientError):
"""Error while thread creation (invalid scheme)."""


class ThreadCreationProhibitedError(BaseClientError):
"""
Error while permission checks.

1. Bot has no permissions to create thread
2. Threads are not allowed for that message
3. Bot is not a chat member where message is located
4. Message is located in personal chat
5. Usupported event type
6. Unsuppoerted chat type
7. Thread is already created
8. No access for message
9. Message in stealth mode
10. Message is deleted
"""
4 changes: 4 additions & 0 deletions pybotx/models/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class ChatTypes(AutoName):
PERSONAL_CHAT = auto()
GROUP_CHAT = auto()
CHANNEL = auto()
THREAD = auto()


class SyncSourceTypes(AutoName):
Expand Down Expand Up @@ -92,6 +93,7 @@ class APIChatTypes(Enum):
CHAT = "chat"
GROUP_CHAT = "group_chat"
CHANNEL = "channel"
THREAD = "thread"


class BotAPICommandTypes(StrEnum):
Expand Down Expand Up @@ -295,6 +297,7 @@ def convert_chat_type_from_domain(chat_type: ChatTypes) -> APIChatTypes:
ChatTypes.PERSONAL_CHAT: APIChatTypes.CHAT,
ChatTypes.GROUP_CHAT: APIChatTypes.GROUP_CHAT,
ChatTypes.CHANNEL: APIChatTypes.CHANNEL,
ChatTypes.THREAD: APIChatTypes.THREAD,
}

converted_type = chat_types_mapping.get(chat_type)
Expand Down Expand Up @@ -323,6 +326,7 @@ def convert_chat_type_to_domain(
APIChatTypes.CHAT: ChatTypes.PERSONAL_CHAT,
APIChatTypes.GROUP_CHAT: ChatTypes.GROUP_CHAT,
APIChatTypes.CHANNEL: ChatTypes.CHANNEL,
APIChatTypes.THREAD: ChatTypes.THREAD,
}

converted_type: Optional[IncomingChatTypes]
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[tool.poetry]
name = "pybotx"
version = "0.75.1"
version = "0.75.2"
description = "A python library for interacting with eXpress BotX API"
authors = [
"Sidnev Nikolay <nsidnev@ccsteam.ru>",
"Maxim Gorbachev <mgorbachev@ccsteam.ru>",
"Alexander Samoylenko <alexandr.samojlenko@ccsteam.ru>",
"Arseniy Zhiltsov <arseniy.zhiltsov@ccsteam.ru>"
"Arseniy Zhiltsov <arseniy.zhiltsov@ccsteam.ru>",
]
readme = "README.md"
repository = "https://github.com/ExpressApp/pybotx"
Expand Down
Loading
Loading