File size: 5,411 Bytes
ddbc9ac
 
128003a
0593f86
 
afc2013
0593f86
 
 
 
 
 
ddbc9ac
 
a04ed72
ddbc9ac
bf0c0d3
 
ddbc9ac
128003a
 
 
ddbc9ac
 
 
 
bf0c0d3
d8fcf36
bf0c0d3
 
d8fcf36
bf0c0d3
c76be5c
c6f41f6
c76be5c
bf0c0d3
3a0f3d4
bf0c0d3
 
 
 
 
 
128003a
 
 
0593f86
e5bca64
 
 
 
0593f86
ddbc9ac
 
 
128003a
 
 
ddbc9ac
91bbd67
7daad99
0593f86
9ab3747
0593f86
 
 
3115613
9ab3747
 
 
612298b
9ab3747
f7a2ff4
3ada2fa
612298b
 
0593f86
 
 
 
9ab3747
c6f41f6
0593f86
612298b
0593f86
5166981
128003a
7daad99
5166981
10ee58a
ddbc9ac
128003a
 
57726d8
53acbe3
7daad99
57726d8
02e376e
0d88cd0
57726d8
ddbc9ac
7daad99
 
3abdf8c
4a452b5
 
 
7d91736
 
3abdf8c
02e376e
7daad99
 
 
 
 
3abdf8c
7daad99
 
3abdf8c
7daad99
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4a452b5
0593f86
 
07be87a
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
137
138
139
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 = {}

@bot.event
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 ---------------------------------------------------------------------------------------------------------
@bot.command()
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)


@bot.command(name='sendbutton')
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