mirror of
https://github.com/status-im/status-python-sdk.git
synced 2026-08-30 21:51:14 +00:00
account: Emoji reactions
- Related to https://github.com/status-im/status-python-sdk/issues/43
This commit is contained in:
@@ -515,6 +515,42 @@ account.send_image(
|
||||
)
|
||||
```
|
||||
|
||||
#### `send_emoji_reaction(message_id, emoji_shortname, chat_id=None)`
|
||||
|
||||
React to a message with an emoji, the same as reacting to a message in Status App. The reaction is a **toggle** - calling the method again with the same emoji on the same message removes it, so the same call both sets and unsets the reaction.
|
||||
|
||||
Emojis are identified by their **shortname**, exactly as Status App names them (`:thumbsup:`, `:heart_eyes:`). The surrounding colons are optional - `thumbsup` and `:thumbsup:` are the same emoji - and the full list of supported shortnames is documented under [Emojis](./utils.md#emojis).
|
||||
|
||||
Passing `chat_id` is purely an **optimisation**. Without it the chat has to be resolved from the message first, which costs one extra round trip to the Status Backend per reaction - worth avoiding when reacting to many messages in a chat that is already known, such as inside a [`listen_messages`](./account.md#listen_messages) loop. A `chat_id` that does not match the message is rejected by the backend and raises a custom exception, so pass it only when it is certain.
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
|-----|-----|-----|-------------|
|
||||
| `message_id` | `str` | Yes | The `id` of the message to react to. Message IDs can be obtained from the `id` key of [`get_messages`](./account.md#get_messageschat_id-start_timestampnone-end_timestampnone), from the `lastMessage` of a [`listen_messages`](./account.md#listen_messages) event, or directly from the return value of [`send_message`](./account.md#send_messagechat_id-message-reply_to_message_idnone) / [`send_image`](./account.md#send_imagechat_id-file_path-messagenone-reply_to_message_idnone). |
|
||||
| `emoji_shortname` | `str` | Yes | The emoji shortname as in Status App, with or without the surrounding colons. See [Emojis](./utils.md#emojis) for all supported values. |
|
||||
| `chat_id` | `str` | No | Identifier of the chat the message belongs to, as found in the [`chats`](./account.md#chats) property. When omitted (default), it is resolved from `message_id` with an extra call to the Status Backend. |
|
||||
|
||||
```python
|
||||
from status_sdk import Account
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
|
||||
chat = account.chats[0]
|
||||
|
||||
# Messages are returned newest first, so this is the latest message in the chat
|
||||
messages = account.get_messages(chat["id"])
|
||||
latest = messages[0]
|
||||
|
||||
account.send_emoji_reaction(latest["id"], ":thumbsup:")
|
||||
|
||||
# Reacting with the same emoji again removes the reaction
|
||||
account.send_emoji_reaction(latest["id"], ":thumbsup:")
|
||||
```
|
||||
|
||||
#### `get_messages(chat_id, start_timestamp=None, end_timestamp=None)`
|
||||
|
||||
Retrieve messages from the specified chat within an optional time range. Messages are returned in **descending order** (newest to oldest). The method automatically paginates through the backend until all messages in the specified range are collected. This method is ideal for backfilling, [batch processing](https://aws.amazon.com/what-is/batch-processing/) or [micro batch processing](https://www.dremio.com/wiki/micro-batch-processing/).
|
||||
|
||||
@@ -1239,6 +1239,42 @@ message_id = channel.send_image("./meme-67.png", "Daily random meme")
|
||||
print(f"Sent image: {message_id}")
|
||||
```
|
||||
|
||||
### `send_emoji_reaction(message_id, emoji_shortname)`
|
||||
|
||||
React to a message in the channel with an emoji, the same as reacting to a message in Status App. The reaction is a **toggle** - calling the method again with the same emoji on the same message removes it, so the same call both sets and unsets the reaction.
|
||||
|
||||
Emojis are identified by their **shortname**, exactly as Status App names them (`:thumbsup:`, `:heart_eyes:`). The surrounding colons are optional - `thumbsup` and `:thumbsup:` are the same emoji - and the full list of supported shortnames is documented under [Emojis](./utils.md#emojis).
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
|-----|-----|-----|-------------|
|
||||
| `message_id` | `str` | Yes | The `id` of the message to react to. Message IDs can be obtained from the `id` key of [`get_messages`](./community.md#get_messagesstart_timestampnone-end_timestampnone), or directly from the return value of [`send_message`](./community.md#send_messagemessage-reply_to_message_idnone) / [`send_image`](./community.md#send_imagefile_path-messagenone-reply_to_message_idnone). |
|
||||
| `emoji_shortname` | `str` | Yes | The emoji shortname as in Status App, with or without the surrounding colons. See [Emojis](./utils.md#emojis) for all supported values. |
|
||||
|
||||
```python
|
||||
from status_sdk import Account, Community
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
|
||||
url = "https://status.app/c/G3QAAMQn9ueHRsR3W5Ouuy25fkCxziknAIEkCbYAoC04HjyGeQ6X8k45q3GVeyZiksbd38tQ4S_EfhrJKhRV3sDvjhmrCuSoDBIf2QJiEKwAOZipxis8ntNRVyPhC5IoWaEsj9X4P5zw093pcLofZzTV2gM=#zQ3shZeEJqTC1xhGUjxuS4rtHSrhJ8vUYp64v6qWkLpvdy9L9"
|
||||
community = Community(account, url=url)
|
||||
|
||||
channel = community["general"]
|
||||
|
||||
# Messages are returned newest first, so this is the latest message in the channel
|
||||
messages = channel.get_messages()
|
||||
latest = messages[0]
|
||||
|
||||
channel.send_emoji_reaction(latest["id"], ":thumbsup:")
|
||||
|
||||
# Reacting with the same emoji again removes the reaction
|
||||
channel.send_emoji_reaction(latest["id"], ":thumbsup:")
|
||||
```
|
||||
|
||||
### `get_messages(start_timestamp=None, end_timestamp=None)`
|
||||
|
||||
Retrieve messages from the channel within an optional time range. Messages are returned in **descending order** (newest to oldest).
|
||||
|
||||
@@ -252,6 +252,40 @@ message_id = group_chat.send_image("./meme-67.png", "Daily random meme")
|
||||
print(f"Sent image: {message_id}")
|
||||
```
|
||||
|
||||
### `send_emoji_reaction(message_id, emoji_shortname)`
|
||||
|
||||
React to a message in the group chat with an emoji, the same as reacting to a message in Status App. The reaction is a **toggle** - calling the method again with the same emoji on the same message removes it, so the same call both sets and unsets the reaction.
|
||||
|
||||
Emojis are identified by their **shortname**, exactly as Status App names them (`:thumbsup:`, `:heart_eyes:`). The surrounding colons are optional - `thumbsup` and `:thumbsup:` are the same emoji - and the full list of supported shortnames is documented under [Emojis](./utils.md#emojis).
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
|-----|-----|-----|-------------|
|
||||
| `message_id` | `str` | Yes | The `id` of the message to react to. Message IDs can be obtained from the `id` key of [`get_messages`](./group-chat.md#get_messagesstart_timestampnone-end_timestampnone), or directly from the return value of [`send_message`](./group-chat.md#send_messagemessage-reply_to_message_idnone) / [`send_image`](./group-chat.md#send_imagefile_path-messagenone-reply_to_message_idnone). |
|
||||
| `emoji_shortname` | `str` | Yes | The emoji shortname as in Status App, with or without the surrounding colons. See [Emojis](./utils.md#emojis) for all supported values. |
|
||||
|
||||
```python
|
||||
from status_sdk import Account, GroupChat
|
||||
|
||||
account = Account()
|
||||
params = {
|
||||
"name": "status-app-bot",
|
||||
"password": "SNTPUMP"
|
||||
}
|
||||
account.login(**params)
|
||||
|
||||
chat = [chat for chat in account.chats if chat["type"] == "group_chat"][0]
|
||||
group_chat = GroupChat(account, chat["id"])
|
||||
|
||||
# Messages are returned newest first, so this is the latest message in the chat
|
||||
messages = group_chat.get_messages()
|
||||
latest = messages[0]
|
||||
|
||||
group_chat.send_emoji_reaction(latest["id"], ":thumbsup:")
|
||||
|
||||
# Reacting with the same emoji again removes the reaction
|
||||
group_chat.send_emoji_reaction(latest["id"], ":thumbsup:")
|
||||
```
|
||||
|
||||
### `delete_message(id)`
|
||||
|
||||
Delete one of your **own** messages from the group chat. The deletion is propagated to the other members, so the message disappears for everybody. You can only delete messages that the logged-in account has sent.
|
||||
|
||||
+1876
File diff suppressed because it is too large
Load Diff
@@ -673,6 +673,40 @@ class Account:
|
||||
"""
|
||||
return self.__send_content(chat_id, message, reply_to_message_id)
|
||||
|
||||
|
||||
def send_emoji_reaction(self, message_id: str, emoji_shortname: str, chat_id: Optional[str] = None):
|
||||
"""
|
||||
Set / unset emoji reaction for a message.
|
||||
|
||||
Parameters:
|
||||
- `message_id`- the `id` of the message
|
||||
- `emoji_shortname` - the emoji shortname as in Status App
|
||||
- `chat_id` - the `id` of the chat. If not provided it will be found from `message_id`
|
||||
"""
|
||||
if not emoji_shortname.startswith(":"):
|
||||
emoji_shortname = f":{emoji_shortname}"
|
||||
|
||||
if not emoji_shortname.endswith(":"):
|
||||
emoji_shortname += ":"
|
||||
|
||||
emoji_unicode = constants.EMOJI_UNICODES.get(emoji_shortname)
|
||||
if not emoji_unicode:
|
||||
raise exceptions.EmojiNotFoundError(emoji_shortname)
|
||||
|
||||
if not chat_id:
|
||||
response = self._call_rpc("messaging", "messageByMessageID", [message_id])
|
||||
error = response.get("error", {}) or {}
|
||||
if error:
|
||||
raise exceptions.ChatNotFoundError(error.get("message"))
|
||||
|
||||
chat_id: str = response["result"]["localChatId"]
|
||||
|
||||
params = [chat_id, message_id, emoji_unicode]
|
||||
response = self._call_rpc("messaging", "sendEmojiReaction", params)
|
||||
error = response.get("error", {}) or {}
|
||||
if error:
|
||||
raise exceptions.ChatNotFoundError(error.get("message"))
|
||||
|
||||
def __send_content(self, chat_id: str, message: Optional[str] = None, reply_to_message_id: Optional[str] = None, image_path: Optional[str] = None) -> str:
|
||||
"""
|
||||
Send a message with optional media attached to the given chat.
|
||||
|
||||
@@ -214,6 +214,15 @@ class Channel:
|
||||
"""
|
||||
return self.__account.send_image(self.id, file_path, message, reply_to_message_id)
|
||||
|
||||
def send_emoji_reaction(self, message_id: str, emoji_shortname: str):
|
||||
"""
|
||||
Set / unset emoji reaction for a message in the channel.
|
||||
|
||||
Parameters:
|
||||
- `message_id` - the `id` of the message, as it appears in `self.get_messages()`
|
||||
- `emoji_shortname` - the emoji shortname as in Status App, with or without the surrounding colons
|
||||
"""
|
||||
self.__account.send_emoji_reaction(message_id, emoji_shortname, self.id)
|
||||
|
||||
def get_messages(self, start_timestamp: Optional[Union[str, datetime.datetime, datetime.date, pd.Timestamp]] = None, end_timestamp: Optional[Union[str, datetime.datetime, datetime.date, pd.Timestamp]] = None) -> list[dict]:
|
||||
"""
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -74,6 +74,13 @@ class InvalidCommunityChannelColourError(ValueError):
|
||||
class InvalidCommunityChannelEmojiError(ValueError):
|
||||
pass
|
||||
|
||||
class ChatNotFoundError(Exception):
|
||||
pass
|
||||
|
||||
class EmojiNotFoundError(Exception):
|
||||
def __init__(self, shortname: str):
|
||||
super().__init__(f"Emoji shortcode '{shortname}' does not exist...")
|
||||
|
||||
class GroupChatCreationError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@@ -84,6 +84,15 @@ class GroupChat:
|
||||
"""
|
||||
return self.__account.send_image(self.id, file_path, message, reply_to_message_id)
|
||||
|
||||
def send_emoji_reaction(self, message_id: str, emoji_shortname: str):
|
||||
"""
|
||||
Set / unset emoji reaction for a message in the group chat.
|
||||
|
||||
Parameters:
|
||||
- `message_id` - the `id` of the message, as it appears in `self.get_messages()`
|
||||
- `emoji_shortname` - the emoji shortname as in Status App, with or without the surrounding colons
|
||||
"""
|
||||
self.__account.send_emoji_reaction(message_id, emoji_shortname, self.id)
|
||||
|
||||
def get_messages(self, start_timestamp: Optional[Union[str, datetime.datetime, datetime.date, pd.Timestamp]] = None, end_timestamp: Optional[Union[str, datetime.datetime, datetime.date, pd.Timestamp]] = None) -> list[dict]:
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user