├── README.md ├── bot.py ├── config.py ├── db.db ├── module.py ├── role.py ├── web.py └── 웹실행.bat /README.md: -------------------------------------------------------------------------------- 1 | A simple Oauth verification bot designed to restore all of your members. 2 | If you have any problems, open a issue here or contact 3 | gamb1t#0001 4 | -------------------------------------------------------------------------------- /bot.py: -------------------------------------------------------------------------------- 1 | import discord, sqlite3, config 2 | from module import opendb, refresh_token, add_user 3 | 4 | client = discord.Client() 5 | 6 | @client.event 7 | async def on_message(msg): 8 | if msg.guild == None: 9 | return 10 | 11 | if msg.author.id == msg.guild.owner_id: 12 | if msg.content == f"!복구 {config.recover_key}": 13 | await msg.channel.send("복구 중입니다...") 14 | con,cur = opendb() 15 | cur.execute("SELECT * FROM users;") 16 | users = cur.fetchall() 17 | 18 | for user in list(set(users)): 19 | try: 20 | new_token = await refresh_token(user[1]) 21 | if new_token != False: 22 | cur.execute("UPDATE users SET refresh_token = ? WHERE id == ?;", (new_token["refresh_token"], user[0])) 23 | con.commit() 24 | await add_user(new_token["access_token"], msg.guild.id, user[0]) 25 | except: 26 | pass 27 | 28 | await msg.channel.send("복구 성공") 29 | 30 | if msg.content == "!안내": 31 | try: 32 | await msg.delete() 33 | except: 34 | pass 35 | await msg.channel.send(embed=discord.Embed(color=0x32cd32, title="인증 시스템", description=f"[인증하]({config.oauth2_url})를 클릭하시면\n인증 역할을 바로 받으실 수 있습니다.")) 36 | 37 | 38 | 39 | client.run(config.token) 40 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | token = "봇 토큰" 2 | oauth2_url = "Oauth2 인증 URL" 3 | recover_key = "복구 시 사용할 복구 키" 4 | guildid = "서버아이디" 5 | roleid = "인증시 부여할 역할 아이디" 6 | 7 | API_ENDPOINT = "https://discord.com/api/v9" # 건들지 말것 8 | CLIENT_ID = "Oauth2 클라이언트 아이디" 9 | CLIENT_SECRET = "Oauth2 클라이언트 시크릿" 10 | BASE_URL = "http://도메인" 11 | REDIRECT_URI = "http://도메인/callback" 12 | -------------------------------------------------------------------------------- /db.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gamb2t/discord-restore-bot/22ac88b54f74467f37f56ce127040ffc268aa981/db.db -------------------------------------------------------------------------------- /module.py: -------------------------------------------------------------------------------- 1 | import config, requests, asyncio, sqlite3 2 | 3 | async def exchange_code(code): 4 | data = { 5 | 'client_id': config.CLIENT_ID, 6 | 'client_secret': config.CLIENT_SECRET, 7 | 'grant_type': 'authorization_code', 8 | 'code': code, 9 | 'redirect_uri': config.REDIRECT_URI 10 | } 11 | headers = { 12 | 'Content-Type': 'application/x-www-form-urlencoded' 13 | } 14 | while True: 15 | r = requests.post('%s/oauth2/token' % config.API_ENDPOINT, data=data, headers=headers) 16 | if (r.status_code != 429): 17 | break 18 | 19 | limitinfo = r.json() 20 | await asyncio.sleep(limitinfo["retry_after"] + 2) 21 | return False if "error" in r.json() else r.json() 22 | 23 | async def refresh_token(refresh_token): 24 | data = { 25 | 'client_id': config.CLIENT_ID, 26 | 'client_secret': config.CLIENT_SECRET, 27 | 'grant_type': 'refresh_token', 28 | 'refresh_token': refresh_token 29 | } 30 | headers = { 31 | 'Content-Type': 'application/x-www-form-urlencoded' 32 | } 33 | while True: 34 | r = requests.post('%s/oauth2/token' % config.API_ENDPOINT, data=data, headers=headers) 35 | if (r.status_code != 429): 36 | break 37 | 38 | limitinfo = r.json() 39 | await asyncio.sleep(limitinfo["retry_after"] + 2) 40 | 41 | print(r.json()) 42 | return False if "error" in r.json() else r.json() 43 | 44 | async def add_user(access_token, guild_id, user_id): 45 | while True: 46 | jsonData = {"access_token" : access_token} 47 | header = {"Authorization" : "Bot " + config.token} 48 | r = requests.put(f"{config.API_ENDPOINT}/guilds/{guild_id}/members/{user_id}", json=jsonData, headers=header) 49 | if (r.status_code != 429): 50 | break 51 | 52 | limitinfo = r.json() 53 | await asyncio.sleep(limitinfo["retry_after"] + 2) 54 | 55 | if (r.status_code == 201 or r.status_code == 204): 56 | return True 57 | else: 58 | print(r.json()) 59 | return False 60 | 61 | def opendb(): 62 | con = sqlite3.connect("db.db") 63 | cur = con.cursor() 64 | return con,cur 65 | 66 | async def get_user_profile(token): 67 | header = {"Authorization" : "Bearer " + token} 68 | res = requests.get("https://discordapp.com/api/v8/users/@me", headers=header) 69 | print(res.json()) 70 | if (res.status_code != 200): 71 | return False 72 | else: 73 | return res.json() -------------------------------------------------------------------------------- /role.py: -------------------------------------------------------------------------------- 1 | import requests, config 2 | 3 | URL = "https://discordapp.com/api/v9" 4 | 5 | def add_role(guildid,userid,roleid): 6 | url = f"{URL}/guilds/{guildid}/members/{userid}/roles/{roleid}" 7 | 8 | botToken = config.token 9 | 10 | headers = { 11 | "Authorization" : f"Bot {botToken}", 12 | 'Content-Type': 'application/json' 13 | } 14 | 15 | response = requests.put(url=url, headers=headers) 16 | print(response.json) 17 | -------------------------------------------------------------------------------- /web.py: -------------------------------------------------------------------------------- 1 | import asyncio, role, config 2 | from fastapi import FastAPI 3 | from fastapi.responses import RedirectResponse 4 | from requests.api import get 5 | from module import exchange_code, opendb, get_user_profile 6 | 7 | app = FastAPI() 8 | 9 | @app.get("/callback") 10 | async def callback(code : str): 11 | exchange_res = await exchange_code(code) 12 | if exchange_code == False: 13 | return "권한이 부여되지 않았습니다" 14 | profile = await get_user_profile(exchange_res["access_token"]) 15 | if profile == False: 16 | return "권한이 부여되지 않았습니다" 17 | con,cur = opendb() 18 | cur.execute("INSERT INTO users VALUES (?, ?);", (profile["id"], exchange_res["refresh_token"])) 19 | con.commit() 20 | con.close() 21 | role.add_role(config.guildid,profile["id"], config.roleid) 22 | return RedirectResponse("https://discord.com/oauth2/authorized") 23 | -------------------------------------------------------------------------------- /웹실행.bat: -------------------------------------------------------------------------------- 1 | uvicorn web:app --host 0.0.0.0 --port 80 --workers 10 --------------------------------------------------------------------------------