Slack_App / config.py
ujalaarshad17's picture
first commit
93dae80 verified
from slack_sdk.errors import SlackApiError
import os
from dotenv import load_dotenv
from slack_sdk import WebClient
import sqlite3
import json
import psycopg2
import logging
from datetime import datetime
# Load environment variables
load_dotenv()
# Slack credentials
SLACK_BOT_TOKEN = os.environ["SLACK_BOT_TOKEN"]
# Initialize the Slack client
client = WebClient(token=SLACK_BOT_TOKEN)
logger = logging.getLogger(__name__)
def load_preferences(team_id, user_id):
with preferences_cache_lock:
if (team_id, user_id) in preferences_cache:
return preferences_cache[(team_id, user_id)]
try:
conn = psycopg2.connect(os.getenv('DATABASE_URL'))
cur = conn.cursor()
cur.execute('SELECT zoom_config, calendar_tool FROM Preferences WHERE team_id = %s AND user_id = %s', (team_id, user_id))
row = cur.fetchone()
if row:
zoom_config, calendar_tool = row
# For jsonb, zoom_config is already a dict; no json.loads needed
preferences = {
"zoom_config": zoom_config if zoom_config else {"mode": "manual", "link": None},
"calendar_tool": calendar_tool or "none"
}
else:
preferences = {"zoom_config": {"mode": "manual", "link": None}, "calendar_tool": "none"}
cur.close()
conn.close()
except Exception as e:
logger.error(f"Failed to load preferences for team {team_id}, user {user_id}: {e}")
preferences = {"zoom_config": {"mode": "manual", "link": None}, "calendar_tool": "none"}
with preferences_cache_lock:
preferences_cache[(team_id, user_id)] = preferences
return preferences
from threading import Lock
user_cache = {}
preferences_cache = {}
preferences_cache_lock = Lock()
user_cache_lock = Lock() # Example threading lock for cache
owner_id_cache = {}
owner_id_lock = Lock()
def initialize_workspace_cache(client, team_id):
conn = psycopg2.connect(os.getenv('DATABASE_URL'))
cur = conn.cursor()
cur.execute('SELECT MAX(last_updated) FROM Users WHERE team_id = %s', (team_id,))
last_updated_row = cur.fetchone()
last_updated = last_updated_row[0] if last_updated_row and last_updated_row[0] else None
# Check if cache is fresh (e.g., less than 24 hours old)
if last_updated and (datetime.now() - last_updated).total_seconds() < 86400:
cur.execute('SELECT user_id, real_name, email, name, is_owner, workspace_name FROM Users WHERE team_id = %s', (team_id,))
rows = cur.fetchall()
new_cache = {row[0]: {"real_name": row[1], "email": row[2], "name": row[3], "is_owner": row[4], "workspace_name": row[5]} for row in rows}
with user_cache_lock:
user_cache[team_id] = new_cache
with owner_id_lock:
owner_id_cache[team_id] = next((user_id for user_id, data in new_cache.items() if data['is_owner']), None)
else:
# Fetch user data from Slack and update database
response = client.users_list()
users = response["members"]
workspace_name = client.team_info()["team"]["name"] # Get workspace name from Slack API
new_cache = {}
for user in users:
user_id = user['id']
profile = user.get('profile', {})
real_name = profile.get('real_name', 'Unknown')
name = user.get('name', '')
email = f"{name}@gmail.com" # Placeholder; adjust as needed
is_owner = user.get('is_owner', False)
new_cache[user_id] = {"real_name": real_name, "email": email, "name": name, "is_owner": is_owner, "workspace_name": workspace_name}
cur.execute('''
INSERT INTO Users (team_id, user_id, workspace_name, real_name, email, name, is_owner, last_updated)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
ON CONFLICT (team_id, user_id) DO UPDATE SET
workspace_name = %s, real_name = %s, email = %s, name = %s, is_owner = %s, last_updated = %s
''', (team_id, user_id, workspace_name, real_name, email, name, is_owner, datetime.now(),
workspace_name, real_name, email, name, is_owner, datetime.now()))
conn.commit()
with user_cache_lock:
user_cache[team_id] = new_cache
with owner_id_lock:
owner_id_cache[team_id] = next((user_id for user_id, data in new_cache.items() if data['is_owner']), None)
cur.close()
conn.close()
def get_workspace_owner_id_client(client ):
"""Get the workspace owner's user ID."""
try:
response = client.users_list()
members = response["members"]
for member in members:
if member.get("is_owner"):
return member["id"]
except SlackApiError as e:
print(f"Error fetching users: {e.response['error']}")
return None
def get_workspace_owner_id(client, team_id):
with owner_id_lock:
if team_id in owner_id_cache and owner_id_cache[team_id]:
return owner_id_cache[team_id]
initialize_workspace_cache(client, team_id)
with owner_id_lock:
return owner_id_cache.get(team_id)
# def get_workspace_owner_id():
# conn = sqlite3.connect('workspace_cache.db')
# c = conn.cursor()
# c.execute('SELECT user_id FROM workspace_cache WHERE is_owner = 1')
# owner_id = c.fetchone()
# conn.close()
# return owner_id[0] if owner_id else None
owner_id_pref = get_workspace_owner_id_client(client)
def GetAllUsers():
all_users = {}
try:
response = client.users_list()
print(response)
members = response['members']
for member in members:
user_id = member['id']
profile = member.get('profile', {})
user_name = profile.get('real_name', '') # Use real_name from profile
# Use actual email if available, otherwise construct one from member['name']
email = profile.get('email', f"{member.get('name', '')}@gmail.com")
print(f"User ID: {user_id}, Name: {user_name}, Email: {email}")
all_users[user_id] = {"Slack Id": user_id, "name": user_name, "email": email}
return all_users
except SlackApiError as e:
print(f"Error fetching users: {e.response['error']}")
return {}
def load_token(team_id, user_id, service):
"""
Load token data from the database for a specific team, user, and service.
Parameters:
team_id (str): The Slack team ID.
user_id (str): The Slack user ID.
service (str): The service name (e.g., 'google').
Returns:
dict: The token data as a dictionary, or None if not found.
"""
conn = psycopg2.connect(os.getenv('DATABASE_URL'))
cur = conn.cursor()
cur.execute(
'SELECT token_data FROM Tokens WHERE team_id = %s AND user_id = %s AND service = %s',
(team_id, user_id, service)
)
row = cur.fetchone()
cur.close()
conn.close()
return row[0] if row else None
def save_token(team_id, user_id, service, token_data):
"""
Save token data to the database for a specific team, user, and service.
Parameters:
team_id (str): The Slack team ID.
user_id (str): The Slack user ID.
service (str): The service name (e.g., 'google').
token_data (dict): The token data to save (e.g., {'access_token', 'refresh_token', 'expires_at'}).
"""
conn = psycopg2.connect(os.getenv('DATABASE_URL'))
cur = conn.cursor()
cur.execute(
'''
INSERT INTO Tokens (team_id, user_id, service, token_data, updated_at)
VALUES (%s, %s, %s, %s, %s)
ON CONFLICT (team_id, user_id, service)
DO UPDATE SET token_data = %s, updated_at = %s
''',
(
team_id, user_id, service, json.dumps(token_data), datetime.now(),
json.dumps(token_data), datetime.now()
)
)
conn.commit()
cur.close()
conn.close()
all_users_preload = GetAllUsers()
if all_users_preload:
print("Users Prefection enabled")
# def GetAllUsers():
# return ""
# all_users_preload = ""
# owner_id_pref = ""