diff --git a/apps/docs/src/content/docs/guides/python-wrapper.mdx b/apps/docs/src/content/docs/guides/python-wrapper.mdx index 73d2cfa..3ead85f 100644 --- a/apps/docs/src/content/docs/guides/python-wrapper.mdx +++ b/apps/docs/src/content/docs/guides/python-wrapper.mdx @@ -1,6 +1,6 @@ --- -title: How to use HCTV's python wrapper! -description: How to use HCTV's unofficial Python wrapper. +title: Python wrapper +description: How to use hctv's unofficial Python wrapper. --- A Pycord-style Python wrapper for [hackclub.tv](https://hackclub.tv), made by [Christian](https://github.com/christianwell). Build chat bots with decorators and minimal boilerplate. @@ -15,13 +15,14 @@ pip install hctvwrapper ## Quick Start ```python +import os from hctvwrapper import Bot bot = Bot(command_prefix="!") @bot.event async def on_ready(session): - print(f"Logged in as {session.viewer}") + print(f"Logged in as {session.viewer.username}") @bot.event async def on_message(message): @@ -31,10 +32,10 @@ async def on_message(message): async def ping(ctx): await ctx.reply("pong!") -bot.run("hctvb_your_token_here", channel="bot-playground") +bot.run(os.environ['BOT_TOKEN'], channel="bot-playground") ``` -## Getting a Bot Token +### Getting a Bot Token 1. Go to [hackclub.tv](https://hackclub.tv) 2. Create a bot account and get your API key (starts with `hctvb_`) @@ -100,7 +101,7 @@ Register commands with `@bot.command()`. The bot automatically parses messages s ```python bot = Bot(command_prefix="!") -# Simple command — no arguments +# Simple command, no arguments @bot.command() async def ping(ctx): await ctx.reply("pong!") @@ -114,8 +115,17 @@ async def say_cmd(ctx, *, text): @bot.command() async def greet(ctx, name, greeting="hello"): await ctx.reply(f"{greeting}, {name}!") + +# Keyword-only (rest of message) +# Use *, text to capture everything after the command as a single string: +@bot.command() +async def echo(ctx, *, text): + await ctx.reply(text) +# !echo hello world foo → text = "hello world foo" ``` +> The bot automatically ignores its own messages to prevent loops. + ### Context The `ctx` object passed to commands gives you everything you need: @@ -185,6 +195,29 @@ await bot.unban_user("channel", user_id="user123") await bot.delete_message("channel", msg_id="msg-uuid") ``` +### Emojis + +Look up or search emojis from the Slack. Results come back via events. + +```python +# Look up emoji URLs +await bot.lookup_emojis(["yay", "aga"]) + +# Search emojis +await bot.search_emojis("yay") + +# Handle results +@bot.event +async def on_emoji_response(emojis): + # emojis = {"yay": "https://...", "aga": "https://..."} + print(emojis) + +@bot.event +async def on_emoji_search(results): + # results = ["yay", "yay-bounce", "yay-spin", ...] + print(results) +``` + ### Async Entry Point If you manage your own event loop: @@ -204,6 +237,77 @@ async def main(): asyncio.run(main()) ``` +## Examples + +### Echo Bot + +```python +from hctvwrapper import Bot +import os + +bot = Bot(command_prefix="!") + +@bot.event +async def on_ready(session): + print(f"✅ Logged in as {session.viewer}") + +@bot.command() +async def ping(ctx): + await ctx.reply("pong! 🏓") + +@bot.command(name="echo", aliases=["say"]) +async def echo_cmd(ctx, *, text): + await ctx.send(text) + +bot.run(os.environ["BOT_TOKEN"], channel="bot-playground") +``` + +### AI Bot + +```python +from hctvwrapper import Bot +import aiohttp, os + +bot = Bot(command_prefix="/") + +@bot.command(name="ai") +async def ai_cmd(ctx, *, prompt): + async with aiohttp.ClientSession() as http: + resp = await http.post( + "https://ai.hackclub.com/proxy/v1/chat/completions", + headers={"Authorization": f"Bearer {os.environ['AI_TOKEN']}"}, + json={ + "model": "google/gemini-3-flash-preview", + "messages": [{"role": "user", "content": prompt}], + }, + ) + data = await resp.json() + answer = data["choices"][0]["message"]["content"] + await ctx.reply(answer) + +bot.run(os.environ["BOT_TOKEN"], channel="bot-playground") +``` + +### Moderation Bot + +```python +from hctvwrapper import Bot +import os + +bot = Bot(command_prefix="!") + +@bot.command() +async def timeout(ctx, user_id, seconds="300"): + await bot.timeout_user(ctx.channel, user_id, duration=int(seconds)) + await ctx.send(f"⏰ Timed out for {seconds}s") + +@bot.event +async def on_moderation_error(error, channel): + print(f"⚠️ {error.code}: {error.message}") + +bot.run(os.environ["BOT_TOKEN"], channel="my-channel") +``` + ## Models Reference | Model | Fields | @@ -226,4 +330,4 @@ asyncio.run(main()) ## License -Copyright (c) 2026 Christian Well - [MIT License](https://github.com/christianwell/hctvwrapper/blob/main/LICENSE) \ No newline at end of file +Copyright (c) 2026 Christian Well - [MIT License](https://github.com/christianwell/hctvwrapper/blob/main/LICENSE) diff --git a/apps/docs/src/content/docs/guides/start-stream.mdx b/apps/docs/src/content/docs/guides/start-stream.mdx index f7aa0dc..9170766 100644 --- a/apps/docs/src/content/docs/guides/start-stream.mdx +++ b/apps/docs/src/content/docs/guides/start-stream.mdx @@ -29,7 +29,7 @@ _This guide demonstrates how to stream with hackclub.tv via OBS Studio. For othe ![Hack Club TV Stream Settings](../../../assets/hctv-settings.png) -- Go back to the website and click this Lock Icon icon to regenerate your stream key. Copy the new key and paste it into the `Stream Key` box in OBS. +- Go back to the website and click this Lock Icon icon to regenerate your stream key. Copy the new key and paste it into the `Stream Key` box in OBS. ![OBS Stream Settings with data filled in](../../../assets/obs-custom.png) (_Your OBS settings should now look like this_)