aboutsummaryrefslogtreecommitdiff
path: root/lib/discordSync.py
blob: fe5c37bf9e8e6dc43ae010693b7037ed972ea147 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import aiohttp
import asyncio
from config import *
from lib.PacketManager.packets.FSNETCMD_TEXTMESSAGE import FSNETCMD_TEXTMESSAGE as txtMsgr
from logging import debug, warning
import re

BOT_TOKEN = DISCORD_TOKEN

# API Base URL
BASE_URL = 'https://discord.com/api/v10'

# Headers for making API requests
HEADERS = {
    'Authorization': f'Bot {BOT_TOKEN}',
    'Content-Type': 'application/json'
}

# Function to send a message to a specific Discord channel
async def discord_send_message(channel_id:int, message:str, santize_message:bool = True):
    """
    Santizes the message of @everyone and @here pings
    and then sends the message to given channel id
    """
    if santize_message : message = re.sub(r'@(?:everyone|here)', '', message)
    url = f'{BASE_URL}/channels/{channel_id}/messages'
    payload = {
        'content': message
    }

    async with aiohttp.ClientSession() as session:
        async with session.post(url, json=payload, headers=HEADERS) as response:
            if response.status in [200, 201]:
                pass
            else:
                warning(f'Failed to send message. Status Code: {response.status} | {await response.text()}')

# Function to fetch messages from a specific Discord channel

async def discord_fetch_messages(channel_id, last_message_id=None):
    url = f'{BASE_URL}/channels/{channel_id}/messages'
    params = {'limit': 1}
    if last_message_id:
        params['after'] = last_message_id

    try:
        async with aiohttp.ClientSession() as session:
            async with session.get(url, headers=HEADERS, params=params) as response:
                if response.status == 200:
                    return await response.json()
                else:
                    warning(f"Failed to fetch messages. Status Code: {response.status} | {await response.text()}")
                    return []
    except (aiohttp.ClientError, asyncio.TimeoutError) as e:
        warning(f"Network error while fetching messages: {e}")
        return []  # Return empty list to avoid crashing


# Callback function when a new message is detected
def on_new_message(message):
    author = message['author']
    # Skip messages from bots (including this bot itself)
    if author.get('bot'):  # Safely get the 'bot' key (returns None if key does not exist)
        return

    username = author['username']
    content = message['content']
    debug(f'New Discord message from {username}: {content}')

# Asynchronous function to monitor a Discord channel for new messages
async def monitor_channel(channel_id, playerList:list):
    last_message_id = None
    while True:
        # Fetch new messages
        messages = await discord_fetch_messages(channel_id, last_message_id)
        if messages:
            # Process only the latest message
            message = messages[0]
            if messages:
                message = messages[0]
                if last_message_id is None or message['id'] > last_message_id:  # Ensure only newer messages are processed
                    last_message_id = message['id']
                    if not message['author'].get('bot'): # Skip messages from bot
                        encoded_msg = txtMsgr.encode(f"[Discord] {message['author']['username']}: {message['content']}", True)
                        for player in playerList:
                            if player.streamWriterObject.is_closing():
                                if not player.is_a_bot:
                                    asyncio.create_task(discord_send_message(channel_id, f"{player.username} has left the server!"))
                                playerList.remove(player)  # Remove disconnected players
                                continue
                            player.streamWriterObject.write(encoded_msg)
                            await player.streamWriterObject.drain()
                        on_new_message(message)
        await asyncio.sleep(1)  # Poll every second (adjust as needed)