import json import subprocess from concurrent.futures import ThreadPoolExecutor from realtime.connection import Socket import os import time from supabase import create_client from dotenv import load_dotenv import requests load_dotenv() SUPABASE_ID = os.getenv('supabaseID') SUPABASE_URL = os.getenv('supabaseUrl') SUPABASE_KEY = os.getenv('supabaseAnonKey') # Supabase client creation for each function def get_client(): return create_client(SUPABASE_URL, SUPABASE_KEY) def getUsername(userid): supabase = get_client() response = supabase.table("profiles").select( "*").eq("id", userid).execute() data = response.data username = data[0]['username'] return username def getAuthorNotifToken(userid): supabase = get_client() response = supabase.table("profiles").select( "*").eq("id", userid).execute() data = response.data token = data[0]['notifToken'] return token # def send_notification(title, body, token, id, post_id, notif_type): # print(token) # notification_data = { # 'to': token, # 'title': title, # 'body': body, # 'data': { # 'user_id': id, # 'id': post_id, # 'type': notif_type # } # } # notification_json = json.dumps(notification_data) # print(notification_json) # curl_command = [ # 'curl', # '-X', 'POST', # '-H', 'Content-Type: application/json', # '-d', notification_json, # 'https://exp.host/--/api/v2/push/send' # ] # try: # result = subprocess.run( # curl_command, capture_output=True, text=True, check=True) # print(f'Notification sent successfully: {result.stdout}') # except subprocess.CalledProcessError as e: # print(f'Failed to send notification: {e.stderr}') def send_notification(title, body, token, id, post_id, notif_type): print(token) notification_data = { 'to': token, 'title': title, 'body': body, 'data': { 'user_id': id, 'id': post_id, 'type': notif_type } } try: response = requests.post( 'https://exp.host/--/api/v2/push/send', json=notification_data) response.raise_for_status() print(f'Notification sent successfully: {response.text}') except requests.exceptions.RequestException as e: print(f'Failed to send notification: {e}') def handle_listlikes_update(event_payload): print('Received update in listlikes:') print(event_payload) record = event_payload['record'] id = record['list_id'] author_id = record['author_id'] user_id = record['user_id'] token = getAuthorNotifToken(author_id) username = getUsername(user_id).lower() title = 'Picturelock' body = f'@{username} liked your collection!' if token and user_id != author_id: send_notification(title, body, token, user_id, id, "list") def handle_listcomments_update(event_payload): print('Received update in listcomments:') print(event_payload) record = event_payload['record'] author_id = record['author_id'] user_id = record['user_id'] id = record['list_id'] token = getAuthorNotifToken(author_id) username = getUsername(user_id).lower() title = 'Picturelock' body = f'@{username} commented on your collection!' if token and user_id != author_id: send_notification(title, body, token, user_id, id, "list") def handle_likes_update(event_payload): print('Received update in likes:') print(event_payload) record = event_payload['record'] author_id = record['author_id'] user_id = record['user_id'] id = record['post_id'] token = getAuthorNotifToken(author_id) username = getUsername(user_id).lower() title = 'Picturelock' body = f'@{username} liked your post!' if token and user_id != author_id: send_notification(title, body, token, user_id, id, "post") def handle_comments_update(event_payload): print('Received update in comments:') print(event_payload) record = event_payload['record'] author_id = record['author_id'] user_id = record['user_id'] id = record['post_id'] token = getAuthorNotifToken(author_id) username = getUsername(user_id).lower() title = 'Picturelock' body = f'@{username} commented on your post!' if token and user_id != author_id: send_notification(title, body, token, user_id, id, "post") def handle_follow_update(event_payload): print('Received update in followers:') print(event_payload) record = event_payload['record'] author_id = record['id'] user_id = record['following'] id = record['following'] token = getAuthorNotifToken(author_id) username = getUsername(user_id).lower() title = 'Picturelock' body = f'@{username} followed you!' if token and user_id != author_id: send_notification(title, body, token, user_id, id, "follow") def getConversationUser(author_id, conv_id): supabase = create_client(SUPABASE_URL, SUPABASE_KEY) response = supabase.table("conversations").select("*").eq("id", conv_id).execute() data = response.data user1 = data[0]['user1'] user2 = data[0]['user2'] if user1 == author_id: return user2 else: return user1 def handle_message_update(event_payload): print('Received update in messages:') print(event_payload) record = event_payload['record'] author_id = record['user_id'] conv_id = record['conversation_id'] id = record['conversation_id'] user_id = getConversationUser(author_id, conv_id) token = getAuthorNotifToken(user_id) username = getUsername(author_id).lower() title = 'Picturelock' body = f'@{username} sent you a message!' if token and user_id != author_id: send_notification(title, body, token, user_id, id, "message") def handle_listreply_update(event_payload): print('Received update in listreplies:') print(event_payload) record = event_payload['record'] author_id = record['user_id'] user_id = record['to'] id = record['list_id'] token = getAuthorNotifToken(user_id) username = getUsername(author_id).lower() title = 'Picturelock' body = f'@{username} replied to you!' if token and user_id != author_id: send_notification(title, body, token, user_id, id, "list") def handle_reply_update(event_payload): print('Received update in replies:') print(event_payload) record = event_payload['record'] author_id = record['user_id'] user_id = record['to'] id = record['post_id'] token = getAuthorNotifToken(user_id) username = getUsername(author_id).lower() body = f'@{username} replied to you!' title = 'Picturelock' if token and user_id != author_id: send_notification(title, body, token, user_id, id, "post") def handle_commentlikes_update(event_payload): print('Received update in commentlikes:') print(event_payload) record = event_payload['record'] author_id = record['author_id'] user_id = record['user_id'] if record['post_id'] == None: id = record['list_id'] post_type = "list" else: id = record['post_id'] post_type = "post" token = getAuthorNotifToken(author_id) username = getUsername(user_id).lower() title = 'Picturelock' body = f'@{username} liked your comment!' if token and user_id != author_id: send_notification(title, body, token, user_id, id, post_type) def handle_replylikes_update(event_payload): print('Received update in replylikes:') print(event_payload) record = event_payload['record'] author_id = record['author_id'] user_id = record['user_id'] if record['post_id'] == None: id = record['list_id'] post_type = "list" else: id = record['post_id'] post_type = "post" token = getAuthorNotifToken(author_id) username = getUsername(user_id).lower() title = 'Picturelock' body = f'@{username} liked your reply!' if token and user_id != author_id: send_notification(title, body, token, user_id, id, post_type) def handle_groupreviewrequests_update(event_payload): print('Received update in posts:') print(event_payload) record = event_payload['record'] author_id = record['groupReviewLeader'] id = record['id'] user_id = record['author'] isGroupReview = record['isGroupReview'] token = getAuthorNotifToken(user_id) username = getUsername(author_id).lower() title = 'Picturelock' body = f'@{username} sent you an invite to a group review!' print(body) if token and user_id != author_id and isGroupReview: send_notification(title, body, token, author_id, id, "post") def setup_likes_subscription(SUPABASE_ID, SUPABASE_KEY): URL = f"wss://{SUPABASE_ID}.supabase.co/realtime/v1/websocket?apikey={SUPABASE_KEY}&vsn=1.0.0" with ThreadPoolExecutor(max_workers=10) as executor: while True: try: s = Socket(URL) s.connect() channel_listlikes = s.set_channel("realtime:public:listlikes") channel_listlikes.join().on( "INSERT", lambda payload: executor.submit(handle_listlikes_update, payload)) channel_listcomments = s.set_channel( "realtime:public:listcomments") channel_listcomments.join().on( "INSERT", lambda payload: executor.submit(handle_listcomments_update, payload)) channel_likes = s.set_channel("realtime:public:likes") channel_likes.join().on( "INSERT", lambda payload: executor.submit(handle_likes_update, payload)) channel_replylikes = s.set_channel( "realtime:public:replylikes") channel_replylikes.join().on( "INSERT", lambda payload: executor.submit(handle_replylikes_update, payload)) channel_commentlikes = s.set_channel( "realtime:public:commentlikes") channel_commentlikes.join().on( "INSERT", lambda payload: executor.submit(handle_commentlikes_update, payload)) channel_comments = s.set_channel("realtime:public:comments") channel_comments.join().on( "INSERT", lambda payload: executor.submit(handle_comments_update, payload)) channel_followers = s.set_channel("realtime:public:followers") channel_followers.join().on( "INSERT", lambda payload: executor.submit(handle_follow_update, payload)) channel_replies = s.set_channel("realtime:public:replies") channel_replies.join().on( "INSERT", lambda payload: executor.submit(handle_reply_update, payload)) channel_listreplies = s.set_channel( "realtime:public:listreplies") channel_listreplies.join().on( "INSERT", lambda payload: executor.submit(handle_listreply_update, payload)) channel_messages = s.set_channel("realtime:public:messages") channel_messages.join().on( "INSERT", lambda payload: executor.submit(handle_message_update, payload)) channel_posts = s.set_channel("realtime:public:posts") channel_posts.join().on("INSERT", lambda payload: executor.submit( handle_groupreviewrequests_update, payload)) s.listen() except Exception as e: print(f'Connection error: {e}') print('Reconnecting in 5 seconds...') time.sleep(5) if __name__ == '__main__': setup_likes_subscription(SUPABASE_ID, SUPABASE_KEY)