From d9499138aeaf32faee65640e624719df83f465eb Mon Sep 17 00:00:00 2001 From: Arslaan Pathan Date: Thu, 9 Jul 2026 12:49:22 +1200 Subject: Make OAuth work and send a welcome message! --- src/auth.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/db.py | 32 ++++++++++++++++++++++++++++++++ src/main.py | 21 +++++++++++++++++++-- 3 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 src/auth.py create mode 100644 src/db.py (limited to 'src') diff --git a/src/auth.py b/src/auth.py new file mode 100644 index 0000000..3f8ff02 --- /dev/null +++ b/src/auth.py @@ -0,0 +1,44 @@ +from fastapi import FastAPI, Request, Query +from fastapi.responses import RedirectResponse +import httpx +import os +from .db import add_user +from dotenv import load_dotenv + +load_dotenv() + +app = FastAPI() + +CLIENT_ID = os.environ.get("SLAKC_CLIENT_ID") +CLIENT_SECRET = os.environ.get("SLAKC_CLIENT_SECRET") +REDIRECT_URI = os.environ.get("SLAKC_REDIRECT_URI") + +@app.get("/slack/oauth/install") +async def install(): + slack_auth_url = ( + "https://slack.com/oauth/v2/authorize" + f"?client_id={CLIENT_ID}" + f"&redirect_uri={REDIRECT_URI}" + "&scope=" + "&user_scope=channels:write,channels:history,channels:read,chat:write,im:history,users:read" + ) + return RedirectResponse(slack_auth_url) + +@app.get("/slack/oauth/redirect") +async def oauth_redirect(request: Request, code: str = Query(...), state: str = Query(None)): + async with httpx.AsyncClient() as client: + response = await client.post("https://slack.com/api/oauth.v2.access", data={"client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, "code": code, "redirect_uri": REDIRECT_URI}) + data = response.json() + + if not data.get("ok"): + return {"error": data.get("error", "Unknown error")} + + user_id = data.get("authed_user", {}).get("id") + access_token = data.get("authed_user", {}).get("access_token") + + if not user_id or not access_token: + return {"error": "Could not get user info from OAuth response"} + + await add_user(user_id, access_token) + + return {"message": "Successfully joined Botnet!", "user_id": user_id} diff --git a/src/db.py b/src/db.py new file mode 100644 index 0000000..6dd5cad --- /dev/null +++ b/src/db.py @@ -0,0 +1,32 @@ +from slack_sdk.web.async_client import AsyncWebClient +import aiosqlite + +DB_PATH = "botnet.db" + +async def init_db(): + async with aiosqlite.connect(DB_PATH) as db: + await db.execute(""" + CREATE TABLE IF NOT EXISTS Users ( + slack_id TEXT PRIMARY KEY, + oauth_token TEXT NOT NULL, + joined_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) + """) + await db.commit() + +async def add_user(slack_id: str, oauth_token: str): + async with aiosqlite.connect(DB_PATH) as db: + await db.execute( + "INSERT OR REPLACE INTO Users (slack_id, oauth_token) VALUES (?, ?)", + (slack_id, oauth_token) + ) + await db.commit() + client = AsyncWebClient(token=oauth_token) + try: + await client.chat_postMessage( + channel="C0BGMV1CAQG", + text="I've joined the botnet!", + as_user=True + ) + except Exception as e: + print(f"Failed to send welcome message: {e}") diff --git a/src/main.py b/src/main.py index 6f5e2d6..8b0e692 100644 --- a/src/main.py +++ b/src/main.py @@ -2,7 +2,11 @@ import os from slack_bolt.app.async_app import AsyncApp from slack_bolt.adapter.socket_mode.async_handler import AsyncSocketModeHandler from dotenv import load_dotenv +from .db import init_db +from .auth import app as fastapi_app +import threading import asyncio +import uvicorn load_dotenv() @@ -19,11 +23,16 @@ async def handle_messages(message, say): if message.get("user") == selfbot_user_id: return + + if message.get("user") != "U0AKCBZHHMH": + await say("Botnet is temporarily disabled for users other than <@U0AKCBZHHMH> for debugging and the safety of all OAuth-authorized users. Please DM <@U0AKCBZHHMH> if this is not resolved within a few days.") + return text = message.get("text", "").lower().strip() if not text.startswith("botnet"): - return + # yay more scuffed arbitrary stuff + text = "botnet help" parts = text.split(" ") if len(parts) == 1: @@ -41,7 +50,7 @@ async def handle_messages(message, say): elif command == "approve": await say("Not implemented yet") else: - await say("Unknown command: {command}") + await say(f"Unknown command: {command}") @app.event("message") async def shut_up_slack_bolt(): @@ -49,6 +58,14 @@ async def shut_up_slack_bolt(): pass async def main(): + await init_db() + + def run_uvicorn(): + uvicorn.run(fastapi_app, host="0.0.0.0", port=8000) + + thread = threading.Thread(target=run_uvicorn, daemon=True) + thread.start() + handler = AsyncSocketModeHandler(app, app_token=app_token) await handler.start_async() -- cgit v1.2.3