{"id":19874106,"url":"https://github.com/pythoninthegrass/meetup_bot","last_synced_at":"2025-05-02T10:30:59.704Z","repository":{"id":171161021,"uuid":"487117891","full_name":"pythoninthegrass/meetup_bot","owner":"pythoninthegrass","description":"Use Meetup Pro API to send Slack messages before events occur.","archived":false,"fork":false,"pushed_at":"2024-09-18T07:15:23.000Z","size":1189,"stargazers_count":2,"open_issues_count":4,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-09-19T07:53:17.567Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pythoninthegrass.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2022-04-29T21:44:59.000Z","updated_at":"2024-09-18T07:12:00.000Z","dependencies_parsed_at":"2024-02-29T01:55:15.977Z","dependency_job_id":"6e94e519-e0f6-4f08-9a08-554f880edc47","html_url":"https://github.com/pythoninthegrass/meetup_bot","commit_stats":null,"previous_names":["pythoninthegrass/meetup_bot"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pythoninthegrass%2Fmeetup_bot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pythoninthegrass%2Fmeetup_bot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pythoninthegrass%2Fmeetup_bot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pythoninthegrass%2Fmeetup_bot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pythoninthegrass","download_url":"https://codeload.github.com/pythoninthegrass/meetup_bot/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224306671,"owners_count":17289668,"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":[],"created_at":"2024-11-12T16:21:45.119Z","updated_at":"2025-05-02T10:30:59.692Z","avatar_url":"https://github.com/pythoninthegrass.png","language":"Python","readme":"\u003cimg alt=\"gitleaks badge\" src=\"https://img.shields.io/badge/protected%20by-gitleaks-blue\"\u003e\n\n# meetup_bot\n\n**Table of Contents**\n* [meetup\\_bot](#meetup_bot)\n  * [Summary](#summary)\n  * [Minimum Requirements](#minimum-requirements)\n  * [Recommended Requirements](#recommended-requirements)\n  * [Quickstart](#quickstart)\n    * [Python only](#python-only)\n    * [Shell wrapper](#shell-wrapper)\n    * [Devbox](#devbox)\n    * [Docker](#docker)\n    * [Docker Compose](#docker-compose)\n  * [TODO](#todo)\n  * [Stretch Goals](#stretch-goals)\n  * [Contributors](#contributors)\n  * [Further Reading](#further-reading)\n\n## Summary\n\nUse Meetup Pro API to send Slack messages before events occur.\n\n## Minimum Requirements\n\n* [Python 3.11+](https://www.python.org/downloads/)\n* [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli)\n* [Create a Meetup API key](https://secure.meetup.com/meetup_api/key/)\n* Slack\n  * [Create a Slack app](https://api.slack.com/apps)\n  * [Create a Slack bot](https://api.slack.com/bot-users)\n\n## Recommended Requirements\n\n* [Devbox](https://www.jetpack.io/devbox/docs/quickstart/)\n* [Docker](https://www.docker.com/products/docker-desktop)\n\n## Quickstart\n\n* Clone repo\n* Copy `.env.example` to `.env` and fill out environment variables\n\n### Python only\n\n```bash\ncd ./app\n\n# run individual app\npython \u003csign_jwt|meetup_query|slackbot|main\u003e.py\n\n# run only main app\npython main.py\n```\n\n### Shell wrapper\n\n```bash\ncd ./app\n\n# standalone server w/hard-coded port (default: 3000)\n./startup.sh\n\n# standalone server w/port argument\n./startup.sh 3000\n\n# server used with scheduled job (e.g., cron job)\n./scheduler.sh\n```\n\n### Devbox\n\nI.e., [Nix Package Manager](https://search.nixos.org/packages)\n```bash\n# enter dev environment\ndevbox shell\n\n# run individual app\npython \u003csign_jwt|meetup_query|slackbot|main\u003e.py\n\n# exit dev environment\nexit\n\n# run standalone server\ndevbox run start\n\n# run tests\ndevbox run test\n```\n\n### Docker\n\n```bash\ncd ./app\n\n# build image\ndocker build -f Dockerfile.web --progress=plain -t meetup_bot:latest .\n\n# run image\ndocker run --name meetup_bot -it --rm --env-file .env -p 3000:3000 meetup_bot bash\n```\n\n### Docker Compose\n\n```bash\ncd ./app\n\n# build image\ndocker compose build --remove-orphans\n\n# run image\ndocker compose up -d\n\n# enter server container\ndocker exec -it meetup_bot-cont bash\n\n# exit server container\nexit\n\n# stop image\ndocker compose stop\n\n# remove image\ndocker compose down --volumes\n```\n\n## TODO\n\n* Refactor authentication\n  * passlib + bcrypt -\u003e bcrypt (see: [AttributeError: module 'bcrypt' has no attribute '__about__' with new 4.1.1 version · Issue #684 · pyca/bcrypt](https://github.com/pyca/bcrypt/issues/684#issuecomment-1902590553))\n  * Secured endpoints\n    * Store auth in browser session vs. memory\n* Scheduling\n  * Couple scheduling with locations (e.g., Norman vs. OKC)\n* Norman events\n  * Get Norman events from existing GraphQL API\n    * Coded as `Oklahoma City`\n    * Will need to modify the query to get title and body content\n  * Post to `#norman`\n    * M-F\n* Unit test\n  * Add badge\n  * 100% coverage\n* Documentation\n  * quickstart\n    * `taskfile` usage\n    * QA (especially accounts)\n  * Coralogix logging\n\n## Stretch Goals\n\n* Indicate online vs. in-person\n* Time Frame \n  * 2 hours before\n* Slash commands to manually call:\n  * Next `n` events\n  * This week's events\n  * Create new events\n\n## Contributors\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/alex-code4okc\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/17677369?v=4?s=50\" width=\"50px;\" alt=\"Alex Ayon\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAlex Ayon\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/pythoninthegrass/meetup_bot/commits?author=alex-code4okc\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n  \u003ctfoot\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" size=\"13px\" colspan=\"7\"\u003e\n        \u003cimg src=\"https://raw.githubusercontent.com/all-contributors/all-contributors-cli/1b8533af435da9854653492b1327a23a4dbd0a10/assets/logo-small.svg\"\u003e\n          \u003ca href=\"https://all-contributors.js.org/docs/en/bot/usage\"\u003eAdd your contributions\u003c/a\u003e\n        \u003c/img\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tfoot\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\n## Further Reading\n\n[API Doc Authentication | Meetup](https://www.meetup.com/api/authentication/#p04-jwt-flow-section)\n\n[How to Handle JWTs in Python](https://auth0.com/blog/how-to-handle-jwt-in-python/)\n\n[Building a Basic Authorization Server using Authorization Code Flow (PKCE) | by Ratros Y. | Medium](https://medium.com/@ratrosy/building-a-basic-authorization-server-using-authorization-code-flow-pkce-3155e843466)\n\n[How to cancel a Heroku build | remarkablemark](https://remarkablemark.org/blog/2021/05/05/heroku-cancel-build/)\n\n[OAuth2 with Password (and hashing), Bearer with JWT tokens - FastAPI](https://fastapi.tiangolo.com/tutorial/security/oauth2-jwt/)\n\n[Python bcrypt - hashing passwords in Python with bcrypt](https://zetcode.com/python/bcrypt/)\n\n[MushroomMaula/fastapi_login](https://github.com/MushroomMaula/fastapi_login)\n\n[FastAPI Auth + Login Page](https://dev.to/athulcajay/fastapi-auth-login-page-48po)\n\n[checkbashisms](https://command-not-found.com/checkbashisms)\n\n[Efficient Python Docker Image from any Poetry Project](https://denisbrogg.hashnode.dev/efficient-python-docker-image-from-any-poetry-project)\n\n[Document docker poetry best practices · python-poetry · Discussion #1879](https://github.com/python-poetry/poetry/discussions/1879#discussioncomment-216865)\n\n[Building Docker images in Kubernetes | Snyk](https://snyk.io/blog/building-docker-images-kubernetes/)\n\n[Kaniko, How to Build Container Image with SSH | by Yossi Cohn | HiredScore Engineering | Medium](https://medium.com/hiredscore-engineering/kaniko-builds-with-private-repository-634d5e7fa4a5)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpythoninthegrass%2Fmeetup_bot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpythoninthegrass%2Fmeetup_bot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpythoninthegrass%2Fmeetup_bot/lists"}