webex-bot 1.0.7__py2.py3-none-any.whl → 1.1.12__py2.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.
- webex_bot/__init__.py +1 -1
- webex_bot/commands/echo.py +1 -0
- webex_bot/webex_bot.py +59 -40
- webex_bot/websockets/webex_websocket_client.py +41 -8
- {webex_bot-1.0.7.dist-info → webex_bot-1.1.12.dist-info}/METADATA +18 -23
- webex_bot-1.1.12.dist-info/RECORD +18 -0
- {webex_bot-1.0.7.dist-info → webex_bot-1.1.12.dist-info}/WHEEL +1 -1
- webex_bot-1.0.7.dist-info/RECORD +0 -18
- {webex_bot-1.0.7.dist-info/licenses → webex_bot-1.1.12.dist-info}/LICENSE +0 -0
- {webex_bot-1.0.7.dist-info → webex_bot-1.1.12.dist-info}/top_level.txt +0 -0
webex_bot/__init__.py
CHANGED
webex_bot/commands/echo.py
CHANGED
webex_bot/webex_bot.py
CHANGED
|
@@ -102,7 +102,8 @@ class WebexBot(WebexWebsocketClient):
|
|
|
102
102
|
"""
|
|
103
103
|
me = self.teams.people.me()
|
|
104
104
|
self.bot_display_name = me.displayName
|
|
105
|
-
|
|
105
|
+
self.bot_email = me.emails[0]
|
|
106
|
+
log.info(f"Running as {me.type} '{me.displayName}' with email {self.bot_email}")
|
|
106
107
|
log.debug(f"Running as bot '{me}'")
|
|
107
108
|
return me
|
|
108
109
|
|
|
@@ -173,7 +174,7 @@ class WebexBot(WebexWebsocketClient):
|
|
|
173
174
|
if member.personEmail == user_email:
|
|
174
175
|
is_user_member = True
|
|
175
176
|
except webexpythonsdk.exceptions.ApiError as apie:
|
|
176
|
-
log.
|
|
177
|
+
log.warning(f"API error: {apie}")
|
|
177
178
|
return is_user_member
|
|
178
179
|
|
|
179
180
|
def process_incoming_card_action(self, attachment_actions, activity):
|
|
@@ -207,12 +208,15 @@ class WebexBot(WebexWebsocketClient):
|
|
|
207
208
|
is_one_on_one_space = 'ONE_ON_ONE' in activity['target']['tags']
|
|
208
209
|
|
|
209
210
|
if activity['actor']['type'] != 'PERSON':
|
|
211
|
+
if self.bot_email == user_email:
|
|
212
|
+
log.warning(f"Message is from myself ({self.bot_email}), ignoring.")
|
|
213
|
+
return
|
|
210
214
|
if not self.allow_bot_to_bot:
|
|
211
|
-
log.warning(f"Message is from a bot ({user_email}), ignoring")
|
|
215
|
+
log.warning(f"Message is from a bot ({user_email}), ignoring.")
|
|
212
216
|
return
|
|
213
217
|
else:
|
|
214
218
|
log.warning(
|
|
215
|
-
f"Message is from
|
|
219
|
+
f"Message is from another bot ({user_email}), and allow_bot_to_bot is {self.allow_bot_to_bot}. Be careful not to create a message loop!")
|
|
216
220
|
|
|
217
221
|
# Log details on message
|
|
218
222
|
log.info(f"Message from {user_email}: {teams_message}")
|
|
@@ -304,6 +308,8 @@ class WebexBot(WebexWebsocketClient):
|
|
|
304
308
|
log.info(f"delete_previous_message is True. Deleting message with ID: {previous_message_id}")
|
|
305
309
|
self.teams.messages.delete(previous_message_id)
|
|
306
310
|
|
|
311
|
+
pre_reply_message_id = None
|
|
312
|
+
|
|
307
313
|
if not is_card_callback_command and command.card is not None:
|
|
308
314
|
response = Response()
|
|
309
315
|
response.text = "This bot requires a client which can render cards."
|
|
@@ -316,7 +322,7 @@ class WebexBot(WebexWebsocketClient):
|
|
|
316
322
|
message=message_without_command,
|
|
317
323
|
teams_message=teams_message,
|
|
318
324
|
activity=activity)
|
|
319
|
-
self.do_reply(pre_card_load_reply, room_id, user_email, pre_card_load_reply_one_to_one, is_one_on_one_space, thread_parent_id)
|
|
325
|
+
pre_reply_message_id = self.do_reply(pre_card_load_reply, room_id, user_email, pre_card_load_reply_one_to_one, is_one_on_one_space, thread_parent_id)
|
|
320
326
|
reply = response
|
|
321
327
|
else:
|
|
322
328
|
log.debug(f"Going to run command: '{command}' with input: '{message_without_command}'")
|
|
@@ -324,25 +330,36 @@ class WebexBot(WebexWebsocketClient):
|
|
|
324
330
|
message=message_without_command,
|
|
325
331
|
teams_message=teams_message,
|
|
326
332
|
activity=activity)
|
|
327
|
-
self.do_reply(pre_execute_reply, room_id, user_email, pre_execute_reply_one_to_one, is_one_on_one_space, thread_parent_id)
|
|
333
|
+
pre_reply_message_id = self.do_reply(pre_execute_reply, room_id, user_email, pre_execute_reply_one_to_one, is_one_on_one_space, thread_parent_id)
|
|
328
334
|
reply, reply_one_to_one = self.run_command_and_handle_bot_exceptions(command=command,
|
|
329
335
|
message=message_without_command,
|
|
330
336
|
teams_message=teams_message,
|
|
331
337
|
activity=activity)
|
|
332
338
|
log.info(f"Using thread id={thread_parent_id}")
|
|
333
|
-
|
|
339
|
+
final_message_id = self.do_reply(reply, room_id, user_email, reply_one_to_one, is_one_on_one_space, thread_parent_id)
|
|
340
|
+
|
|
341
|
+
# If requested, delete the pre-execute (or pre-card-load) message once the final reply has been sent
|
|
342
|
+
if command.delete_previous_message and pre_reply_message_id:
|
|
343
|
+
try:
|
|
344
|
+
log.info(f"Deleting pre-execute message with ID: {pre_reply_message_id}")
|
|
345
|
+
self.teams.messages.delete(pre_reply_message_id)
|
|
346
|
+
except Exception as e:
|
|
347
|
+
log.warning(f"Failed to delete pre-execute message {pre_reply_message_id}: {e}")
|
|
348
|
+
|
|
349
|
+
return final_message_id
|
|
334
350
|
|
|
335
351
|
def do_reply(self, reply, room_id, user_email, reply_one_to_one, is_one_on_one_space, conv_target_id):
|
|
336
352
|
# allow command handlers to craft their own Teams message
|
|
353
|
+
created_message_id = None
|
|
337
354
|
if reply and isinstance(reply, Response):
|
|
338
355
|
# If the Response lacks a roomId, set it to the incoming room
|
|
339
356
|
if not reply.roomId:
|
|
340
357
|
reply.roomId = room_id
|
|
341
358
|
if not reply.parentId and conv_target_id and self.threads:
|
|
342
359
|
reply.parentId = conv_target_id
|
|
343
|
-
|
|
344
|
-
self.teams.messages.create(**
|
|
345
|
-
|
|
360
|
+
reply_dict = reply.as_dict()
|
|
361
|
+
created = self.teams.messages.create(**reply_dict)
|
|
362
|
+
created_message_id = getattr(created, 'id', None)
|
|
346
363
|
# Support returning a list of Responses
|
|
347
364
|
elif reply and (isinstance(reply, list) or isinstance(reply, types.GeneratorType)):
|
|
348
365
|
for response in reply:
|
|
@@ -352,24 +369,24 @@ class WebexBot(WebexWebsocketClient):
|
|
|
352
369
|
response.roomId = room_id
|
|
353
370
|
if not response.parentId and conv_target_id:
|
|
354
371
|
response.parentId = conv_target_id
|
|
355
|
-
self.teams.messages.create(**response.as_dict())
|
|
372
|
+
created = self.teams.messages.create(**response.as_dict())
|
|
373
|
+
created_message_id = getattr(created, 'id', None)
|
|
356
374
|
else:
|
|
357
375
|
# Just a plain message
|
|
358
|
-
self.send_message_to_room_or_person(user_email,
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
reply = "ok"
|
|
376
|
+
created_message_id = self.send_message_to_room_or_person(user_email,
|
|
377
|
+
room_id,
|
|
378
|
+
reply_one_to_one,
|
|
379
|
+
is_one_on_one_space,
|
|
380
|
+
response,
|
|
381
|
+
conv_target_id)
|
|
365
382
|
elif reply:
|
|
366
|
-
self.send_message_to_room_or_person(user_email,
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
return
|
|
383
|
+
created_message_id = self.send_message_to_room_or_person(user_email,
|
|
384
|
+
room_id,
|
|
385
|
+
reply_one_to_one,
|
|
386
|
+
is_one_on_one_space,
|
|
387
|
+
reply,
|
|
388
|
+
conv_target_id)
|
|
389
|
+
return created_message_id
|
|
373
390
|
|
|
374
391
|
def send_message_to_room_or_person(self,
|
|
375
392
|
user_email,
|
|
@@ -380,27 +397,29 @@ class WebexBot(WebexWebsocketClient):
|
|
|
380
397
|
conv_target_id):
|
|
381
398
|
default_move_to_one_to_one_heads_up = \
|
|
382
399
|
quote_info(f"{user_email} I've messaged you 1-1. Please reply to me there.")
|
|
400
|
+
last_created = None
|
|
383
401
|
if reply_one_to_one:
|
|
384
402
|
if not is_one_on_one_space:
|
|
385
403
|
if self.threads:
|
|
386
|
-
self.teams.messages.create(roomId=room_id,
|
|
387
|
-
|
|
388
|
-
|
|
404
|
+
last_created = self.teams.messages.create(roomId=room_id,
|
|
405
|
+
markdown=default_move_to_one_to_one_heads_up,
|
|
406
|
+
parentId=conv_target_id)
|
|
389
407
|
else:
|
|
390
|
-
self.teams.messages.create(roomId=room_id,
|
|
391
|
-
|
|
408
|
+
last_created = self.teams.messages.create(roomId=room_id,
|
|
409
|
+
markdown=default_move_to_one_to_one_heads_up)
|
|
392
410
|
if self.threads:
|
|
393
|
-
self.teams.messages.create(toPersonEmail=user_email,
|
|
394
|
-
|
|
395
|
-
|
|
411
|
+
last_created = self.teams.messages.create(toPersonEmail=user_email,
|
|
412
|
+
markdown=reply,
|
|
413
|
+
parentId=conv_target_id)
|
|
396
414
|
else:
|
|
397
|
-
self.teams.messages.create(toPersonEmail=user_email,
|
|
398
|
-
|
|
415
|
+
last_created = self.teams.messages.create(toPersonEmail=user_email,
|
|
416
|
+
markdown=reply)
|
|
399
417
|
else:
|
|
400
418
|
if self.threads:
|
|
401
|
-
self.teams.messages.create(roomId=room_id, markdown=reply, parentId=conv_target_id)
|
|
419
|
+
last_created = self.teams.messages.create(roomId=room_id, markdown=reply, parentId=conv_target_id)
|
|
402
420
|
else:
|
|
403
|
-
self.teams.messages.create(roomId=room_id, markdown=reply)
|
|
421
|
+
last_created = self.teams.messages.create(roomId=room_id, markdown=reply)
|
|
422
|
+
return getattr(last_created, 'id', None)
|
|
404
423
|
|
|
405
424
|
def run_pre_card_load_reply(self, command, message, teams_message, activity):
|
|
406
425
|
"""
|
|
@@ -409,7 +428,7 @@ class WebexBot(WebexWebsocketClient):
|
|
|
409
428
|
try:
|
|
410
429
|
return command.pre_card_load_reply(message, teams_message, activity), False
|
|
411
430
|
except BotException as e:
|
|
412
|
-
log.
|
|
431
|
+
log.warning(f"BotException: {e.debug_message}")
|
|
413
432
|
return e.reply_message, e.reply_one_to_one
|
|
414
433
|
|
|
415
434
|
def run_pre_execute(self, command, message, teams_message, activity):
|
|
@@ -419,14 +438,14 @@ class WebexBot(WebexWebsocketClient):
|
|
|
419
438
|
try:
|
|
420
439
|
return command.pre_execute(message, teams_message, activity), False
|
|
421
440
|
except BotException as e:
|
|
422
|
-
log.
|
|
441
|
+
log.warning(f"BotException: {e.debug_message}")
|
|
423
442
|
return e.reply_message, e.reply_one_to_one
|
|
424
443
|
|
|
425
444
|
def run_command_and_handle_bot_exceptions(self, command, message, teams_message, activity):
|
|
426
445
|
try:
|
|
427
446
|
return command.card_callback(message, teams_message, activity), False
|
|
428
447
|
except BotException as e:
|
|
429
|
-
log.
|
|
448
|
+
log.warning(f"BotException: {e.debug_message}")
|
|
430
449
|
return e.reply_message, e.reply_one_to_one
|
|
431
450
|
|
|
432
451
|
@staticmethod
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import json
|
|
3
|
+
import inspect
|
|
3
4
|
import logging
|
|
4
5
|
import socket
|
|
5
6
|
import ssl
|
|
@@ -10,7 +11,10 @@ import certifi
|
|
|
10
11
|
import requests
|
|
11
12
|
import websockets
|
|
12
13
|
from webexpythonsdk import WebexAPI
|
|
13
|
-
|
|
14
|
+
try:
|
|
15
|
+
from websockets import InvalidStatus
|
|
16
|
+
except ImportError: # pragma: no cover - fallback for older websockets versions
|
|
17
|
+
from websockets.exceptions import InvalidStatus
|
|
14
18
|
|
|
15
19
|
from webex_bot import __version__
|
|
16
20
|
|
|
@@ -79,6 +83,20 @@ class WebexWebsocketClient(object):
|
|
|
79
83
|
"trackingid": self.tracking_id
|
|
80
84
|
}
|
|
81
85
|
|
|
86
|
+
def _get_websocket_connect_kwargs(self, connect_func):
|
|
87
|
+
headers = self._get_headers()
|
|
88
|
+
try:
|
|
89
|
+
params = inspect.signature(connect_func).parameters
|
|
90
|
+
except (TypeError, ValueError):
|
|
91
|
+
return {"extra_headers": headers}
|
|
92
|
+
|
|
93
|
+
if "extra_headers" in params:
|
|
94
|
+
return {"extra_headers": headers}
|
|
95
|
+
if "additional_headers" in params:
|
|
96
|
+
return {"additional_headers": headers}
|
|
97
|
+
|
|
98
|
+
return {"extra_headers": headers}
|
|
99
|
+
|
|
82
100
|
def _process_incoming_websocket_message(self, msg):
|
|
83
101
|
"""
|
|
84
102
|
Handle websocket data.
|
|
@@ -247,7 +265,7 @@ class WebexWebsocketClient(object):
|
|
|
247
265
|
websockets.ConnectionClosedOK,
|
|
248
266
|
websockets.ConnectionClosed,
|
|
249
267
|
socket.gaierror,
|
|
250
|
-
|
|
268
|
+
InvalidStatus,
|
|
251
269
|
),
|
|
252
270
|
max_time=MAX_BACKOFF_TIME
|
|
253
271
|
)
|
|
@@ -258,14 +276,28 @@ class WebexWebsocketClient(object):
|
|
|
258
276
|
if self.proxies and "wss" in self.proxies:
|
|
259
277
|
logger.info(f"Using proxy for websocket connection: {self.proxies['wss']}")
|
|
260
278
|
proxy = Proxy.from_url(self.proxies["wss"])
|
|
261
|
-
connect = proxy_connect(
|
|
279
|
+
connect = proxy_connect(
|
|
280
|
+
ws_url,
|
|
281
|
+
ssl=ssl_context,
|
|
282
|
+
proxy=proxy,
|
|
283
|
+
**self._get_websocket_connect_kwargs(proxy_connect),
|
|
284
|
+
)
|
|
262
285
|
elif self.proxies and "https" in self.proxies:
|
|
263
286
|
logger.info(f"Using proxy for websocket connection: {self.proxies['https']}")
|
|
264
287
|
proxy = Proxy.from_url(self.proxies["https"])
|
|
265
|
-
connect = proxy_connect(
|
|
288
|
+
connect = proxy_connect(
|
|
289
|
+
ws_url,
|
|
290
|
+
ssl=ssl_context,
|
|
291
|
+
proxy=proxy,
|
|
292
|
+
**self._get_websocket_connect_kwargs(proxy_connect),
|
|
293
|
+
)
|
|
266
294
|
else:
|
|
267
295
|
logger.debug(f"Not using proxy for websocket connection.")
|
|
268
|
-
connect = websockets.connect(
|
|
296
|
+
connect = websockets.connect(
|
|
297
|
+
ws_url,
|
|
298
|
+
ssl=ssl_context,
|
|
299
|
+
**self._get_websocket_connect_kwargs(websockets.connect),
|
|
300
|
+
)
|
|
269
301
|
|
|
270
302
|
async with connect as _websocket:
|
|
271
303
|
self.websocket = _websocket
|
|
@@ -287,10 +319,11 @@ class WebexWebsocketClient(object):
|
|
|
287
319
|
asyncio.get_event_loop().run_until_complete(_connect_and_listen())
|
|
288
320
|
# If we get here, the connection was successful, so break out of the loop
|
|
289
321
|
break
|
|
290
|
-
except
|
|
291
|
-
|
|
322
|
+
except InvalidStatus as e:
|
|
323
|
+
status_code = getattr(e.response, "status_code", None)
|
|
324
|
+
logger.error(f"WebSocket handshake to {ws_url} failed with status {status_code}")
|
|
292
325
|
|
|
293
|
-
if
|
|
326
|
+
if status_code == 404:
|
|
294
327
|
current_404_retries += 1
|
|
295
328
|
if current_404_retries >= max_404_retries:
|
|
296
329
|
logger.error(f"Reached maximum retries ({max_404_retries}) for 404 errors. Giving up.")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
2
|
Name: webex_bot
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.12
|
|
4
4
|
Summary: Python package for a Webex Bot based on websockets.
|
|
5
5
|
Home-page: https://github.com/fbradyirl/webex_bot
|
|
6
6
|
Author: Finbarr Brady
|
|
@@ -18,29 +18,16 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
18
18
|
Requires-Python: >=3.10
|
|
19
19
|
Description-Content-Type: text/markdown
|
|
20
20
|
License-File: LICENSE
|
|
21
|
-
Requires-Dist: webexpythonsdk==2.0.
|
|
21
|
+
Requires-Dist: webexpythonsdk==2.0.5
|
|
22
22
|
Requires-Dist: coloredlogs
|
|
23
|
-
Requires-Dist: websockets==
|
|
23
|
+
Requires-Dist: websockets==16
|
|
24
24
|
Requires-Dist: backoff
|
|
25
25
|
Provides-Extra: proxy
|
|
26
|
-
Requires-Dist:
|
|
27
|
-
Dynamic: author
|
|
28
|
-
Dynamic: author-email
|
|
29
|
-
Dynamic: classifier
|
|
30
|
-
Dynamic: description
|
|
31
|
-
Dynamic: description-content-type
|
|
32
|
-
Dynamic: home-page
|
|
33
|
-
Dynamic: keywords
|
|
34
|
-
Dynamic: license
|
|
35
|
-
Dynamic: license-file
|
|
36
|
-
Dynamic: provides-extra
|
|
37
|
-
Dynamic: requires-dist
|
|
38
|
-
Dynamic: requires-python
|
|
39
|
-
Dynamic: summary
|
|
26
|
+
Requires-Dist: websockets-proxy>=0.1.3; extra == "proxy"
|
|
40
27
|
|
|
41
28
|
# Introduction
|
|
42
29
|
|
|
43
|
-
[](https://pypi.python.org/pypi/webex_bot) [](https://github.com/fbradyirl/webex_bot/actions)
|
|
30
|
+
[](https://pypi.python.org/pypi/webex_bot) [](https://github.com/fbradyirl/webex_bot/actions) [](https://github.com/fbradyirl/webex_bot/actions/workflows/codeql.yml) [](https://codecov.io/gh/fbradyirl/webex_bot) [](https://github.com/fbradyirl/webex_bot/releases) [](https://pypi.python.org/pypi/webex_bot)
|
|
44
31
|
|
|
45
32
|
> [!IMPORTANT]
|
|
46
33
|
> This repository is only sporadically maintained. Breaking API changes will be maintained on a best efforts basis.
|
|
@@ -50,7 +37,7 @@ Dynamic: summary
|
|
|
50
37
|
> Bug reports unrelated to API changes may not get the attention you want.
|
|
51
38
|
|
|
52
39
|
|
|
53
|
-
By using this module, you can create a [Webex
|
|
40
|
+
By using this module, you can create a [Webex][5] messaging bot quickly in just a couple of lines of code.
|
|
54
41
|
|
|
55
42
|
This module does not require you to set up an ngrok tunnel to receive incoming messages when behind a firewall or
|
|
56
43
|
inside a LAN. This package instead uses a websocket to receive messages from the Webex cloud.
|
|
@@ -75,7 +62,7 @@ You can find a sample project, using OpenAI/ChatGPT with this library here: http
|
|
|
75
62
|
|
|
76
63
|
----
|
|
77
64
|
|
|
78
|
-
**
|
|
65
|
+
**Python 3.10, 3.11, and 3.12 are tested at this time.**
|
|
79
66
|
|
|
80
67
|
1. Install this module from pypi:
|
|
81
68
|
|
|
@@ -113,7 +100,7 @@ proxies = {
|
|
|
113
100
|
# Create a Bot Object
|
|
114
101
|
bot = WebexBot(teams_bot_token=os.getenv("WEBEX_ACCESS_TOKEN"),
|
|
115
102
|
approved_rooms=['06586d8d-6aad-4201-9a69-0bf9eeb5766e'],
|
|
116
|
-
bot_name="My
|
|
103
|
+
bot_name="My Webex Ops Bot",
|
|
117
104
|
include_demo_commands=True,
|
|
118
105
|
proxies=proxies)
|
|
119
106
|
|
|
@@ -460,10 +447,18 @@ bot = WebexBot(teams_bot_token=os.getenv("WEBEX_ACCESS_TOKEN")
|
|
|
460
447
|
|
|
461
448
|
* Update UA
|
|
462
449
|
|
|
463
|
-
### 1.0.
|
|
450
|
+
### 1.0.8 (2025-Sept-18)
|
|
464
451
|
|
|
465
452
|
* Allow flag to disable bot to bot check
|
|
466
453
|
|
|
454
|
+
### 1.1.6 (2026-Feb-02)
|
|
455
|
+
|
|
456
|
+
* Update dependancies.
|
|
457
|
+
* Expand test coverage and add CI matrix for Python 3.10–3.12
|
|
458
|
+
* Add coverage reporting and update contributor docs
|
|
459
|
+
* Refresh websocket status handling to avoid deprecations
|
|
460
|
+
|
|
461
|
+
|
|
467
462
|
[1]: https://github.com/aaugustin/websockets
|
|
468
463
|
|
|
469
464
|
[2]: https://github.com/WebexCommunity/WebexPythonSDK
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
webex_bot/__init__.py,sha256=be-WC6WXfNEs7SDFXNjf9a9eBf9j3BJeRd6KAFiPOLI,96
|
|
2
|
+
webex_bot/exceptions.py,sha256=qs9yVitfJtvxwBMC8uCvTDOxUQ_oZjWFf1dU8Oaue14,740
|
|
3
|
+
webex_bot/formatting.py,sha256=jvPKym-z8CIJygpPVTVbt6vFXQo9_HQHpRDJB-nh-SI,382
|
|
4
|
+
webex_bot/webex_bot.py,sha256=IDCxIbVWyZX0SkDIcvb_iquEcrElXvYQdElDunvxTmA,23350
|
|
5
|
+
webex_bot/cards/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
webex_bot/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
webex_bot/commands/echo.py,sha256=DwKAFHVEP0LrSj0l35uDQQhoeh9w62wUvP5C-IankeM,3441
|
|
8
|
+
webex_bot/commands/help.py,sha256=n7sbnJHepNSqUgZ0-8PW37kbGsaqvGIk2-jYy6I7ch4,3470
|
|
9
|
+
webex_bot/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
+
webex_bot/models/command.py,sha256=MyThlDaEkGlj1fDE_i_wr79O3QboakimRme8yI744yo,5327
|
|
11
|
+
webex_bot/models/response.py,sha256=d4k2ohR5SUVzvuQzcnm7jQQVTMB0gH9Kz9y09vkoAaU,2545
|
|
12
|
+
webex_bot/websockets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
+
webex_bot/websockets/webex_websocket_client.py,sha256=ZIK4GFF0i_EqdDbQj5Sdc6Q0u-nWVWjMbq4Ex4_wToM,14911
|
|
14
|
+
webex_bot-1.1.12.dist-info/LICENSE,sha256=93eGb10xmgkBP2Fh_n0E9YDXe0c0oz-FsnAimXG0S4Y,1072
|
|
15
|
+
webex_bot-1.1.12.dist-info/METADATA,sha256=D2tHNMEEQLaSnn7wzEo6lCFwxYZU2VaQ85WxpRl4TiY,15358
|
|
16
|
+
webex_bot-1.1.12.dist-info/WHEEL,sha256=YqkG3aKUxtNWfdKBz3DzkIakbboD_OAzmgL1ryH-ru4,110
|
|
17
|
+
webex_bot-1.1.12.dist-info/top_level.txt,sha256=q1Y0RtYYinR7oXSwL93cK59c2KN_CbMVca8MLWeF63M,10
|
|
18
|
+
webex_bot-1.1.12.dist-info/RECORD,,
|
webex_bot-1.0.7.dist-info/RECORD
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
webex_bot/__init__.py,sha256=khfK-5S8GGJi-F6Y8AYhEOeZtF7W7B2IBROMjDG_t6U,95
|
|
2
|
-
webex_bot/exceptions.py,sha256=qs9yVitfJtvxwBMC8uCvTDOxUQ_oZjWFf1dU8Oaue14,740
|
|
3
|
-
webex_bot/formatting.py,sha256=jvPKym-z8CIJygpPVTVbt6vFXQo9_HQHpRDJB-nh-SI,382
|
|
4
|
-
webex_bot/webex_bot.py,sha256=fuqucqKCZ-jFo4qW3XAYo7n5g_LB3GQnuAuQHEZRw_Y,21866
|
|
5
|
-
webex_bot/cards/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
webex_bot/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
-
webex_bot/commands/echo.py,sha256=STY-MikBRjUteDK-g8G4GPB0V-Yi7siPN1DRMXrT-QU,3399
|
|
8
|
-
webex_bot/commands/help.py,sha256=n7sbnJHepNSqUgZ0-8PW37kbGsaqvGIk2-jYy6I7ch4,3470
|
|
9
|
-
webex_bot/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
webex_bot/models/command.py,sha256=MyThlDaEkGlj1fDE_i_wr79O3QboakimRme8yI744yo,5327
|
|
11
|
-
webex_bot/models/response.py,sha256=d4k2ohR5SUVzvuQzcnm7jQQVTMB0gH9Kz9y09vkoAaU,2545
|
|
12
|
-
webex_bot/websockets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
-
webex_bot/websockets/webex_websocket_client.py,sha256=ZlyTyNZuWr7cbf0mHBPu7JB432gVwBKT2Gvq9K1Pv5k,13895
|
|
14
|
-
webex_bot-1.0.7.dist-info/licenses/LICENSE,sha256=93eGb10xmgkBP2Fh_n0E9YDXe0c0oz-FsnAimXG0S4Y,1072
|
|
15
|
-
webex_bot-1.0.7.dist-info/METADATA,sha256=ZtQy9gjLJT6gFgrXLk94wBqn9ZGXZViQ2ATs2VX28_I,14887
|
|
16
|
-
webex_bot-1.0.7.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
|
|
17
|
-
webex_bot-1.0.7.dist-info/top_level.txt,sha256=q1Y0RtYYinR7oXSwL93cK59c2KN_CbMVca8MLWeF63M,10
|
|
18
|
-
webex_bot-1.0.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|