-
Notifications
You must be signed in to change notification settings - Fork 16
Port Slack Events Bot into Laravel #570
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
oliviasculley
wants to merge
19
commits into
hackgvl:develop
Choose a base branch
from
oliviasculley:slack-events-bot
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
67cddbe
Port Slack Events Bot
bogdankharchenko b2f59a3
style
bogdankharchenko 126203c
Simplify code
bogdankharchenko eaa08f3
pint
bogdankharchenko 2b6b56b
Delete .env.example
bogdankharchenko 9da7f5f
add slack bot manifest
oliviasculley 5d11872
update composer
oliviasculley 1ac8926
add changes to get slash commands and message updating working
oliviasculley cf2c176
implement deleting old messages command
oliviasculley c1bfeab
update versions
oliviasculley 783d307
add development mode changes
oliviasculley c076f50
add details about creating a slack app
oliviasculley 924c66f
fix bug that AI found?
oliviasculley 333b9db
use access tokens per workspace
oliviasculley 6aebdeb
run composer update again
oliviasculley da0908d
move docs to docs folder
oliviasculley 7de2c92
add more env vars and better docs
oliviasculley df68940
remove extra spacing
oliviasculley aa2d970
Fix styling
oliviasculley File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Our production is still on older versions of PHP and Node. Once we move things off to Railway, we shouldn't have an issue with versions. Is changing this likely to mess with anything on the npm or composer packages? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,3 @@ | ||
| nodejs 18.17.1 | ||
| php 8.1.27 | ||
| yarn 1.22.19 | ||
| nodejs 24.3.0 | ||
| php 8.3.6 | ||
| yarn 1.22.22 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| FROM serversideup/php:8.1-fpm-nginx | ||
| FROM serversideup/php:8.3-fpm-nginx | ||
|
|
||
| # Install additional packages | ||
| USER root | ||
|
|
||
irby marked this conversation as resolved.
Show resolved
Hide resolved
oliviasculley marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| # Slack Events Bot Module | ||
|
|
||
| A Laravel module that posts HackGreenville events from the database to configured Slack channels. | ||
|
|
||
| ## Installation | ||
|
|
||
| This module is automatically loaded as it's in the `app-modules` directory. | ||
|
|
||
| ## Configuration | ||
|
|
||
irby marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Add the following environment variables to your `.env` file: | ||
|
|
||
| ```env | ||
| SLACK_BOT_TOKEN=xoxb-your-bot-token | ||
oliviasculley marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| SLACK_SIGNING_SECRET=your-signing-secret | ||
| SLACK_CLIENT_ID=your-client-id | ||
| SLACK_CLIENT_SECRET=your-client-secret | ||
| ``` | ||
|
|
||
| ## Setting up Slack Credentials for Testing | ||
|
|
||
| To obtain the necessary Slack credentials for testing (SLACK_BOT_TOKEN, SLACK_SIGNING_SECRET, SLACK_CLIENT_ID, SLACK_CLIENT_SECRET), you'll need to create a Slack app and configure it. Follow these steps: | ||
|
|
||
| 1. Run `cp app-modules/slack-events-bot/slackbot-manifest.json app-modules/slack-events-bot/slackbot-manifest.dev.json` to create a copy version of the manifest. More information about Slack bot manifests can be found on their documentation [here](https://docs.slack.dev/app-manifests/). Modify the values in `slackbot-manifest.dev.json` to match your public endpoint. If you don't have a public endpoint, you may need to create one with [ngrok](https://ngrok.com/). | ||
|
|
||
| 2. Go to [api.slack.com/apps](https://api.slack.com/apps) and click "Create New App". Then, upload your development manifest to get a head start. | ||
|
|
||
| 3. Get the following environment variables and add them to your `.env` file: `SLACK_BOT_TOKEN`, `SLACK_SIGNING_SECRET`, `SLACK_CLIENT_ID`, `SLACK_CLIENT_SECRET` | ||
|
|
||
| 4. Next, navigate to your public endpoint and add `/slack/install` at the end. You should see a `Add to Slack` button displayed if it worked correctly! | ||
|
|
||
| 5. Go through the flow to connect the bot to a server and channel accordingly. | ||
|
|
||
| 6. In your Slack workspace, try doing the `/check_api`, `/add_channel`, and `/remove_channel` commands. | ||
|
|
||
| 7. The slackbot should work correctly! | ||
|
|
||
| ## Publishing Configuration | ||
|
|
||
| To publish the configuration file: | ||
|
|
||
| ```bash | ||
| php artisan vendor:publish --tag=slack-events-bot-config | ||
| ``` | ||
|
|
||
| ## Running Migrations | ||
|
|
||
| The migrations will run automatically with: | ||
|
|
||
| ```bash | ||
| php artisan migrate | ||
| ``` | ||
|
|
||
| ## Available Commands | ||
|
|
||
| ```bash | ||
| # Manually check for events and update Slack messages | ||
| php artisan slack:check-events | ||
|
|
||
| # Delete old messages (default: 90 days) | ||
| php artisan slack:delete-old-messages | ||
| php artisan slack:delete-old-messages --days=60 | ||
| ``` | ||
|
|
||
| ## Scheduled Tasks | ||
|
|
||
| The module automatically schedules: | ||
| - Event check: Every hour | ||
oliviasculley marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| - Old message cleanup: Daily | ||
|
|
||
| Make sure your Laravel scheduler is running: | ||
|
|
||
| ```bash | ||
| php artisan schedule:work | ||
| ``` | ||
|
|
||
| ## Slack Commands | ||
|
|
||
| The bot supports the following slash commands: | ||
irby marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| - `/add_channel` - Add the current channel to receive event updates (admin only) | ||
| - `/remove_channel` - Remove the current channel from receiving updates (admin only) | ||
| - `/check_api` - Manually trigger an event check (rate limited to once per 15 minutes per workspace) | ||
|
|
||
| ## Routes | ||
|
|
||
| - `GET /slack/install` - Display Slack installation button | ||
| - `GET /slack/auth` - OAuth callback for Slack | ||
| - `POST /slack/events` - Webhook endpoint for Slack events and commands | ||
|
|
||
| ## Features | ||
|
|
||
| - Posts weekly event summaries to configured Slack channels | ||
| - Automatically updates messages when events change | ||
| - Handles message chunking for large event lists | ||
| - Rate limiting for manual checks | ||
| - Admin-only channel management | ||
| - OAuth installation flow | ||
| - Automatic cleanup of old messages | ||
| - Direct database integration (no API calls needed) | ||
|
|
||
| ## How It Works | ||
|
|
||
| 1. The bot queries the Event model directly every hour for new/updated events | ||
| 2. Events are filtered to show published events from 1 day ago to 14 days ahead | ||
| 3. Events are grouped by week (Sunday to Saturday) | ||
| 4. Messages are posted/updated in configured Slack channels | ||
| 5. If a week has many events, they're split across multiple messages | ||
| 6. Messages for the current week and next week (5 days early) are maintained | ||
|
|
||
| ## Configuration Options | ||
|
|
||
| The module can be configured in `config/slack-events-bot.php`: | ||
|
|
||
| - `days_to_look_back` - How many days in the past to include events (default: 1) | ||
| - `days_to_look_ahead` - How many days in the future to include events (default: 14) | ||
| - `max_message_character_length` - Maximum characters per Slack message (default: 3000) | ||
| - `check_api_cooldown_minutes` - Cooldown period for manual checks (default: 15) | ||
| - `old_messages_retention_days` - Days to keep old messages (default: 90) | ||
|
|
||
| ## Migration from Python | ||
|
|
||
| This module is a Laravel port of the original Python slack-events-bot, now refactored to use the Event model directly instead of making API calls. This provides: | ||
|
|
||
| - Better performance (no HTTP overhead) | ||
| - Real-time data (no API caching delays) | ||
| - Tighter integration with the application | ||
| - Easier maintenance and debugging | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| { | ||
| "name": "hack-greenville/slack-events-bot", | ||
| "description": "Slack bot that relays information from HackGreenville Labs' Events API to Slack channels", | ||
| "type": "library", | ||
| "license": "MIT", | ||
| "version": "1.0", | ||
| "autoload": { | ||
| "psr-4": { | ||
| "HackGreenville\\SlackEventsBot\\": "src/", | ||
| "HackGreenville\\SlackEventsBot\\Database\\Factories\\": "./database/factories/" | ||
| } | ||
| }, | ||
| "autoload-dev": { | ||
| "psr-4": { | ||
| "HackGreenville\\SlackEventsBot\\Tests\\": "tests/" | ||
| } | ||
| }, | ||
| "extra": { | ||
| "laravel": { | ||
| "providers": [ | ||
| "HackGreenville\\SlackEventsBot\\Providers\\SlackEventsBotServiceProvider" | ||
| ] | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| <?php | ||
|
|
||
| return [ | ||
| /* | ||
| |-------------------------------------------------------------------------- | ||
| | Slack Bot Configuration | ||
| |-------------------------------------------------------------------------- | ||
| | | ||
| | These are the configuration values for the Slack Events Bot. | ||
| | | ||
| */ | ||
|
|
||
| 'bot_token' => env('SLACK_BOT_TOKEN'), | ||
| 'signing_secret' => env('SLACK_SIGNING_SECRET'), | ||
| 'client_id' => env('SLACK_CLIENT_ID'), | ||
| 'client_secret' => env('SLACK_CLIENT_SECRET'), | ||
|
|
||
| /* | ||
| |-------------------------------------------------------------------------- | ||
| | Scopes | ||
| |-------------------------------------------------------------------------- | ||
| */ | ||
| 'scopes' => [ | ||
| 'chat:write', | ||
| 'chat:write.public', | ||
| 'commands', | ||
| 'incoming-webhook', | ||
| 'users:read', | ||
| ], | ||
|
|
||
| /* | ||
| |-------------------------------------------------------------------------- | ||
| | Message Configuration | ||
| |-------------------------------------------------------------------------- | ||
| */ | ||
| 'max_message_character_length' => 3000, | ||
| 'header_buffer_length' => 61, | ||
|
|
||
| /* | ||
| |-------------------------------------------------------------------------- | ||
| | Cooldown Configuration | ||
| |-------------------------------------------------------------------------- | ||
| */ | ||
| 'check_api_cooldown_minutes' => 15, | ||
|
|
||
| /* | ||
| |-------------------------------------------------------------------------- | ||
| | Database Configuration | ||
| |-------------------------------------------------------------------------- | ||
| */ | ||
| 'old_messages_retention_days' => 90, | ||
|
|
||
| /* | ||
| |-------------------------------------------------------------------------- | ||
| | Event Configuration | ||
| |-------------------------------------------------------------------------- | ||
| */ | ||
| 'days_to_look_back' => 1, | ||
| 'days_to_look_ahead' => 14, | ||
| ]; |
20 changes: 20 additions & 0 deletions
20
app-modules/slack-events-bot/database/factories/SlackChannelFactory.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| <?php | ||
|
|
||
| namespace HackGreenville\SlackEventsBot\Database\Factories; | ||
|
|
||
| use HackGreenville\SlackEventsBot\Models\SlackChannel; | ||
| use HackGreenville\SlackEventsBot\Models\SlackWorkspace; | ||
| use Illuminate\Database\Eloquent\Factories\Factory; | ||
|
|
||
| class SlackChannelFactory extends Factory | ||
| { | ||
| protected $model = SlackChannel::class; | ||
|
|
||
| public function definition(): array | ||
| { | ||
| return [ | ||
| 'slack_channel_id' => $this->faker->unique()->regexify('[C][A-Z0-9]{10}'), | ||
| 'slack_workspace_id' => SlackWorkspace::factory(), | ||
| ]; | ||
| } | ||
| } |
24 changes: 24 additions & 0 deletions
24
app-modules/slack-events-bot/database/factories/SlackMessageFactory.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| <?php | ||
|
|
||
| namespace HackGreenville\SlackEventsBot\Database\Factories; | ||
|
|
||
| use HackGreenville\SlackEventsBot\Models\SlackChannel; | ||
| use HackGreenville\SlackEventsBot\Models\SlackMessage; | ||
| use Illuminate\Database\Eloquent\Factories\Factory; | ||
| use Illuminate\Support\Carbon; | ||
|
|
||
| class SlackMessageFactory extends Factory | ||
| { | ||
| protected $model = SlackMessage::class; | ||
|
|
||
| public function definition(): array | ||
| { | ||
| return [ | ||
| 'week' => Carbon::now()->startOfWeek(), | ||
| 'message' => $this->faker->sentence, | ||
| 'message_timestamp' => now()->timestamp . '.' . $this->faker->randomNumber(6, true), | ||
| 'sequence_position' => $this->faker->numberBetween(0, 10), | ||
| 'channel_id' => SlackChannel::factory(), | ||
| ]; | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.