๋งํฌ๋์ธ์์
๋งคํ ๋ฉค๋ฒ๋ค์ด ์๋ก ํ ๋งํ ๋ฅผ ์ฃผ๋ ์ด์ ๋? ๋ผ๋ ๊ธ์ ์ฝ๊ณ , ์ฌ๋ ์ด๋ชจ์ง(Emoji)๋ก ๋ฉค๋ฒ๋ค์๊ฒ ์นญ์ฐฌ์ด๋ ๋ฆฌ์คํ ํ ์ ์๋ ๋ฌธํ๊ฐ ์๊ธด๋ค๋ฉด ์ฌ๋ฐ๊ธฐ๋ ํ๊ณ ๊ณ ๋ง์๋ ํํํ ์ ์์ ๊ฒ
๊ฐ์์ต๋๋ค.
๊ทธ๋์ ์ด๋ฐ ์ฌ๋ฏธ๋ ๊ธฐ๋ฅ์ ์คํ์์ค๋ก ๊ณต๊ฐํ๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค๊ณ ์๊ฐํด์ ํ ์ด ํ๋ก์ ํธ๋ก ๋ง๋ค์ด ๋ณด์์ต๋๋ค.
(๊ทผ๋ฐ Nodejs๋ก ๋ง๋ค์ด์ง๊ฒ ์ด๋ฏธ ์์๋ค์ heyburrito)
์ข ๋ ์ฌ๋ฏธ๋ ๊ธฐ๋ฅ + ์์ฑ๋ ์๋ ํ๋ก์ ํธ๊ฐ ๋๊ธฐ์ํด ์ ์ง๋ณด์๋ ์ง์์ ์ผ๋ก ํ ์์ ์
๋๋ค.๐ช
FastAPI์ ๊ตฌ์กฐ๋ ํ๋ก์ ํธ ๊ด๋ จ๋ ์ถ๊ฐ๊ธฐ๋ฅ, ๊ฐ์ ์ฌํญ PR์ ์ธ์ ๋ ํ์์
๋๋ค!
Heymoji API์๋ฒ๋ Python 3.10, FastAPI ๋ก ๊ฐ๋ฐ๋์์ต๋๋ค.
๊ทธ ์ธ ๋ฒ์ ์์ ํจํค์ง ๋ฐ ๋์์ ๋ํ ํธํ์ ๋ณด์ฅํ์ง ์์ต๋๋ค. (๊ทผ๋ฐ ๊ฑฐ์ ๋ค ๋ ๊ฑฐ์์ python3.7 ์ด์์ด๋ฉด...์๋ง๋~๐ )
ํ๋ก ํธ์๋๋ vuejs๋ฅผ ์ฌ์ฉํด์ ๊ฐ๋จํ ๋ง๋ค์ด ๋ดค์ต๋๋ค!
์ฒ์ Heymoji๋ฅผ ๊ฐ๋ฐํ ๋๋ DDD ๊ตฌ์กฐ๊ฐ ์๋์์ต๋๋ค.
DDD์ ๋ํ ์คํฐ๋๋ฅผ ์ํด ๊ตฌ์กฐ๋ฅผ ๋ณ๊ฒฝํ์ผ๋ฉฐ https://github.com/Ermlab/python-ddd ๋ฅผ ์ฐธ๊ณ ํ์์ต๋๋ค.
๋ค์ ๋ณต์กํ ์ ์์ผ๋ ์ถํ ์ ์ง๋ณด์์ ์ฌ๋ฌ ์ํ๋ณ๊ฒฝ์ด ์ผ์ด๋๋ ๊ฒฝ์ฐ DDD๊ฐ ์ข ๋ ์ ์ฐํ ๊ฑฐ๋ผ๊ณ ์๊ฐํ์ต๋๋ค๐
โโโ apps
| โโ api
| | โโโ dependancy
| | โโโ router
| โโ applications
| | โโโ services (Application Service)
| โโ domains
| | โโ user (๋๋ฉ์ธ)
| | โโ entities.py
| | โโ services.py (Domain Service)
| | โโ repositories.py
| | โโ schemas.py
| โโ infrastructure (infra ๊ด๋ จ ์ ์ ๊ตฌ์กฐ)
| โโ utils
| โโ tests
| โโ main.py
โโโ conf
| โโโ settings.py
โโโ scripts
โโโ migrations (alembic DB ๋ง์ด๊ทธ๋ ์ด์
์ค์ )
โโโ seed_work (ํ๋ก์ ํธ์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํด์ผํ๋ ์์
, ์ฝ๋)
โโโ alembic.ini
โโโ requirements.txt
โโโ docker-compose.yaml
โโโ Dockerfile
โโโ web.Dockerfile
โโโ .env_sample
โโโ frontend (heymoji ์นํ์ด์ง ๊ด๋ จ ์ฝ๋)
.env_sample์ ์ฐธ๊ณ ํด์ .envํ์ผ์ ์์ฑํฉ๋๋ค.
์ํ์๋ ์ธํ
์ผ๋ก ํ๊ฒฝ๋ณ์๋ค์ ์ธํ
ํฉ๋๋ค.
DB๋ MySQL์ ์ฌ์ฉํ๋ฉฐ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ์ํด aiomysql๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํจ๊ป ์ฌ์ฉํฉ๋๋ค.
๋ค๋ฅธ DB ์ฌ์ฉํ๋ ค๋ฉด config ์ค์ ์ด ์กฐ๊ธ ๋ฌ๋ผ์ง ์ ์์ต๋๋ค.
| ์ด๋ฆ | ์ค๋ช |
|---|---|
| ENV | ๋ฐฐํฌํ๊ฒฝ ์ ์ |
| ALLOW_ORIGINS | CORS๋ฅผ ํ์ฉํ ORIGIN ๋ฆฌ์คํธ |
| DB_HOST | DB ํธ์คํธ |
| DB_PORT | DB ํฌํธ |
| DATABASE | DB ์ด๋ฆ |
| DB_USERNAME | DB ์ ์ ์ ์ ๋ค์ |
| DB_PASSWORD | DB ํจ์ค์๋ |
| SLACK_TOKEN | ์ฌ๋ ํ ํฐ |
| BOT_NAME | ์ฌ๋๋ด ์ด๋ฆ |
| ERROR_CHANNEL | ์ฌ๋ ์๋ฌ ๋ฆฌํฌํ ์ฑ๋ |
| SPECIAL_EMOJI | ํน๋ณํ ์๋ฏธ๋ฅผ ๊ฐ์ง ์ด๋ชจ์ง |
| LIMIT_GIVE_COUNT_OF_SPECIAL_EMOJI | ๋งค์ ๋ค๋ฅธ ๋ฉค๋ฒ์๊ฒ ์ค ์ ์๋ SPECIAL_EMOJI ์ ํ ๊ฐ์ |
| ALLOWED_REACTION_LIST | ์นํ ๋ฆฌ์ก์ ์ผ๋ก ํ์ฉ๋ ์ด๋ชจ์ง(reaction)๋ค์ ์ ์ํฉ๋๋ค. |
| ALLOWED_EMOJI_TYPES | ํธ๋ค๋งํ ์ด๋ชจ์ง๋ค์ ์ ์ํฉ๋๋ค. |
| RANK_URL | ๋ญํน ์นํ์ด์ง URK |
| DEFAULT_AVATAR_URL | ๊ธฐ๋ณธ ํ๋กํ ์ด๋ฏธ์ง URL |
.env_sample์ ์ฐธ๊ณ ํ์ฌ.envํ์ผ์ ์์ฑํ ๋ค docker-compose up -d ๋ฅผ ์คํํฉ๋๋ค.
api, web, db ์ปจํ
์ด๋๊ฐ ๋ชจ๋ ์คํ ๋ ํ http://127.0.0.1:8080 ์ ์ ์ํ์ฌ ๋์์ ํ์ธํฉ๋๋ค.
โ๏ธ์ฃผ์: ์ปจํ
์ด๋๊ฐ ๋จ๊ณ ํจํค์ง ์ค์น์ ์๊ฐ์ด ๊ฑธ๋ฆด์ ์์ด์ ์ ํ๋ฆฌ์ผ์ด์
์คํ๊น์ง ๋ช๋ถ์ด ์์ ๋ ์ ์์ต๋๋ค.
docker-comopse ์คํ ์ ์ README ํ๋จ์ ์๋
Slack Bot ์ค์ ์ ๋จผ์ ๋ณด์๊ณ SlackToken ๊ฐ์ ํ๊ฒฝ๋ณ์๋ฅผ ๋จผ์ ์ฃผ์
ํด์ฃผ์ธ์!
pip install -r requirements
root๊ฒฝ๋ก(/heymoji) ์ ๊ฐ์ uvicorn์ผ๋ก ์๋ฒ๋ฅผ ์คํ์ํต๋๋ค.
๋ฐฑ๊ทธ๋ผ์ด๋๋ก ์คํํ๊ธฐ ์ํด์๋ &๋ฅผ ๋ง์ง๋ง์ ๋ถ์ฌ์ฃผ์ธ์.
uvicorn app.main:app --port 8080
๋ง์ฝ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์คํ๋๊ณ ์๋ ํ๋ก์ธ์ค๋ฅผ ์ ๊ฑฐํ๊ณ ์ถ์ ๊ฒฝ์ฐ
1. ps aux | grep uvicorn
2. kill -9 {PID}
์๋ชป๋ ํ๋ก์ธ์ค kill์ ์ฃผ์ํ์ธ์!
HOST_URL/docs๋ก ์ ์ํ๋ฉด Swagger๋ก ๋ง๋ค์ด์ง web ํ์ด์ง๋ฅผ ํ์ธํ ์ ์์ต๋๋ค. (FastAPI๋ swagger, redoc ์ง์)
| ์ด๋ฆ | ์ค๋ช |
|---|---|
| help | ์ปค๋ฉ๋ ๊ด๋ จ help |
| create_user | user ์์ฑ |
| update_user | user ์ ๋ณด ์ ๋ฐ์ดํธ |
| show_user | ์ ์ is_display = True (๋ ธ์ถ) |
| hide_user | ์ ์ is_display = False (์จ๊น) |
| show_best_member | ํด๋น์ ๋ฒ ์คํธ ๋ฉค๋ฒ ์ถ์ถ |
๐ฅณ ๋ฉค๋ฒ ๋ฑ๋ก
์ด๋ฆ์ ํ์ ์
๋๋ค!
@EmojiBot --create_user --name=์ด๋ฆ --avatar_url=์ด๋ฏธ์งURL --department=๋ถ์
๐ ๋ฉค๋ฒ ์ ๋ณด ์
๋ฐ์ดํธ
์
๋ฐ์ดํธํ ์ ๋ณด๋ง ์ ์ด์ฃผ์ธ์!
@EmojiBot --update_user --avatar_url=์ด๋ฏธ์งURL
๐ ์ด๋ฒ๋ฌ ๋ฒ ์คํธ ๋ฉค๋ฒ ๋ฆฌ์คํธ ์ถ์ถ
@EmojiBot --show_best_member --year=2022 --month=1
๐ ์ ์ ์จ๊ธฐ๊ธฐ
@EmojiBot --hide_user --slack_id=์ฌ๋ID
๐ ์ ์ ๋ณด์ด๊ธฐ
@EmojiBot --show_user --slack_id=์ฌ๋ID
shell script๋ก ๊ฐ๋จํ๊ฒ Live ์ฒดํฌ๋ฅผ ์งํ ํ ์ ์์ต๋๋ค! ํฌ๋ก ํญ์ 1๋ถ๋ง๋ค ์คํํ๋๋ก ๋ฑ๋ก.
๋ก๊น
๋ ์ถ๊ฐํ๋ฉด ์ข์ต๋๋ค.
#! /bin/bash
PYTHON_PATH=/{{ path }}/venv/bin/python
SCRIPT_PATH=/{{ path }}/heymoji/app
checker=`ps aux | grep -v "grep" | grep "{{ ๊ฒ์ํ ์ด๋ฆ}}" | wc -l`
if [ "$checker" == "0" ]; then
source '{{ path }}/venv/bin/activate'
cd $SCRIPT_PATH && `uvicorn main:app --port 8080 &`
fi
https://api.slack.com/apps ์ ์ ์ํ์ฌ create app ๋ฒํผ์ ํด๋ฆญํ ํ,
์ํ๋ workspace์ app์ ์์ฑํด์ฃผ์ธ์!
Basic Information ํญ์ ํด๋ฆญํ ํ๋จ์์ app์ ํ๋กํ ์ด๋ฏธ์ง๋ฅผ ์ถ๊ฐํ๊ณ Save ํด์ค๋๋ค.
์ด๊ฑด ์ํด๋ ๋์ง๋ง ํ๋๊ฒ ์ข์์. ์๋ํ๋ฉด ๋ฉ์๊ฑฐ๋ ์๐
Add features and functionality์์ Event Subscriptions์ ํด๋ฆญํฉ๋๋ค.
Event๋ฅผ Enable(ํ์ฑํ) ์ํจํ Requst URL์ ๋ฃ์ด์ ์ธ์ฆ์ ํฉ๋๋ค.
์ ํ๋ฉด์์ ์ฌ๋ํ ํฐ์ copyํ์ฌ .env ํ์ผ์ ์ถ๊ฐํฉ๋๋ค.
๋ก์ปฌ์์ ํ
์คํธ ํ๊ธฐ ์ํด ngrok์ ์ฌ์ฉํ์๋ฉด ํธํฉ๋๋ค.์ค์ prod
ํ๊ฒฝ์์๋ Nginx + uvicorn์ผ๋ก ์คํํ๋ฉด ๋์!
Nginx Config ์์ proxy_pass ๋ง uvicorn์ผ๋ก ์คํํ ๋ก์ปฌ ์๋ฒ๋ก ์ฐ๊ฒฐํด์ฃผ๋ฉด ๋ฉ๋๋ค!
Heymoji๋ ์ฌ๋ ๋ฉค๋ฒ๋ค์ reaction_added, reaction_removed ์ด๋ฒคํธ์ bot์ ํธ์ถํ๋ app_mention ์ด๋ ๊ฒ 3๊ฐ์ง ์ด๋ฒคํธ๋ฅผ ๋ฐ์ต๋๋ค.
์ฌ๋๋ด๊ณผ DM์ ํตํด ๋ช
๋ น์ด๋ฅผ ์คํํ๊ธฐ ์ํด์๋ message.im์ ์ ํํ๊ณ Message Tab ๊ธฐ๋ฅ์ on ์์ผ์ฃผ์
์ผ ํฉ๋๋ค.
๋ง์ง๋ง์ผ๋ก app์ workspace์ ์ค์น(install)ํ๋ฉด ์ค์ ํ ์ด๋ฒคํธ๊ฐ ์ผ์ด๋ ๋๋ง๋ค slack์์ Heymoji์๋ฒ๋ก ์นํ
api๋ฅผ ํธ์ถํฉ๋๋ค.














