poolguy


Namepoolguy JSON
Version 0.1.3 PyPI version JSON
download
home_pagehttps://github.com/s4w3d0ff/pool-guy
SummaryA Twitch bot framework with event subscription and alert handling capabilities
upload_time2025-02-01 21:34:56
maintainerNone
docs_urlNone
authors4w3d0ff
requires_python>=3.10
licenseGNU General Public License v3 (GPLv3)
keywords twitch bot eventsub websocket async alerts streaming poolguy
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Pool Guy 🏊‍♂️

A lightweight Twitch bot framework with event subscription and alert handling capabilities.

[![Python Version](https://img.shields.io/badge/python-3.10%2B-blue)](https://www.python.org/downloads/)
[![License](https://img.shields.io/badge/license-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)

## 🚀 Features

- Event subscription handling
- Custom alert system
- Twitch chat command integration
- WebSocket-based real-time updates
- Support for multiple storage backends (MongoDB, SQLite)
- Customizable command prefix system
- Rate limiting for commands

## 🛠️ Quick Setup


### Install directly from git:
```bash
pip install git+https://github.com/s4w3d0ff/pool-guy.git
```

### Create a configuration file (e.g., config.json):
```json
{
  "http_config": {
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "redirect_uri": "http://localhost:5000/callback",
    "scopes": [
      "user:read:chat",
      "user:write:chat"
    ]
  },
  "ws_config": {
      "channels": {"channel.chat.message": [null]}, 
      "queue_skip": ["channel.chat.message"], 
      "storage_type": "json"
  },
  "max_retries": 30,
  "retry_delay": 10,
  "login_browser": {
    "chrome": "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe"
  }
}
```

### Simple Command Bot:
```python
from poolguy.utils import asyncio
from poolguy.utils import loadJSON, ctxt
from poolguy import CommandBot, Alert, ColorLogger, cmd_rate_limit

logger = ColorLogger(__name__)

class ChannelChatMessageAlert(Alert):
    """channel.chat.message"""
    async def process(self):
        logger.debug(f'{self.data}')
        text = self.data["message"]["text"]
        user = {
            "user_id": self.data["chatter_user_id"], 
            "username": self.data["chatter_user_name"]
            }
        channel = {
            "broadcaster_id": self.data["broadcaster_user_id"],
            "broadcaster_user_name": self.data["broadcaster_user_name"]
            }
        logger.info(f'[Chat] {user["username"]}: {text}', 'purple')
        if str(user["user_id"]) == str(self.bot.http.user_id):
            logger.debug(f'Own message ignored')
            return
        if self.data["source_broadcaster_user_id"]:
            logger.debug(f'Shared chat message ignored')
            return
        await self.bot.command_check(text, user, channel)

class ExampleBot(CommandBot):
    def __init__(self, *args, **kwargs):
        """
        # Fetch sensitive data from environment variables
        import os
        client_id = os.getenv("CLIENT_ID")
        client_secret = os.getenv("CLIENT_SECRET")
        if not client_id or not client_secret:
            raise ValueError("Environment variables CLIENT_ID and CLIENT_SECRET are required")
        kwargs['http_config']['client_id'] = client_id
        kwargs['http_config']['client_secret'] = client_secret
        """
        super().__init__(*args, **kwargs)

    async def send_chat(self, message, channel_id=None):
        r = await self.http.sendChatMessage(message, channel_id)
        if not r[0]['is_sent']:
            logger.error(f"Message not sent! Reason: {r[0]['drop_reason']}")

    @cmd_rate_limit(calls=1, period=10)
    async def cmd_hi(self, user, channel, args):
        await self.send_chat(f"Hi, @{user['username']}", channel["broadcaster_id"])

    async def my_loop(self):
        logger.warning(f'my_loop started')
        while self.ws.connected:
            await asyncio.sleep(10)
        logger.warning(f'my_loop stopped')

    async def after_login(self):
        await self.add_task(self.my_loop)


if __name__ == '__main__':
    import logging
    fmat = ctxt('%(asctime)s', 'yellow', style='d') + '-%(levelname)s-' + ctxt('[%(name)s]', 'purple', style='d') + ctxt(' %(message)s', 'green', style='d')
    logging.basicConfig(
        format=fmat,
        datefmt="%I:%M:%S%p",
        level=logging.INFO
    )
    cfg = loadJSON('config.json')
    bot = ExampleBot(**cfg, alert_objs={'channel.chat.message': ChannelChatMessageAlert})
    asyncio.run(bot.start())
    
```
More fleshed out example: https://github.com/s4w3d0ff/deezbot

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/s4w3d0ff/pool-guy",
    "name": "poolguy",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "twitch, bot, eventsub, websocket, async, alerts, streaming, poolguy",
    "author": "s4w3d0ff",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/c7/7a/017cb551c8d7b003f30ba7eb5b44f6456d64852e9af6aaf738a530a16854/poolguy-0.1.3.tar.gz",
    "platform": "any",
    "description": "# Pool Guy \ud83c\udfca\u200d\u2642\ufe0f\n\nA lightweight Twitch bot framework with event subscription and alert handling capabilities.\n\n[![Python Version](https://img.shields.io/badge/python-3.10%2B-blue)](https://www.python.org/downloads/)\n[![License](https://img.shields.io/badge/license-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)\n\n## \ud83d\ude80 Features\n\n- Event subscription handling\n- Custom alert system\n- Twitch chat command integration\n- WebSocket-based real-time updates\n- Support for multiple storage backends (MongoDB, SQLite)\n- Customizable command prefix system\n- Rate limiting for commands\n\n## \ud83d\udee0\ufe0f Quick Setup\n\n\n### Install directly from git:\n```bash\npip install git+https://github.com/s4w3d0ff/pool-guy.git\n```\n\n### Create a configuration file (e.g., config.json):\n```json\n{\n  \"http_config\": {\n    \"client_id\": \"YOUR_CLIENT_ID\",\n    \"client_secret\": \"YOUR_CLIENT_SECRET\",\n    \"redirect_uri\": \"http://localhost:5000/callback\",\n    \"scopes\": [\n      \"user:read:chat\",\n      \"user:write:chat\"\n    ]\n  },\n  \"ws_config\": {\n      \"channels\": {\"channel.chat.message\": [null]}, \n      \"queue_skip\": [\"channel.chat.message\"], \n      \"storage_type\": \"json\"\n  },\n  \"max_retries\": 30,\n  \"retry_delay\": 10,\n  \"login_browser\": {\n    \"chrome\": \"C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\"\n  }\n}\n```\n\n### Simple Command Bot:\n```python\nfrom poolguy.utils import asyncio\nfrom poolguy.utils import loadJSON, ctxt\nfrom poolguy import CommandBot, Alert, ColorLogger, cmd_rate_limit\n\nlogger = ColorLogger(__name__)\n\nclass ChannelChatMessageAlert(Alert):\n    \"\"\"channel.chat.message\"\"\"\n    async def process(self):\n        logger.debug(f'{self.data}')\n        text = self.data[\"message\"][\"text\"]\n        user = {\n            \"user_id\": self.data[\"chatter_user_id\"], \n            \"username\": self.data[\"chatter_user_name\"]\n            }\n        channel = {\n            \"broadcaster_id\": self.data[\"broadcaster_user_id\"],\n            \"broadcaster_user_name\": self.data[\"broadcaster_user_name\"]\n            }\n        logger.info(f'[Chat] {user[\"username\"]}: {text}', 'purple')\n        if str(user[\"user_id\"]) == str(self.bot.http.user_id):\n            logger.debug(f'Own message ignored')\n            return\n        if self.data[\"source_broadcaster_user_id\"]:\n            logger.debug(f'Shared chat message ignored')\n            return\n        await self.bot.command_check(text, user, channel)\n\nclass ExampleBot(CommandBot):\n    def __init__(self, *args, **kwargs):\n        \"\"\"\n        # Fetch sensitive data from environment variables\n        import os\n        client_id = os.getenv(\"CLIENT_ID\")\n        client_secret = os.getenv(\"CLIENT_SECRET\")\n        if not client_id or not client_secret:\n            raise ValueError(\"Environment variables CLIENT_ID and CLIENT_SECRET are required\")\n        kwargs['http_config']['client_id'] = client_id\n        kwargs['http_config']['client_secret'] = client_secret\n        \"\"\"\n        super().__init__(*args, **kwargs)\n\n    async def send_chat(self, message, channel_id=None):\n        r = await self.http.sendChatMessage(message, channel_id)\n        if not r[0]['is_sent']:\n            logger.error(f\"Message not sent! Reason: {r[0]['drop_reason']}\")\n\n    @cmd_rate_limit(calls=1, period=10)\n    async def cmd_hi(self, user, channel, args):\n        await self.send_chat(f\"Hi, @{user['username']}\", channel[\"broadcaster_id\"])\n\n    async def my_loop(self):\n        logger.warning(f'my_loop started')\n        while self.ws.connected:\n            await asyncio.sleep(10)\n        logger.warning(f'my_loop stopped')\n\n    async def after_login(self):\n        await self.add_task(self.my_loop)\n\n\nif __name__ == '__main__':\n    import logging\n    fmat = ctxt('%(asctime)s', 'yellow', style='d') + '-%(levelname)s-' + ctxt('[%(name)s]', 'purple', style='d') + ctxt(' %(message)s', 'green', style='d')\n    logging.basicConfig(\n        format=fmat,\n        datefmt=\"%I:%M:%S%p\",\n        level=logging.INFO\n    )\n    cfg = loadJSON('config.json')\n    bot = ExampleBot(**cfg, alert_objs={'channel.chat.message': ChannelChatMessageAlert})\n    asyncio.run(bot.start())\n    \n```\nMore fleshed out example: https://github.com/s4w3d0ff/deezbot\n",
    "bugtrack_url": null,
    "license": "GNU General Public License v3 (GPLv3)",
    "summary": "A Twitch bot framework with event subscription and alert handling capabilities",
    "version": "0.1.3",
    "project_urls": {
        "Homepage": "https://github.com/s4w3d0ff/pool-guy"
    },
    "split_keywords": [
        "twitch",
        " bot",
        " eventsub",
        " websocket",
        " async",
        " alerts",
        " streaming",
        " poolguy"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "65853d7f9bdda90caa7dfc360c7c91aef926ee68971db449d859307f7ca617e0",
                "md5": "0c4945b8d4cdf046275a4a2dbdcf38b4",
                "sha256": "cc8ffde37a126d79fb58be96c394f3e2d47e72e049158c5dac1a432bda10c3a1"
            },
            "downloads": -1,
            "filename": "poolguy-0.1.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "0c4945b8d4cdf046275a4a2dbdcf38b4",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 37249,
            "upload_time": "2025-02-01T21:34:55",
            "upload_time_iso_8601": "2025-02-01T21:34:55.058933Z",
            "url": "https://files.pythonhosted.org/packages/65/85/3d7f9bdda90caa7dfc360c7c91aef926ee68971db449d859307f7ca617e0/poolguy-0.1.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "c77a017cb551c8d7b003f30ba7eb5b44f6456d64852e9af6aaf738a530a16854",
                "md5": "321ca809a6198c26db1b8f4222df92b7",
                "sha256": "ce39b631c63c51c0d602fe015497265c44e0a41733e61c3f8ad8851825db06d2"
            },
            "downloads": -1,
            "filename": "poolguy-0.1.3.tar.gz",
            "has_sig": false,
            "md5_digest": "321ca809a6198c26db1b8f4222df92b7",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 36568,
            "upload_time": "2025-02-01T21:34:56",
            "upload_time_iso_8601": "2025-02-01T21:34:56.904362Z",
            "url": "https://files.pythonhosted.org/packages/c7/7a/017cb551c8d7b003f30ba7eb5b44f6456d64852e9af6aaf738a530a16854/poolguy-0.1.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-02-01 21:34:56",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "s4w3d0ff",
    "github_project": "pool-guy",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "poolguy"
}
        
Elapsed time: 1.02000s