{"id":27334971,"url":"https://github.com/dmuth/cheetah-bot","last_synced_at":"2025-07-18T01:04:18.449Z","repository":{"id":48963350,"uuid":"359245824","full_name":"dmuth/cheetah-bot","owner":"dmuth","description":"A Telegram bot to post cheetah pictures and make cheetah sounds.","archived":false,"fork":false,"pushed_at":"2022-04-20T00:48:59.000Z","size":1598,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-12T14:51:30.469Z","etag":null,"topics":["cheetah","furry","furry-fandom","python","telegram","telegram-bot"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dmuth.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":"dmuth"}},"created_at":"2021-04-18T20:27:38.000Z","updated_at":"2022-04-20T00:49:03.000Z","dependencies_parsed_at":"2022-09-24T00:52:06.553Z","dependency_job_id":null,"html_url":"https://github.com/dmuth/cheetah-bot","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dmuth/cheetah-bot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmuth%2Fcheetah-bot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmuth%2Fcheetah-bot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmuth%2Fcheetah-bot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmuth%2Fcheetah-bot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dmuth","download_url":"https://codeload.github.com/dmuth/cheetah-bot/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmuth%2Fcheetah-bot/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265686650,"owners_count":23811210,"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","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":["cheetah","furry","furry-fandom","python","telegram","telegram-bot"],"created_at":"2025-04-12T14:46:45.529Z","updated_at":"2025-07-18T01:04:18.394Z","avatar_url":"https://github.com/dmuth.png","language":"Python","funding_links":["https://github.com/sponsors/dmuth"],"categories":[],"sub_categories":[],"readme":"\n\u003cimg src=\"./img/screenshot2.png\" align=\"right\" width=\"300\" /\u003e\n\n# Cheetah Bot for Telegram\n\nThis script lets you run a Telegram Bot that (semi-regularly) posts pictures of cheetahs and (semi-regularly) replies to comments as if it were a cheetah.\n\n\n## Features\n\n- Will post a cheetah sound or picture when trigged by every Nth message (configurable)\n- Messages with profanity or the middle finger emoji will provoke smartass responses.\n- Can be configured to only interact wiht allowlisted groups/group IDs.\n- When added to a channel, sent the message `help` on a channel, or DMed, it will respond with an \"about me\" string.\n- Configurable rate limiting to prevent accidental flooding of the group.\n- Age checking on messages to prevent spamming the group after a hiatus.\n- Support for talking to \u003ca href=\"https://mitmproxy.org/\"\u003emitmproxy\u003c/a\u003e, if you'd like to monitor network activity.\n\n\n## Usage\n\n- Talk to \u003ca href=\"https://t.me/BotFather\"\u003e@BotFather on Telegram\u003c/a\u003e to create a bot.\n- Copy down the API token.\n- Go to `Bot Settings -\u003e Group Privacy` and click `Turn Off`. This will allow your bot to see messages sent to groups it is in.\n- Copy `.env-SAMPLE` to `.env` and fill out the settings.  Settings are described in detail further down.\n- Add your bot to one or more groups.  Make sure the group owners are cool with this!\n- Start the bot using one of the methods outlined below:\n\n\n### Docker Compose\n\n- Verify environment settings with with `docker-compose config`\n- `docker-compose up`\n- To kill, rebuild, and relaunch the container:\n   - `docker-compose kill; docker-compose rm -f; docker-compose build; docker-compose up -d; docker-compose logs -f`\n\n\n### CLI\n\n- `. .env` - Read the variables from our `.env file.\n- `export $(cat .env | egrep \"^\\w\" | cut -d= -f1)` - Mark those varaibles as exportable.\n- `pip install -r ./requirements.txt`\n- `./cheetah-bot.py` - Usage arguments will be displayed.\n\n### Development mode\n\n- `. .env` - Read the variables from our `.env file.\n- `export $(cat .env | egrep \"^\\w\" | cut -d= -f1)` - Mark those varaibles as exportable.\n- `./bin/devel.sh` - This will start a Docker container with a `bash` shell.  Follow the instructions on screen to proceed.\n   - `./bin/run-bot.sh` - Meant to be run inside of a `bash` shell spawned by `devel.sh`, this will print the environment variables you're using before running the bot and give you a chance to change them.\n   - `./bin/import-mitmproxy-cert.py` - Run this inside of a `bash shell spawned by `devel.sh` to import the mitmproxy root certificate.\n- `./bin/build.sh` - Build the container only.  This is called by `bin/devel.sh`.\n- `./bin/docker-compose-build-and-run.sh` - Build and run the container with `docker-compose`, and tail the output.\n\n\n## Configuration\n\n- `GROUP_IDS` - Optional. List of group IDs (separated by spaces) where the bot should operate.\n   - If unsure of the group ID, use `GROUP_NAMES`, and the ID will show up in the logging messages from the bot.\n   - If neither this nor `GROUP_NAMES` are specified, then any group may add this bot.\n- `GROUP_NAMES` - Optional. A list of strings (separated by spaces) which are then substring matched against the name of the gorup as messages come in.  Be careful with this, because `test` will match `test`, `test2`, and `test1234`, for example.  Note that a string can't have a space in it, since the space is a delimiter.  \n- `ACTIONS` - Used for rate-limiting.  How many messages can be sent in a given period?\n- `PERIOD` - Used for rate-limiting. How long is the period in seconds?\n   - Note that the queue for sending messages is refilled based on time-elapsed.\n   - For example, ACTIONS=2 and PERIOD=10 means that .2 will be added to the queue every second.\n   - So if a message is sent at second 0, the queue is now 1, at 1 second, it is 1.2, then 1.4 at 2 seconds, etc. until the queue maxes out at 2.\n- `POST_EVERY` - Posts wehn tirggered by every Nth message in the group.  100 is usually a good number.\n   - Optional.  If not specified, the cheetah bot will not issue any unsolicited replies.\n- `POSTS_FILE` - CSV File containing image comments and optional images to go with them.  Defaults to `./posts.txt`.\n   - Default images can be found Imgur: https://imgur.com/gallery/iisbC6p\n- `PROFANITY_REPLY` - Set to 1 for the bot to reply to profanity it sees in channels.  This can be annoying, so it's off by default.\n\n\n## Good Testing Practices\n\nI'm not even sure how to unit test against Telegram, so I have manual instructions here for now:\n\n- Start the bot with default settings, except for... \n   - `POST_EVERY`, which should be 2.\n   - `ACTIONS` should be 2.\n   - `PERIOD` should be 10.\n   - e.g. `POST_EVERY=2 ACTIONS=2 PERIOD=10 /mnt/bin/run-bot.sh`\n- Send 2 test messages to the group, ensure the bot replies to the second message.\n- Type `chee` and ensure the bot replies.\n- Type an f-bomb in a message and make sure the bot catches that.\n- Type a message with the bot tagged in it and ensure it replies\n   - Repeat a few times to make sure it does text AND images\n- Reply to a message from the bot in the gorup and ensure it replies\n   - Repeat a few times to make sure it does text AND images\n- Spam the bot with messages until you exhaust the quota (it won't take long with these settings) and make sure it goes to sleep than wakes back up.\n- Finally, send a DM to the bot and make sure it replies.\n\n### Unit Testing\n\n- `bin/pytest` - Run unit tests.  This script is just a wrapper to add `lib/` into `$PYTHONPATH`.\n   - `-s` - Specify `-s` to print contents of stdout. \n   - `-k string` - Run only tests that match that substring\n   - `--log-cli-level=info` - Specify to print logging messages.\n      - Note that `--log-cli-level=info` may break some tests, and there are calls to get quota values in logging messages.  I warned ya!\n   - `file` Specify a unit test file to run\n\nThere is a great blog post about mocking \u003ca href=\"https://yeraydiazdiaz.medium.com/what-the-mock-cheatsheet-mocking-in-python-6a71db997832\"\u003eover here\u003c/a\u003e.\n\n\n## Mitmproxy Support\n\nIf you'd like to send traffic through `mitmproxy` for testing, here's how to make that happen: \n\n- Make sure `mitmproxy` is installed\n- Edit `.env` and set the `HTTP_PROXY` and `HTTPS_PROXY` values to `http://YOUR_IP:8080/`\n   - Note that `YOUR_IP` is NEITHER localhost NOR 127.0.0.1.  It must be the local network IP of your machine, since localhost would be just the Docker container.\n- Copy the CA for mitmproxy to this directory: `cp ~/.mitmproxy/mitmproxy-ca-cert.pem .`\n   - If this fails, try running `mitmproxy` once\n- Start the Docker container in devel mode: `./bin/devel.sh`\n- Run the script `./bin/import-mitmproxy-cert.py` inside the shell to ingest the CA for mitmproxy.\n   - If this is not done, you'll see a `certificate verify failed` error and the bot will not run.\n- Make sure `mitmproxy`, `mitmdump`, or `mitmweb` is running on the host machine.\n   - If it's not running, you'll see a `Connection refused` error and the bot will not run.\n\n\n## Future Features to add\n\n- [ ] Ability for group admins to configure limits on bot\n- [ ] Add `POST_RANDOM` with a percent float that maxes out at `.10`\n\n\n## Credits\n\n- Jan De Dobbeleer for \u003ca href=\"./bin/import-mitmproxy-cert.py\"\u003ehis excellent post\u003c/a\u003e on how to talk to mitmproxy from a Python app in a Docker container.\n\n\n## Copyrights\n\n- The code is copyright by me, and the license is in \u003ca href=\"LICENSE\"\u003eLICENSE\u003c/a\u003e.\n- The images it uses are copyright via their owners.\n\n\n## Contact\n\nMy email is doug.muth@gmail.com.  I am also \u003ca href=\"http://twitter.com/dmuth\"\u003e@dmuth on Twitter\u003c/a\u003e \nand \u003ca href=\"http://facebook.com/dmuth\"\u003eFacebook\u003c/a\u003e!\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmuth%2Fcheetah-bot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdmuth%2Fcheetah-bot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmuth%2Fcheetah-bot/lists"}