File size: 4,779 Bytes
434f798
30462e3
c87648d
8dd1108
1f188d9
f6602f2
1f188d9
 
807606e
960e451
807606e
 
 
 
c6565e2
960e451
773ec73
807606e
 
 
d522acf
960e451
cbfe4d5
807606e
b80bf81
960e451
 
cbfe4d5
960e451
807606e
 
 
960e451
 
 
807606e
960e451
 
 
 
cbfe4d5
960e451
 
 
807606e
960e451
 
 
 
 
 
 
807606e
a56363d
ae4f533
960e451
 
 
ae4f533
 
5e34c0f
 
 
 
807606e
5e34c0f
 
807606e
2cf1870
5e34c0f
 
807606e
 
5e34c0f
807606e
2cf1870
5e34c0f
 
807606e
2cf1870
5e34c0f
d522acf
ae4f533
960e451
807606e
960e451
 
ae4f533
960e451
807606e
960e451
 
c87648d
807606e
 
139364e
960e451
 
139364e
807606e
cbfe4d5
139364e
960e451
 
807606e
960e451
 
807606e
 
 
 
 
 
 
 
139364e
 
 
960e451
 
139364e
960e451
 
807606e
cbfe4d5
 
 
 
 
960e451
 
 
 
 
807606e
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import os
import io
import sys
import asyncio
import discord
import aiohttp
import pandas as pd
import gradio as gr
import logging
from discord.ext import commands

# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Environment variable for Discord token
DISCORD_TOKEN = os.environ.get("DISCORD_TOKEN", None)
if not DISCORD_TOKEN:
    logger.error("DISCORD_TOKEN not set. Exiting.")
    sys.exit(1)

# Create Discord bot with all intents
intents = discord.Intents.all()
bot = commands.Bot(command_prefix="!", intents=intents)

async def process_row(row, guild, role):
    """
    Process a single CSV row: if the Discord member associated with the row hasn't received the role, add it.
    """
    hf_user_name = row["hf_user_name"]
    if pd.notna(hf_user_name) and hf_user_name.lower() != "n/a":
        discord_id = row["discord_user_id"].strip("L")
        try:
            member = guild.get_member(int(discord_id))
        except Exception as e:
            logger.error(f"Error converting Discord ID {discord_id}: {e}")
            return

        if not member:
            return

        if role not in member.roles:
            try:
                await member.add_roles(role)
                logger.info(f"Role added to member: {member}")
                lunar = bot.get_user(811235357663297546)
                if lunar:
                    await lunar.send(f"Verified role given to {member}!")
                await member.send(
                    f"Verification successful! [{member} <---> {row['discord_user_name']}]"
                )
            except Exception as e:
                logger.error(f"Error processing member {member}: {e}")

async def give_verified_roles():
    """
    Periodically fetch CSV data from Google Sheets and verify roles for members.
    """
    while True:
        try:
            async with aiohttp.ClientSession() as session:
                try:
                    async with session.get(
                        "https://docs.google.com/spreadsheets/d/1C8aLqgCqLYcMiIFf-P_Aosaa03C_WLIB_UyqvjSdWg8/export?format=csv&gid=0",
                        timeout=10,
                    ) as response:
                        if response.status != 200:
                            logger.error(f"Failed to fetch CSV: HTTP {response.status}")
                            await asyncio.sleep(30)
                            continue
                        csv_data = await response.text()
                        # Offload CSV parsing to avoid blocking the event loop.
                        global_df = await asyncio.to_thread(pd.read_csv, io.StringIO(csv_data))
                except asyncio.TimeoutError:
                    logger.error("CSV fetch timed out.")
                    await asyncio.sleep(30)
                    continue
                except Exception as e:
                    logger.error(f"Error fetching CSV: {e}")
                    await asyncio.sleep(30)
                    continue

            guild = bot.get_guild(879548962464493619)
            if not guild:
                logger.error("Guild not found.")
                await asyncio.sleep(30)
                continue
            role = guild.get_role(900063512829755413)
            if not role:
                logger.error("Role not found.")
                await asyncio.sleep(30)
                continue

            # Ensure all guild members are cached.
            await guild.chunk()

            tasks = [process_row(row, guild, role) for _, row in global_df.iterrows()]
            await asyncio.gather(*tasks)
        except Exception as e:
            logger.error(f"Error in give_verified_roles loop: {e}")
        await asyncio.sleep(30)  # Adjust the sleep interval as needed

@bot.event
async def on_ready():
    logger.info(f"We have logged in as {bot.user}")
    # Start the background role verification loop
    bot.loop.create_task(give_verified_roles())
    # Optionally, you can add a heartbeat task to log regular status messages.
    bot.loop.create_task(heartbeat())

async def heartbeat():
    """Simple heartbeat task to indicate the bot is still responsive."""
    while True:
        logger.info("Heartbeat: Bot is active.")
        await asyncio.sleep(60)

def greet(name):
    return "Hello " + name + "!"

# Create the Gradio interface
demo = gr.Interface(fn=greet, inputs="text", outputs="text")

async def main():
    # Launch Gradio in a separate thread to avoid blocking
    gradio_thread = asyncio.to_thread(demo.launch, share=False)
    await asyncio.gather(
        bot.start(DISCORD_TOKEN),
        gradio_thread
    )

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        logger.info("Shutting down...")