Simple periodically timer on Slack, sending a message to DM Channel.
⚠️ This project is Kata with Golang and Clean Architecture. Please use Reminder if the timer feature on Slack is needed.
Photo by Peter Yost on Unsplash
- Notify message on Slack by interval minutes.
- Set on and off a notification.
- Slack account
- AWS account assigned policies: Lambda, DynamoDB, SQS, CloudWatch, and CloudFormation
- AWS SAM CLI, version 1.7.0
Creating AWS resources by SAM CLI.
$ cd ./deployments/sam/slack-timer
# Build
$ sam build
Building codeuri: ../../../cmd/lambda/enqueue runtime: go1.x metadata: {} functions: ['EnqueueFunction']
...
Build Succeeded
...
# Deploy to AWS.
$ sam deploy --guided
Configuring SAM deploy
======================
...
Stack Name [sam-app]: slacktimer
...
... enter attributes as you like
...
CloudFormation outputs from deployed stack
...
--------------------------------------------------------------------------------------------
Outputs
--------------------------------------------------------------------------------------------
Key SlackEventAPIRequestURL
Description Enter this URL as the Request URL notified by Slack
Value https://<API_ID>.execute-api.ap-northeast-1.amazonaws.com/Prod/callback/slack
...
--------------------------------------------------------------------------------------------
Successfully created/updated stack - slacktimer in ap-northeast-1
Set each environment variable to each Lambda function the following.
| Key | Value |
|---|---|
| APP_ENV | prod or dev |
| APP_LOG_LEVEL | debug or info or error |
| DYNAMODB_INDEX_NAME | TimeIndex |
| DYNAMODB_INDEX_PRIMARY_KEY_VALUE | 1 |
| DYNAMODB_TABLE | EventTableName value in Cloudformation outputs. |
| SQS_URL | EventQueueURL value in Cloudformation outputs. |
| Key | Value |
|---|---|
| APP_ENV | prod or dev |
| APP_LOG_LEVEL | debug or info or error |
| DYNAMODB_INDEX_NAME | TimeIndex |
| DYNAMODB_INDEX_PRIMARY_KEY_VALUE | 1 |
| DYNAMODB_TABLE | event |
| SLACK_API_BOT_TOKEN | Bot User OAuth Access token in OAuth & Permissions page on Slack api page. It can be seen after creating Slack app. e.g. xoxb-xxxxxxxxxxxxx |
| SLACK_API_URL_CHATPOSTMESSAGE | https://slack.com/api/chat.postMessage |
| SLACK_API_URL_CONVERSATIONSOPEN | https://slack.com/api/conversations.open |
Create Slack app having Event Subscriptions, Bots, and Permissions features in a workspace. After that, install it in the workspace. It will be showed in the workspace, if it succeeded in installing.
These control can be in Basic Information page in the Slack app page.
Ref.
Details of features are below.
- Enable events.
- Enter
SlackEventAPIRequestURLvalue which is showed in Cloudformation outputs to Request URL Field. e.g.https://<API_ID>.execute-api.ap-northeast-1.amazonaws.com/Prod/callback/slack. After entering, it will show "Verified √" if it had succeeded in setup. - Add "message.im" event to "Subscribe to events on behalf of users" section.
- Add scopes according to Bot Token Scopes
- Enter "App Display Name" as you like.
- Enable "Message Tab" on "Show Tabs" section.
Add scopes as follow.
- chat:write
- im.history
This app provides three commands to control this app. Add its channel on Slack workspace and enter commands in its channel message window.
| Command | Format | Action |
|---|---|---|
| Set | set minutes text |
Notify text by minutes |
| On | on | Start to notify. |
| Off | off | Suspend to notify. |
e.g.
Receive I'm active message every 15 minutes.
set 15 I'm active!
Suspend the notification.
off
Start the notification.
on
- AWS Serverless: Lambda, DynamoDB, SQS, CloudWatch, API Gateway, and CloudFormation.
- Golang
- Clean Architecture
- Install Golang by following Download and install
- Run
go mod vendorto get modules. - Install AWS SAM CLI by following Installing the AWS SAM CLI
Testing
# With details: "-v" and "-cover"
$ make test
# No details: without flags
$ make test_light
Formatting codes
# Run "go fmt", "goimports", and "go lint".
$ make fmt
- Directory structure refers to golang-standards/project-layout.
- Design refers to Clean architecture. https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
.
|-- .circleci
| `-- config.yml <-- Circle CI config
|-- .gitignore
|-- LICENSE.md
|-- Makefile <-- Defines make command targets
|-- README.md <-- This instruction file
|-- cmd
| `-- lambda
| |-- enqueue
| | `-- main.go <-- Entrypoint of Lambda; Enqueue
| |-- notify
| | `-- main.go <-- Entrypoint of Lambda; Notification
| `-- settime
| `-- main.go <-- Entrypoint of Lambda; Set command
|
|-- deployments
| `-- sam <-- AWS SAM project directory
| `-- slack-timer
| |-- .gitignore
| |-- Makefile
| |-- README.md
| `-- template.yaml <-- CloudFormation template
|
|-- docs
| `-- note.md <-- Notes
|-- go.mod <-- go modules list
|-- go.sum <-- go modules hash list
|-- internal
| |-- app <-- This app directory
| | |-- adapter <-- Interface Adapters layer
| | | |-- enqueue <-- Codes related to SQS Enqueueing
| | | | |-- cloudwatchlogspresenter.go
| | | | |-- ...
| | | |-- notify <-- Codes related to Notifiy
| | | | |-- cloudwatchlogspresenter.go
| | | | |-- ...
| | | |-- settime <-- Codes related to set command
| | | | |-- controller.go
| | | | |-- ...
| | | |-- slackhandler <-- Codes related to Slack API handling
| | | | |-- slackhandler.go
| | | `-- validator <-- Validation methods.
| | | |-- validate_error_bag.go
| | | `-- validate_error_bag_test.go
| | |
| | |-- driver <-- Frameworks & Drivers layer
| | | |-- lambdahandler <-- Codes related to Lambdahandler
| | | | |-- enqueue
| | | | | |-- lambdafunctor.go
| | | | | |-- ...
| | | | |-- notify
| | | | | |-- lambdafunctor.go
| | | | | |-- ...
| | | | `-- settime
| | | | |-- lambdafunctor.go
| | | | `-- ...
| | | |-- queue <-- Codes related to handle SQS
| | | | |-- sqs.go
| | | | |-- ...
| | | |-- repository <-- Codes related to handle DynamoDB
| | | | |-- dynamodb.go
| | | | |-- ...
| | | `-- slack <-- Codes related to handle Slack API
| | | |-- api.go
| | | `-- ...
| | |
| | |-- enterpriserule <-- Enterprise Business Rules layer
| | | |-- timerevent.go
| | | `-- ...
| | |
| | |-- usecase <-- Application Business Rules layer
| | | |-- enqueueevent <-- Enqueueing usecase
| | | | |-- inputport.go
| | | | `-- ...
| | | |-- notifyevent <-- Notification usecase
| | | | |-- inputport.go
| | | | `-- ...
| | | |-- timeroffevent <-- Set off notification usecase
| | | | |-- inputport.go
| | | | `-- ...
| | | |-- timeronevent <-- Set on notification usecase
| | | | |-- inputport.go
| | | | `-- ...
| | | `-- updatetimerevent <-- Set minutes and notification text usecase
| | | |-- inputport.go
| | | `-- ...
| | |
| | `-- util <-- Codes shared throughout the app
| | |-- appcontext <-- Context includes Lambda handler context
| | | |-- appcontext.go
| | | `-- ...
| | |-- appinitializer <-- Initialize the app function
| | | `-- appinitializer.go
| | |-- config <-- Config
| | | |-- config.go
| | | |-- driver <-- Concrete implementation of Config methods
| | | | |-- envconfig.go
| | | | `-- ...
| | | `-- ...
| | |-- di <-- Dependency Injection methods
| | | |-- container <-- Concrete implementation of DI methods
| | | | |-- dev
| | | | `-- ...
| | | |-- di.go
| | | `-- ...
| | `-- log <-- Logging
| | |-- driver <-- Concrete implementation of Logging methods
| | | |-- cloudwatchlogger.go
| | | `-- ...
| | |-- logger.go
| | `-- ...
| |
| `-- pkg <-- Codes shared, which are not dependent on the app
| |-- collection <-- Collection structure
| | |-- set.go
| | `-- ...
| `-- helper <-- Helper functions
| |-- file.go
| |-- http.go
| |-- time.go
| |-- type.go
|
|-- scripts <-- Scripts used by Makefile
| `-- local.sh
`-- website <-- GitHub readme assets
`-- peter-yost-I9jJXmNkXR4-unsplash.jpgThis is just Kata project, but issues and reviews are welcome. Don't hesitate to create issues and PR.
- MIT license
- Copyright 2020 © takakd.


