Spaces:
Running
Running
import os | |
import discord | |
import secrets | |
import threading | |
import gradio as gr | |
from discord.ext import commands | |
from discord.ui import Button, View | |
from urllib.parse import urlparse, parse_qs | |
# Discord bot ------------------------------------------------------------------------------------------------------ | |
intents = discord.Intents.all() | |
bot = commands.Bot(command_prefix="!", intents=intents) | |
GRADIO_APP_URL = "https://huggingface.co/spaces/lunarflu/gradio-oauth2" | |
DISCORD_TOKEN = os.environ.get("DISCORD_TOKEN", None) | |
BUTTON_CHANNEL_ID = "1106995001155649680" | |
BUTTON_MESSAGE_ID = "1266438263531634708" | |
# Dictionary to store user IDs and their corresponding unique strings | |
user_tokens = {} | |
async def on_ready(): | |
print(f'Logged in as {bot.user}') | |
if BUTTON_MESSAGE_ID: | |
channel = bot.get_channel(932563860597121054) | |
if channel: | |
try: | |
message = await channel.fetch_message(1269917762327674974) | |
if message: | |
button = DMButton(label="Verify Discord Account", style=discord.ButtonStyle.primary) | |
view = View(timeout=None) | |
view.add_item(button) | |
await message.edit(view=view) | |
print("message edited") | |
except discord.NotFound: | |
print(f"Message with ID {KNOWN_MESSAGE_ID} not found.") | |
except discord.HTTPException as e: | |
print(f"Failed to fetch message with ID {KNOWN_MESSAGE_ID}: {e}") | |
def generate_unique_string(length=6): | |
return secrets.token_hex(length // 2) | |
def run_bot(): | |
bot.run(DISCORD_TOKEN) | |
threading.Thread(target=run_bot).start() | |
# commands --------------------------------------------------------------------------------------------------------- | |
async def sendlink(ctx, user: discord.User): | |
if ctx.author.id == 811235357663297546: | |
unique_string = generate_unique_string() | |
user_tokens[user.id] = unique_string | |
unique_link = f"{GRADIO_APP_URL}?user_id={user.id}&token={unique_string}" | |
await user.send(f"Click the link to sign in with Hugging Face: {unique_link}") | |
class DMButton(Button): | |
def __init__(self, label, style): | |
super().__init__(label=label, style=style) | |
async def callback(self, interaction: discord.Interaction): | |
# await interaction.user.send(self.message) # this is for DMs, but users may have DMs disabled | |
user_id = interaction.user.id | |
if int(user_id) in user_tokens: | |
del user_tokens[int(user_id)] # always delete all past tokens when creating new link | |
unique_string = generate_unique_string() | |
user_tokens[user_id] = unique_string | |
unique_link = f"<{GRADIO_APP_URL}?user_id={user_id}&token={unique_string}>" | |
message = f"Login link generated! To complete the verification process:\n- 1 Visit this link,\n- 2 click the '🤗Sign in with Hugging Face' button\n\n{unique_link}" | |
await interaction.response.send_message(message, ephemeral=True) | |
async def send_button(ctx): | |
if ctx.author.id == 811235357663297546: | |
button = DMButton(label="Verify Discord Account", style=discord.ButtonStyle.primary) | |
view = View(timeout=None) | |
view.add_item(button) | |
await ctx.send("Click the button below to generate your verification link:",view=view) # | |
# Gradio ------------------------------------------------------------------------------------------------------------ | |
def hello(profile: gr.OAuthProfile | None, request: gr.Request) -> str: | |
url_str = str(request.url) | |
query_params = parse_qs(urlparse(url_str).query) | |
user_id = query_params.get('user_id', [None])[0] | |
token = query_params.get('token', [None])[0] | |
print(f"||| token:{token}||| user_id:{user_id}||| profile:{profile}||| user_tokens:{user_tokens}") | |
if user_id is None or token is None: | |
return "# ❌ Invalid link. Generate a new link [here](https://discord.com/channels/879548962464493619/900125909984624713) !" | |
if int(user_id) not in user_tokens or user_tokens[int(user_id)] != token: | |
return "# ❌ Invalid or expired link. Generate a new link [here](https://discord.com/channels/879548962464493619/900125909984624713) !" | |
if profile is None: | |
return f"# ❌ Not logged in with Hugging Face yet." | |
# Remove the token after successful verification | |
del user_tokens[int(user_id)] | |
# profile.username | |
return f"# ✅ Verification successful! We have linked your Hugging Face and Discord accounts. You can now earn exp for activity on Hugging Face as well as on Discord!" | |
with gr.Blocks() as demo: | |
with gr.Row(): | |
gr.Markdown("# Discord Verification Space") | |
with gr.Row(): | |
login_button = gr.LoginButton() | |
m1 = gr.Markdown() | |
demo.load(hello, inputs=None, outputs=m1) | |
def check_login_status(): | |
try: | |
return login_button.get_session().get("oauth_info", None) | |
except AttributeError: | |
return None | |
def check_login_wrapper(): | |
session = check_login_status() | |
if session is None: | |
return "Not logged in." | |
else: | |
return f"Logged in as {session.get('username', 'Unknown')}" | |
login_button.click(check_login_wrapper, inputs=None, outputs=m1) | |
demo.launch() | |
# nice version! :D |