Skip to content

Commit

Permalink
feat: bootstrap
Browse files Browse the repository at this point in the history
  • Loading branch information
cabelitos committed Dec 19, 2020
0 parents commit 20e109b
Show file tree
Hide file tree
Showing 17 changed files with 4,660 additions and 0 deletions.
12 changes: 12 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
SLACK_BOT_TOKEN='TOKEN'
TYPEORM_PASSWORD=tijolo22
TYPEORM_CONNECTION=postgres
TYPEORM_PORT=5432
TYPEORM_USERNAME=tacos-db
TYPEORM_DATABASE=tacos-db
TYPEORM_HOST=localhost
TYPEORM_SYNCHRONIZE=1
TYPEORM_ENTITIES=./src/entities/*.ts
LEADERBOARD_LIMIT=10
HEALCHECKER_PORT=8080
HEALCHECKER_HOST=localhost
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build/*
**/node_modules/**
117 changes: 117 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
{
"env": {
"node": true
},
"plugins": [
"@typescript-eslint",
"filenames",
"import"
],
"parser": "@typescript-eslint/parser",
"extends": [
"airbnb-base",
"plugin:prettier/recommended",
"plugin:import/errors",
"prettier",
"plugin:@typescript-eslint/recommended",
"prettier/@typescript-eslint"
],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2019,
"sourceType": "module"
},
"settings": {
"import/resolver": {
"typescript": {}
}
},
"rules": {
"import/extensions": ["error", "never"],
"@typescript-eslint/consistent-type-assertions": [
"error",
{
"assertionStyle": "as",
"objectLiteralTypeAssertions": "allow-as-parameter"
}
],
"@typescript-eslint/explicit-function-return-type": "error",
"@typescript-eslint/explicit-member-accessibility": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{
"argsIgnorePattern": "^_"
}
],
"filenames/match-exported": [
"error",
[
null,
"kebab"
]
],
"filenames/match-regex": [
"error",
"^[a-zA-Z]+(-[a-z]+)*(\\.[a-z]+)?$",
true
],
"func-names": [
2,
"never"
],
"func-style": [
2,
"expression",
{
"allowArrowFunctions": true
}
],
"global-require": 0,
"import/no-cycle": "error",
"import/no-unresolved": "error",
"import/order": [
"error",
{
"groups": [
[
"builtin",
"external"
],
[
"sibling",
"parent",
"internal",
"index"
]
],
"newlines-between": "always-and-inside-groups"
}
],
"no-restricted-imports": [
"error",
{
"patterns": [
"../../*"
]
}
],
"sort-keys": "error",
"strict": [
0,
"global"
]
},
"overrides": [
{
"files": [
"*.js"
],
"rules": {
"@typescript-eslint/no-var-requires": "off"
}
}
]
}
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
node_modules
build
.vscode
.env
.eslintcache
yarn-error.log
.docker-secret*
**.DS_Store
lerna-debug.log
coverage
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
12.20.0
10 changes: 10 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"arrowParens": "avoid",
"singleQuote": true,
"trailingComma": "all",
"parser": "typescript",
"semi": true,
"printWidth": 80,
"tabWidth": 2,
"useTabs": false
}
20 changes: 20 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM node:12.20.0-alpine

WORKDIR /slack-app
COPY . ./
COPY ./docker/entrypoint.sh /entrypoint.sh

RUN export LANG=en_US.UTF-8 \
&& apk --no-cache add curl \
&& yarn install \
&& yarn run build \
&& cp -a build / \
&& rm -rf node_modules \
&& yarn install --production \
&& cp -a node_modules /build

WORKDIR /build

ENV NODE_ENV=production

ENTRYPOINT ["/entrypoint.sh"]
65 changes: 65 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Taco Libre

This project is a clone of [HeyTaco](https://cabelitosinc.slack.com/apps/A0J4UNFLN-heytaco) slack app, but open and free.

## Features

* No taco limits per day.
* Leader boards.
* Bot can join multiple channels.
* Unified leader board for every channel that the bot is listening.

## Distributing tacos

In order to award a taco to someone, just tag the person and put
a taco emoji in the message that the bot will add it to the leaderboard.
(Remember that the bot __must__ be present in the channel).

## Bot commands

* @[botname] leaderboard: Show the current leaderboard on the channel

## Enabling the Bot

* Visit https://api.slack.com/apps?new_classic_app=1 to create a new app and choose the app name and workspace
* After it's created Choose "App Home" under "Features" menu
* Click in "Add legacy bot user"
* Fill the form and submit
* Mark the "Always show my bot as online" option
* Go back to "Basic Information" under "Settings" menu
* Install the app on the workspace
* Go to "OAuth & Permissions" under "Features" menu and copy the "Bot User OAuth Access Token"
* Set this token in the "SLACK_BOT_TOKEN" env variable.
* You're good to go.

## Running

To run locally start the postgres database by running (don't forget to set the .docker-secret-db-password for the database password)
```sh
docker-compose up tacos-db
```

After the database is running install all deps by running
```sh
yarn install && cp .env.example .env
```

Now change the `TYPEORM_PASSWORD` which sets the database password and the `SLACK_BOT_TOKEN` (acquired via `Enabling the Bot` section) variables. After this just run

```sh
yarn start
```

You're ready

## Bot in action

![bot-demo](./demo/demo.gif)

## TODO

* Add logging infra via winston or pico
* k8s deploy?
* Publish slack app?
* Add more commands and features
* Add complex bot messages, like showing leader board for the week, month, year
1 change: 1 addition & 0 deletions commitlint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = { extends: ['@commitlint/config-angular'] };
Binary file added demo/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
66 changes: 66 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
version: "3.7"

services:
tacos-db:
image: postgres:13-alpine
container_name: tacos-db-postgres
restart: on-failure
secrets:
- db-password
environment:
- POSTGRES_PASSWORD_FILE=/run/secrets/db-password
- POSTGRES_USER=tacos-db
- POSTGRES_DB=tacos-db
expose:
- '5432'
ports:
- "127.0.0.1:5432:5432"
networks:
- private
volumes:
- "tacos-db-data:/var/lib/postgresql/data"

taco-libre:
build: .
image: taco-libre:latest
networks:
- private
secrets:
- db-password
- slack-bot-token
environment:
- SLACK_BOT_TOKEN_FILE=/run/secrets/slack-bot-token
- TYPEORM_PASSWORD_FILE=/run/secrets/db-password
- TYPEORM_CONNECTION=postgres
- TYPEORM_PORT=5432
- TYPEORM_USERNAME=tacos-db
- TYPEORM_DATABASE=tacos-db
- TYPEORM_SYNCHRONIZE=1
- TYPEORM_HOST=tacos-db
- TYPEORM_ENTITIES=./entities/*.js
- TYPEORM_LOGGING=all
- LEADERBOARD_LIMIT=10
- HEALCHECKER_HOST=localhost
- HEALCHECKER_PORT=80
container_name: taco-libre
healthcheck:
test: curl -f http://localhost/.well-known/fastify/server-health || exit 1
interval: 1m
timeout: 10s
retries: 3
start_period: 30s
restart: always
depends_on:
- tacos-db

networks:
private:

volumes:
tacos-db-data:

secrets:
slack-bot-token:
file: .docker-secret-slack-bot-token
db-password:
file: .docker-secret-db-password
35 changes: 35 additions & 0 deletions docker/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/sh

# usage: file_env VAR [DEFAULT]
# ie: file_env 'XYZ_DB_PASSWORD' 'example'
# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
function file_env() {
local var="$1"
local def="${2:-}"
local fileVar="${var}_FILE"
local fileVal=`eval echo \$"${fileVar}"`
local val=`eval echo \$"${var}"`
if [ -n "$val" ] && [ -n "$fileVal" ]; then
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
exit 1
elif [ -f "$fileVal" ]; then
val=`cat $fileVal`
elif [ -z "$val" ]; then
val="$def"
fi

export "$var"="$val"
}

file_env TYPEORM_PASSWORD
file_env SLACK_BOT_TOKEN

# Add npm bin directory to PATH in order to run wait-for-postgres
PATH=$(npm bin):$PATH

# Wait until Postgres is up and running

wait-for-postgres --username=${TYPEORM_USERNAME} --password=${TYPEORM_PASSWORD} -h ${TYPEORM_HOST} -D ${TYPEORM_DATABASE} --quiet

exec node index.js "$@"
48 changes: 48 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "taco-libre",
"version": "1.0.0",
"main": "./build/index.js",
"license": "MIT",
"scripts": {
"start": "nodemon -r dotenv-safe/config ./src/index.ts",
"build": "tsc",
"check-types": "tsc --noEmit",
"run-lint": "eslint --max-warnings=0 --ext .ts src",
"lint": "run-s check-types run-lint"
},
"devDependencies": {
"@commitlint/cli": "^11.0.0",
"@commitlint/config-angular": "^11.0.0",
"@types/node": "^12.0.0",
"@typescript-eslint/eslint-plugin": "^4.10.0",
"@typescript-eslint/parser": "^4.10.0",
"dotenv-safe": "^8.2.0",
"eslint": "^7.15.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-config-prettier": "^7.0.0",
"eslint-import-resolver-typescript": "^2.3.0",
"eslint-plugin-filenames": "^1.3.2",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-prettier": "^3.3.0",
"husky": "^4.3.6",
"nodemon": "^2.0.6",
"npm-run-all": "^4.1.5",
"prettier": "^2.2.1",
"ts-node": "^9.1.1",
"typescript": "^4.1.3"
},
"husky": {
"hooks": {
"pre-commit": "yarn lint",
"pre-push": "yarn lint",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
},
"dependencies": {
"@slack/rtm-api": "^5.0.5",
"fastify": "^3.9.2",
"pg": "^8.5.1",
"typeorm": "^0.2.29",
"wait-for-postgres": "^1.5.3"
}
}
Loading

0 comments on commit 20e109b

Please sign in to comment.