{"id":31692192,"url":"https://github.com/phenibut645/balkon","last_synced_at":"2026-04-18T11:03:43.528Z","repository":{"id":314706960,"uuid":"1056476697","full_name":"phenibut645/balkon","owner":"phenibut645","description":"Discord bot for interacting with streamers and cross-server economies [ still in development ]","archived":false,"fork":false,"pushed_at":"2025-09-23T23:02:45.000Z","size":68,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-24T01:07:35.653Z","etag":null,"topics":["1000-7","discord-js","mysql2","nodejs","typescript","vitest-ts","zxc"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phenibut645.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-14T07:07:58.000Z","updated_at":"2025-09-23T23:05:16.000Z","dependencies_parsed_at":"2025-09-14T09:20:06.655Z","dependency_job_id":"5000a7a2-7ecb-4d7e-a75c-7f59b7de0c1f","html_url":"https://github.com/phenibut645/balkon","commit_stats":null,"previous_names":["phenibut645/balkon"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/phenibut645/balkon","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phenibut645%2Fbalkon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phenibut645%2Fbalkon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phenibut645%2Fbalkon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phenibut645%2Fbalkon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phenibut645","download_url":"https://codeload.github.com/phenibut645/balkon/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phenibut645%2Fbalkon/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278956330,"owners_count":26075221,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["1000-7","discord-js","mysql2","nodejs","typescript","vitest-ts","zxc"],"created_at":"2025-10-08T14:04:09.047Z","updated_at":"2026-04-18T11:03:43.522Z","avatar_url":"https://github.com/phenibut645.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🚬 Balkon\n\nThe bot was created for [Discord Server](https://discord.gg/eMrbGMzmyt)\n\nWritten in Node.js using mysql2 for the database and discord.js/rest for communication with the Discord API.\n\n## Setup\n\n1. Install dependencies:\n   `npm install`\n2. Create local env files from the templates:\n   `Copy-Item .env.dev.example .env.dev`\n   `Copy-Item .env.prod.example .env.prod`\n3. Fill in Discord, MySQL and Twitch credentials in the copied files.\n4. Build the bot:\n   `npm run build`\n5. Initialize the database schema if the database is empty:\n   `npm run db:init:dev`\n6. Run the bot in development mode:\n   `npm run dev`\n7. Register slash commands when needed:\n   `npm run dev-deploy`\n\n## Production Start\n\nDirect production start:\n\n1. Build the bot:\n   `npm run build`\n2. Initialize the production database schema if the database is empty:\n   `npm run db:init:prod`\n3. Register production slash commands if needed:\n   `npm run prod-deploy`\n4. Start the compiled bot in production mode:\n   `npm run start`\n\nOne-liner for full production start:\n\n`npm run start:prod`\n\nIf you want to run production without building `dist` first, use:\n\n`npm run start:prod:tsx`\n\n## PM2 Start\n\nThe repository now includes `ecosystem.config.cjs` for PM2.\n\nTypical flow:\n\n1. Build the bot:\n   `npm run build`\n2. Initialize the production database schema if the database is empty:\n   `npm run db:init:prod`\n3. Register production slash commands if needed:\n   `npm run prod-deploy`\n4. Start through PM2:\n   `npm run pm2:start`\n5. Check logs:\n   `npm run pm2:logs`\n6. Restart after updates:\n   `npm run pm2:restart`\n7. Stop the process:\n   `npm run pm2:stop`\n\nEquivalent raw PM2 commands:\n\n- `pm2 start ecosystem.config.cjs --only balkon-bot`\n- `pm2 restart balkon-bot`\n- `pm2 logs balkon-bot`\n- `pm2 stop balkon-bot`\n\n## Environment variables\n\nCurrent runtime requires these values:\n\n- `DISCORD_TOKEN`\n- `CLIENT_ID`\n- `GUILD_ID`\n- `DB_HOST` (preferred) or `HOST`\n- `DB_USER` (preferred) or `USER`\n- `DB_PASSWORD` (preferred) or `PASSWORD`\n- `DB_NAME` (preferred) or `DATABASE`\n- `TWITCH_CLIENT_ID`\n- `TWITCH_SECRET_ID`\n- `DEVELOPER_DISCORD_ID`\n- `BOT_ADMIN_IDS` (optional, comma-separated)\n\nReserved variables for upcoming diploma features:\n\n- `OBS_WEBSOCKET_URL`\n- `OBS_WEBSOCKET_PASSWORD`\n- `OBS_AGENT_RELAY_PORT`\n- `OBS_AGENT_REQUEST_TIMEOUT_MS`\n- `WEB_SESSION_SECRET`\n- `WEB_PORT`\n\n## OBS Agent Mode\n\nFor production with remote streamers, the bot now supports an agent-based OBS flow:\n\n- The main Discord bot runs on your server.\n- The bot starts a WebSocket relay on `OBS_AGENT_RELAY_PORT`.\n- Each streamer runs a local `obs_agent` process on the same PC as OBS.\n- The local agent connects outward to your relay and controls local OBS via `ws://127.0.0.1:4455`.\n\nWhy this matters:\n\n- The bot no longer needs direct network access to the streamer's OBS.\n- OBS stays local to the streamer PC.\n- NAT and home-router limitations are avoided because the agent uses an outgoing connection.\n\nAgent setup on the streamer PC:\n\n1. Copy `.env.agent.example` to `.env.agent`.\n2. Fill in `OBS_AGENT_RELAY_URL`, `OBS_AGENT_ID`, `OBS_AGENT_TOKEN`.\n3. Point local OBS connection to `OBS_WEBSOCKET_URL=ws://127.0.0.1:4455` and set password if needed.\n4. Start the local agent with `npm run agent`.\n\nBot-side binding flow:\n\n1. Register the streamer with `/streamer register`.\n2. Bind the streamer's agent with `/streamer agent_set`.\n3. Check status with `/streamer agent_show` or `/streamer list`.\n4. Use `/serviceuse` and service items will route OBS actions through that streamer's local agent.\n\n## Current Item MVP\n\nThis diploma-ready MVP already supports the core admin-managed item flow:\n\n- `/raritycreate` creates a custom rarity with an optional embed color.\n- `/itemcreate` creates an item template with name, description, rarity, type, image URL, tradeability and optional bot sell price.\n- `/itemcatalog` shows the latest item templates.\n- `/iteminfo` shows the full card of one item template, including the image.\n- `/itemgive` issues one or more concrete item copies to a Discord user.\n- `/inventory` shows a user's inventory. Foreign inventory viewing is restricted to bot admins.\n- `/itemview` shows the full card of one concrete inventory item.\n- `/menu` provides quick navigation and item-management shortcuts.\n\nThe broader diploma demo flow already includes the first connected economy loop:\n\n- `/balance` shows current ODM and LDM.\n- `/market list`, `/market sell`, `/market buy` cover the global player-to-player market.\n- `/botshop list`, `/botshop add`, `/botshop buy`, `/botshop sell` cover fixed-price bot commerce.\n\nThe next diploma-ready gameplay layer now includes:\n\n- `/craftrecipecreate` for admin-managed craft recipes.\n- `/craftrecipes`, `/craftinfo`, `/craft` for user crafting.\n- `/obs status`, `/obs scenes`, `/obs switch_scene`, `/obs source_visibility`, `/obs reconnect` for OBS WebSocket interaction.\n\nRecommended showcase flow:\n\n1. Run `npm run dev`.\n2. Register slash commands with `npm run dev-deploy`.\n3. As a bot admin, create one rarity with `/raritycreate`.\n4. Create an item template with `/itemcreate`, including an `image_url`.\n5. Inspect it with `/iteminfo` or `/itemcatalog`.\n6. Give the item to a test user with `/itemgive`.\n7. Show `/inventory` and `/itemview` in Discord to demonstrate concrete item instances, original owner tracking and image rendering.\n8. Put one item on the market with `/market sell` and buy it from another user with `/market buy`.\n9. Add one fixed bot listing with `/botshop add`, then demonstrate `/botshop buy` and `/botshop sell`.\n10. Open `/menu` and show that the user can navigate between balance, inventory, market, bot shop and admin shortcuts.\n11. Create one craft recipe and show `/craft` consuming materials into a crafted result item.\n12. If OBS is available, show `/obs status` and `/obs switch_scene` as the streamer-control extension point.\n\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://media.tenor.com/chNGPcAXt4QAAAAd/pirat.gif\" width=\"300\" /\u003e\n  \u003cimg src=\"https://media.tenor.com/SxzG9vFWtTcAAAAM/zxc-cat.gif\" width=\"224\" /\u003e\n  \u003cimg src=\"https://images6.fanpop.com/image/photos/41000000/Ken-Kaneki-tokyo-ghoul-GIF-anime-41018150-500-395.gif\" width=\"283\" /\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphenibut645%2Fbalkon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphenibut645%2Fbalkon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphenibut645%2Fbalkon/lists"}