Compare commits

...

8 commits

77
main.py
View file

@ -15,25 +15,33 @@ load_dotenv()
for requiredVar in ["SLACK_BOT_TOKEN", "SLACK_APP_TOKEN"]: for requiredVar in ["SLACK_BOT_TOKEN", "SLACK_APP_TOKEN"]:
if not os.environ.get(requiredVar): if not os.environ.get(requiredVar):
raise ValueError( raise ValueError(
f'Missing required environment variable "{requiredVar}". Please create a .env file in the same directory as this script and define it.' f'Missing required environment variable "{requiredVar}". Please create a .env file in the same directory as this script and define the missing variable.'
) )
print("Establishing a connection to slack...") print("[INFO] Establishing a connection to slack...")
app = App(token=os.environ.get("SLACK_BOT_TOKEN")) app = App(token=os.environ.get("SLACK_BOT_TOKEN"))
client = app.client client = app.client
userMappings = {} userMappings = {}
try: try:
if "--no-cache" in sys.argv: if "--no-cache" in sys.argv:
print("[INFO] Skipping cache on user request")
raise ImportError("User requested to skip cache") raise ImportError("User requested to skip cache")
print("Trying to load user mappings from cache...") print("[INFO] Trying to load user mappings from cache...")
from cache import userMappings from cache import userMappings
print(
"""[INFO] Cache load OK.
[INFO] Reminder: If you need to regenerate the cache, call the script with `--no-cache`"""
)
except ImportError: except ImportError:
users_list = [] users_list = []
print("Cache load failed, falling back to full load from slack...") print("[WARN] Cache load failed, falling back to full load from slack...")
cursor = "N/A" cursor = "N/A"
pages = 0 pages = 0
while cursor: while (
cursor
): # If slack gives us a cursor, then we ain't done loading user data yet
data = "" data = ""
if cursor != "N/A": if cursor != "N/A":
data = client.users_list(cursor=cursor, limit=1000) data = client.users_list(cursor=cursor, limit=1000)
@ -42,29 +50,40 @@ except ImportError:
cursor = data["response_metadata"]["next_cursor"] cursor = data["response_metadata"]["next_cursor"]
users_list.extend(data["members"]) users_list.extend(data["members"])
pages += 1 pages += 1
print(f"Pages of users loaded: {pages}") print(
del pages f"[INFO] Pages of users loaded: {pages} (Estimated user count: {len(pages) * 1000}"
print("Building user mappings now, this shouldn't take long...")
userMappings = {}
for user in users_list:
userMappings[f"<@{user['id']}>"] = (
f"<@{user['profile']['display_name']}>"
if user["profile"]["display_name"]
else f"<@{user['id']}>"
) )
print("All mappings generated, writing cache file now...") del pages
with open("cache.py", "w") as cacheFile: print("[INFO] Building user mappings now, this shouldn't take long...")
for (
user
) in (
users_list
): # Map user ID mentions to user name mentions, it's nicer when printing messages for thread selection.
userMappings[f"<@{user['id']}>"] = (
f"<@{user['profile']['display_name_normalized']}>"
if user["profile"]["display_name_normalized"]
else ( # User is missing a display name for some reason, fallback to real names
f"<@{user['profile']['real_name_normalized']}>"
if user["profile"]["real_name_normalized"]
else f"<@{user['id']}>" # User is missing a real name too... Fallback to ID
)
)
print("[INFO] All mappings generated, writing cache file now...")
with open(
"cache.py", "w"
) as cacheFile: # It is many times faster to load from a local file instead of from slack
cacheFile.write(f"userMappings = {userMappings}") cacheFile.write(f"userMappings = {userMappings}")
print("Cache saved.") print("[INFO] Cache saved.")
print("User mappings loaded. User count:", len(userMappings)) print("[INFO] User mappings loaded. User count:", len(userMappings))
if __name__ == "__main__": if __name__ == "__main__":
print("^D at any time to terminate program") print("[INFO] ^D at any time to terminate program")
while 1: while 1:
chan = input("Channel ID") chan = input("Channel ID")
try: try:
print("^C to change channel") print("[INFO] ^C to change channel")
while 1: while 1:
thread = input("Reply to a thread? (y|N)").lower().startswith("y") thread = input("Reply to a thread? (y|N)").lower().startswith("y")
ts = None ts = None
@ -75,14 +94,16 @@ if __name__ == "__main__":
if not hasID: if not hasID:
try: try:
print( print(
"Getting the last 50 messages for threading options..." "[INFO] Getting the last 50 messages for threading options..."
) )
res = client.conversations_history( res = client.conversations_history(
channel=chan, inclusive=True, limit=50 channel=chan, inclusive=True, limit=50
) )
messages = res["messages"] messages = res["messages"]
texts = {} texts = {}
print("Building messages, this might take a little bit...") print(
"[INFO] Building messages, this might take a little bit..."
)
for i in range(len(messages)): for i in range(len(messages)):
label = f'{messages[i]["text"]} ({messages[i]["ts"]})' label = f'{messages[i]["text"]} ({messages[i]["ts"]})'
for user in userMappings: for user in userMappings:
@ -96,12 +117,12 @@ if __name__ == "__main__":
] ]
ts = found["ts"] ts = found["ts"]
except Exception as E: except Exception as E:
print(f"Exception: {E}") print(f"[WARN] Exception: {E}")
break break
else: else:
ts = input("TS ID") ts = input("TS ID")
print( print(
"^C to change/exit thread (^C twice if you want to change channel)" "[INFO] ^C to change/exit thread (^C twice if you want to change channel)"
) )
try: try:
while 1: while 1:
@ -112,9 +133,9 @@ if __name__ == "__main__":
client.chat_postMessage( client.chat_postMessage(
channel=chan, text=msg, thread_ts=ts channel=chan, text=msg, thread_ts=ts
) )
print("Message sent (to the thread)!") print("[INFO] Message sent (to the thread)!")
except Exception as E: except Exception as E:
print(f"Exception: {E}") print(f"[WARN] Exception: {E}")
except KeyboardInterrupt: except KeyboardInterrupt:
print() print()
if ts: if ts:
@ -124,8 +145,8 @@ if __name__ == "__main__":
) )
try: try:
client.chat_postMessage(channel=chan, text=msg) client.chat_postMessage(channel=chan, text=msg)
print("Message sent (to the channel)!") print("[INFO] Message sent (to the channel)!")
except Exception as E: except Exception as E:
print(f"Exception: {E}") print(f"[WARN] Exception: {E}")
except KeyboardInterrupt: except KeyboardInterrupt:
print() print()