Spaces:
Runtime error
Runtime error
Resolve user identifiers to display or real names for incoming Slack messages
Browse files
src/ctp_slack_bot/app.py
CHANGED
|
@@ -34,7 +34,7 @@ async def main() -> None:
|
|
| 34 |
container.schedule_service()
|
| 35 |
|
| 36 |
# Start the Slack socket mode handler in the background.
|
| 37 |
-
socket_mode_handler = container.socket_mode_handler()
|
| 38 |
slack_bolt_task = create_task(socket_mode_handler.start_async())
|
| 39 |
shutdown_signal_handler = create_shutdown_signal_handler()
|
| 40 |
loop = get_running_loop()
|
|
|
|
| 34 |
container.schedule_service()
|
| 35 |
|
| 36 |
# Start the Slack socket mode handler in the background.
|
| 37 |
+
socket_mode_handler = await container.socket_mode_handler()
|
| 38 |
slack_bolt_task = create_task(socket_mode_handler.start_async())
|
| 39 |
shutdown_signal_handler = create_shutdown_signal_handler()
|
| 40 |
loop = get_running_loop()
|
src/ctp_slack_bot/services/slack_service.py
CHANGED
|
@@ -1,8 +1,10 @@
|
|
| 1 |
-
from dependency_injector.resources import
|
| 2 |
from loguru import logger
|
| 3 |
from openai import OpenAI
|
| 4 |
from pydantic import BaseModel
|
|
|
|
| 5 |
from slack_bolt.async_app import AsyncApp
|
|
|
|
| 6 |
from typing import Any, Mapping, Self
|
| 7 |
|
| 8 |
from ctp_slack_bot.enums import EventType
|
|
@@ -10,6 +12,9 @@ from ctp_slack_bot.models import SlackMessage, SlackResponse
|
|
| 10 |
from ctp_slack_bot.services.event_brokerage_service import EventBrokerageService
|
| 11 |
|
| 12 |
|
|
|
|
|
|
|
|
|
|
| 13 |
class SlackService(BaseModel):
|
| 14 |
"""
|
| 15 |
Service for interfacing with Slack.
|
|
@@ -17,6 +22,7 @@ class SlackService(BaseModel):
|
|
| 17 |
|
| 18 |
event_brokerage_service: EventBrokerageService
|
| 19 |
slack_bolt_app: AsyncApp
|
|
|
|
| 20 |
|
| 21 |
class Config:
|
| 22 |
arbitrary_types_allowed = True
|
|
@@ -28,6 +34,7 @@ class SlackService(BaseModel):
|
|
| 28 |
logger.debug("Created {}", self.__class__.__name__)
|
| 29 |
|
| 30 |
def adapt_event_payload(self: Self, event: Mapping[str, Any]) -> SlackMessage:
|
|
|
|
| 31 |
return SlackMessage(
|
| 32 |
type=event.get("type"),
|
| 33 |
subtype=event.get("subtype"),
|
|
@@ -36,7 +43,7 @@ class SlackService(BaseModel):
|
|
| 36 |
user=event.get("user"),
|
| 37 |
bot_id=event.get("bot_id"),
|
| 38 |
thread_ts=event.get("thread_ts"),
|
| 39 |
-
text=
|
| 40 |
ts=event.get("ts"),
|
| 41 |
event_ts=event.get("event_ts")
|
| 42 |
)
|
|
@@ -57,13 +64,23 @@ class SlackService(BaseModel):
|
|
| 57 |
logger.debug("Received app mention for processing: {}", body.get("event", {}).get("text"))
|
| 58 |
await self.process_message(body)
|
| 59 |
|
| 60 |
-
def
|
| 61 |
self.slack_bolt_app.event("message")(self.handle_message_event)
|
| 62 |
self.slack_bolt_app.event("app_mention")(self.handle_app_mention_event)
|
| 63 |
logger.debug("Registered 2 handlers for Slack Bolt message and app mention events.")
|
| 64 |
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
return slack_service
|
|
|
|
| 1 |
+
from dependency_injector.resources import AsyncResource
|
| 2 |
from loguru import logger
|
| 3 |
from openai import OpenAI
|
| 4 |
from pydantic import BaseModel
|
| 5 |
+
from re import compile as compile_re
|
| 6 |
from slack_bolt.async_app import AsyncApp
|
| 7 |
+
from slack_sdk.web.async_slack_response import AsyncSlackResponse
|
| 8 |
from typing import Any, Mapping, Self
|
| 9 |
|
| 10 |
from ctp_slack_bot.enums import EventType
|
|
|
|
| 12 |
from ctp_slack_bot.services.event_brokerage_service import EventBrokerageService
|
| 13 |
|
| 14 |
|
| 15 |
+
SLACK_USER_MENTION_PATTERN = compile_re(r"<@([A-Z0-9]+)>")
|
| 16 |
+
|
| 17 |
+
|
| 18 |
class SlackService(BaseModel):
|
| 19 |
"""
|
| 20 |
Service for interfacing with Slack.
|
|
|
|
| 22 |
|
| 23 |
event_brokerage_service: EventBrokerageService
|
| 24 |
slack_bolt_app: AsyncApp
|
| 25 |
+
user_id_name_map: dict[str, str] # This is deliberately mutable; the map may change as new users are encountered.
|
| 26 |
|
| 27 |
class Config:
|
| 28 |
arbitrary_types_allowed = True
|
|
|
|
| 34 |
logger.debug("Created {}", self.__class__.__name__)
|
| 35 |
|
| 36 |
def adapt_event_payload(self: Self, event: Mapping[str, Any]) -> SlackMessage:
|
| 37 |
+
text = SLACK_USER_MENTION_PATTERN.sub(lambda match: f"@{self.user_id_name_map.get(match.group(1))}", event.get("text", "")) # TODO: permit look-up of Slack again when not found.
|
| 38 |
return SlackMessage(
|
| 39 |
type=event.get("type"),
|
| 40 |
subtype=event.get("subtype"),
|
|
|
|
| 43 |
user=event.get("user"),
|
| 44 |
bot_id=event.get("bot_id"),
|
| 45 |
thread_ts=event.get("thread_ts"),
|
| 46 |
+
text=text,
|
| 47 |
ts=event.get("ts"),
|
| 48 |
event_ts=event.get("event_ts")
|
| 49 |
)
|
|
|
|
| 64 |
logger.debug("Received app mention for processing: {}", body.get("event", {}).get("text"))
|
| 65 |
await self.process_message(body)
|
| 66 |
|
| 67 |
+
def initialize(self: Self) -> None:
|
| 68 |
self.slack_bolt_app.event("message")(self.handle_message_event)
|
| 69 |
self.slack_bolt_app.event("app_mention")(self.handle_app_mention_event)
|
| 70 |
logger.debug("Registered 2 handlers for Slack Bolt message and app mention events.")
|
| 71 |
|
| 72 |
+
|
| 73 |
+
class SlackServiceResource(AsyncResource):
|
| 74 |
+
async def init(self: Self, event_brokerage_service: EventBrokerageService, slack_bolt_app: AsyncApp) -> SlackService:
|
| 75 |
+
match await slack_bolt_app.client.users_list():
|
| 76 |
+
case AsyncSlackResponse(status_code=200, data={"ok": True, "members": users}):
|
| 77 |
+
user_id_name_map = {user["id"]: user["profile"]["display_name"] or user["real_name"]
|
| 78 |
+
for user
|
| 79 |
+
in users}
|
| 80 |
+
logger.debug("Obtained a list of {} user name(s) for the workspace: {}", len(user_id_name_map), user_id_name_map)
|
| 81 |
+
case something:
|
| 82 |
+
user_id_name_map = {}
|
| 83 |
+
logger.error("Could not obtain a list of user name for the workspace.")
|
| 84 |
+
slack_service = SlackService(event_brokerage_service=event_brokerage_service, slack_bolt_app=slack_bolt_app, user_id_name_map=user_id_name_map)
|
| 85 |
+
slack_service.initialize()
|
| 86 |
return slack_service
|