Coverage for mindsdb / integrations / handlers / discord_handler / discord_handler.py: 0%
71 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-21 00:36 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-21 00:36 +0000
1import requests
2import pandas as pd
4from mindsdb.integrations.handlers.discord_handler.discord_tables import MessagesTable
6from mindsdb.utilities import log
8from mindsdb.integrations.libs.api_handler import APIHandler, FuncParser
9from mindsdb.integrations.utilities.date_utils import parse_utc_date
11from mindsdb.integrations.libs.response import (
12 HandlerStatusResponse as StatusResponse,
13 HandlerResponse as Response,
14 RESPONSE_TYPE,
15)
17discord_bot = None
18logger = log.getLogger(__name__)
21class DiscordHandler(APIHandler):
22 """
23 The Discord handler implementation.
24 """
26 name = 'discord'
28 def __init__(self, name: str, **kwargs):
29 """
30 Initialize the handler.
31 Args:
32 name (str): name of particular handler instance
33 **kwargs: arbitrary keyword arguments.
34 """
35 super().__init__(name)
37 connection_data = kwargs.get("connection_data", {})
38 self.connection_data = connection_data
39 self.kwargs = kwargs
41 self.is_connected = False
43 messages = MessagesTable(self)
44 self._register_table('messages', messages)
46 def connect(self):
47 """
48 Set up the connection required by the handler.
49 Returns
50 -------
51 StatusResponse
52 connection object
53 """
55 if self.is_connected:
56 return StatusResponse(True)
58 url = 'https://discord.com/api/v10/applications/@me'
59 result = requests.get(
60 url,
61 headers={
62 'Authorization': f'Bot {self.connection_data["token"]}',
63 'Content-Type': 'application/json',
64 },
65 )
67 if result.status_code != 200:
68 raise ValueError(result.text)
70 self.is_connected = True
72 def check_connection(self) -> StatusResponse:
73 """
74 Check connection to the handler.
75 Returns:
76 HandlerStatusResponse
77 """
79 response = StatusResponse(False)
81 try:
82 self.connect()
83 response.success = True
84 except Exception as e:
85 response.error_message = e
86 logger.error(f'Error connecting to Discord: {response.error_message}')
88 self.is_connected = response.success
90 return response
92 def native_query(self, query: str = None) -> StatusResponse:
93 """Receive and process a raw query.
94 Parameters
95 ----------
96 query : str
97 query in a native format
98 Returns
99 -------
100 StatusResponse
101 Request status
102 """
103 operation, params = FuncParser().from_string(query)
105 df = self.call_discord_api(operation, params)
107 return Response(RESPONSE_TYPE.TABLE, data_frame=df)
109 def utc_to_snowflake(self, utc_date: str) -> int:
110 """
111 Convert a UTC date to a Snowflake date.
112 Args:
113 utc_date (str): the UTC date
114 Returns:
115 int
116 """
117 # https://discord.com/developers/docs/reference#snowflakes
118 return str(
119 int(parse_utc_date(utc_date).timestamp() * 1000 - 1420070400000) << 22
120 )
122 def call_discord_api(
123 self, operation: str, params: dict = None, filters: list = None
124 ):
125 """
126 Call a Discord API method.
127 Args:
128 method_name (str): the method name
129 params (dict): the method parameters
130 Returns:
131 pd.DataFrame
132 """
134 if operation == 'get_messages':
135 param_strings = {'limit': params['limit']}
136 if 'after' in params:
137 param_strings['after'] = self.utc_to_snowflake(params['after'])
138 if 'before' in params:
139 param_strings['before'] = self.utc_to_snowflake(params['before'])
141 url = (
142 f'https://discord.com/api/v10/channels/{params["channel_id"]}/messages'
143 )
144 result = requests.get(
145 url,
146 headers={
147 'Authorization': f'Bot {self.connection_data["token"]}',
148 'Content-Type': 'application/json',
149 },
150 params=param_strings,
151 )
153 if result.status_code != 200:
154 raise ValueError(f'Error calling Discord API: {result.json()}')
156 json = result.json()
157 for message in json:
158 author = message.get('author')
159 if author is not None:
160 message['author_id'] = author.get('id')
161 message['author_username'] = author.get('username')
162 message['author_global_name'] = author.get('global_name')
164 df = pd.DataFrame.from_records(json)
165 return df
166 elif operation == 'send_message':
167 url = (
168 f'https://discord.com/api/v10/channels/{params["channel_id"]}/messages'
169 )
170 result = requests.post(
171 url,
172 headers={
173 'Authorization': f'Bot {self.connection_data["token"]}',
174 'Content-Type': 'application/json',
175 },
176 json={
177 'content': params['text'],
178 },
179 )
181 if result.status_code != 200:
182 raise ValueError(f'Error calling Discord API: {result.json()}')
184 df = pd.DataFrame.from_records([result.json()])
185 return df
186 else:
187 raise ValueError(f"Unsupported method: {operation}")