fake-slack-app/main.py

162 lines
6.5 KiB
Python
Raw Normal View History

2024-06-05 17:39:00 +00:00
import os, sys
2024-06-03 23:24:56 +00:00
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
from dotenv import load_dotenv
import firepup650 as fp
from traceback import format_exc
2024-06-03 23:24:56 +00:00
input = fp.replitInput
2024-06-04 22:18:48 +00:00
fp.replitCursor = (
fp.bcolors.REPLIT + ">>>" + fp.bcolors.RESET
) # Totally not hijacking one of my functions to use ;P
2024-06-03 23:24:56 +00:00
load_dotenv()
for requiredVar in ["SLACK_BOT_TOKEN", "SLACK_APP_TOKEN"]:
if not os.environ.get(requiredVar):
2024-06-04 22:18:48 +00:00
raise ValueError(
2024-06-05 17:52:56 +00:00
f'Missing required environment variable "{requiredVar}". Please create a .env file in the same directory as this script and define the missing variable.'
2024-06-04 22:18:48 +00:00
)
2024-06-03 23:24:56 +00:00
2024-06-05 18:05:50 +00:00
print("[INFO] Establishing a connection to slack...")
2024-06-03 23:24:56 +00:00
app = App(token=os.environ.get("SLACK_BOT_TOKEN"))
client = app.client
2024-06-05 17:39:00 +00:00
userMappings = {}
try:
if "--no-cache" in sys.argv:
2024-06-05 18:05:50 +00:00
print("[INFO] Skipping cache on user request")
2024-06-05 17:39:00 +00:00
raise ImportError("User requested to skip cache")
2024-06-05 18:05:50 +00:00
print("[INFO] Trying to load user mappings from cache...")
2024-06-05 17:39:00 +00:00
from cache import userMappings
2024-06-05 18:01:23 +00:00
print(
2024-06-05 18:05:50 +00:00
"""[INFO] Cache load OK.
[INFO] Reminder: If you need to regenerate the cache, call the script with `--no-cache`"""
2024-06-05 18:01:23 +00:00
)
2024-06-05 17:39:00 +00:00
except ImportError:
users_list = []
2024-06-05 18:05:50 +00:00
print("[WARN] Cache load failed, falling back to full load from slack...")
2024-06-05 17:39:00 +00:00
cursor = "N/A"
pages = 0
2024-06-05 18:01:23 +00:00
while (
cursor
): # If slack gives us a cursor, then we ain't done loading user data yet
2024-06-05 17:39:00 +00:00
data = ""
if cursor != "N/A":
data = client.users_list(cursor=cursor, limit=1000)
else:
data = client.users_list(limit=1000)
cursor = data["response_metadata"]["next_cursor"]
users_list.extend(data["members"])
pages += 1
2024-06-05 18:05:57 +00:00
print(
f"[INFO] Pages of users loaded: {pages} (Estimated user count: {len(pages) * 1000}"
)
2024-06-05 17:39:00 +00:00
del pages
2024-06-05 18:05:50 +00:00
print("[INFO] Building user mappings now, this shouldn't take long...")
2024-06-05 18:01:23 +00:00
for (
user
) in (
users_list
): # Map user ID mentions to user name mentions, it's nicer when printing messages for thread selection.
2024-06-05 17:39:00 +00:00
userMappings[f"<@{user['id']}>"] = (
2024-06-05 17:50:37 +00:00
f"<@{user['profile']['display_name_normalized']}>"
if user["profile"]["display_name_normalized"]
2024-06-05 18:01:00 +00:00
else ( # User is missing a display name for some reason, fallback to real names
2024-06-05 17:50:37 +00:00
f"<@{user['profile']['real_name_normalized']}>"
if user["profile"]["real_name_normalized"]
2024-06-05 18:01:00 +00:00
else f"<@{user['id']}>" # User is missing a real name too... Fallback to ID
2024-06-05 17:48:35 +00:00
)
2024-06-05 17:39:00 +00:00
)
2024-06-05 18:05:50 +00:00
print("[INFO] All mappings generated, writing cache file now...")
2024-06-05 18:01:23 +00:00
with open(
"cache.py", "w"
) as cacheFile: # It is many times faster to load from a local file instead of from slack
2024-06-05 17:39:00 +00:00
cacheFile.write(f"userMappings = {userMappings}")
2024-06-05 18:05:50 +00:00
print("[INFO] Cache saved.")
2024-06-05 18:05:50 +00:00
print("[INFO] User mappings loaded. User count:", len(userMappings))
2024-06-03 23:24:56 +00:00
if __name__ == "__main__":
2024-06-05 18:05:50 +00:00
print("[INFO] ^D at any time to terminate program")
2024-06-03 23:24:56 +00:00
while 1:
chan = input("Channel ID")
2024-06-03 23:24:56 +00:00
try:
2024-06-05 18:05:50 +00:00
print("[INFO] ^C to change channel")
2024-06-03 23:24:56 +00:00
while 1:
thread = input("Reply to a thread? (y|N)").lower().startswith("y")
2024-06-03 23:24:56 +00:00
ts = None
if thread:
2024-06-04 22:18:48 +00:00
hasID = (
input("Do you have the TS ID? (y|N))").lower().startswith("y")
)
2024-06-03 23:24:56 +00:00
if not hasID:
try:
2024-06-04 22:18:48 +00:00
print(
2024-06-05 18:05:50 +00:00
"[INFO] Getting the last 50 messages for threading options..."
2024-06-04 22:18:48 +00:00
)
2024-06-03 23:24:56 +00:00
res = client.conversations_history(
channel=chan, inclusive=True, limit=50
2024-06-03 23:24:56 +00:00
)
messages = res["messages"]
texts = {}
2024-06-05 18:05:57 +00:00
print(
"[INFO] Building messages, this might take a little bit..."
)
for i in range(len(messages)):
label = f'{messages[i]["text"]} ({messages[i]["ts"]})'
2024-06-05 17:39:00 +00:00
for user in userMappings:
label = label.replace(user, userMappings[user])
texts[label] = i
2024-06-04 22:18:48 +00:00
found = messages[
fp.menu(
texts,
"Please select the message to reply to as a thread",
)
]
2024-06-03 23:24:56 +00:00
ts = found["ts"]
except Exception as E:
print("[WARN] Exception:")
2024-06-05 18:13:26 +00:00
for line in format_exc():
print(f"[WARN] {line}")
break
2024-06-03 23:24:56 +00:00
else:
ts = input("TS ID")
2024-06-04 22:18:48 +00:00
print(
2024-06-05 18:05:50 +00:00
"[INFO] ^C to change/exit thread (^C twice if you want to change channel)"
2024-06-04 22:18:48 +00:00
)
try:
2024-06-04 22:18:48 +00:00
while 1:
2024-06-05 05:06:46 +00:00
msg = input(
"[THREAD] Message (Raw text, not blocks)"
).replace("\\n", "\n")
2024-06-04 22:18:48 +00:00
try:
client.chat_postMessage(
channel=chan, text=msg, thread_ts=ts
2024-06-03 23:24:56 +00:00
)
2024-06-05 18:05:50 +00:00
print("[INFO] Message sent (to the thread)!")
2024-06-04 22:18:48 +00:00
except Exception as E:
print("[WARN] Exception:")
2024-06-05 18:13:26 +00:00
for line in format_exc():
print(f"[WARN] {line}")
break
except KeyboardInterrupt:
print()
if ts:
continue
2024-06-05 05:06:46 +00:00
msg = input("[CHANNEL] Message (Raw text, not blocks)").replace(
"\\n", "\n"
)
2024-06-03 23:24:56 +00:00
try:
client.chat_postMessage(channel=chan, text=msg)
2024-06-05 18:05:50 +00:00
print("[INFO] Message sent (to the channel)!")
2024-06-03 23:24:56 +00:00
except Exception as E:
print("[WARN] Exception:")
2024-06-05 18:13:26 +00:00
for line in format_exc():
print(f"[WARN] {line}")
break
2024-06-03 23:24:56 +00:00
except KeyboardInterrupt:
print()