Ассистент — это бот для Trello, который помогает поддерживать Канбан-доски в Trello в актуальном состоянии.
Автоматизированные действия:
- Ежедневный перенос карточек по столбцам "Сегодня", "Завтра", "На этой неделе", "В этом месяце"
- Обновление крайнего срока на карточке при переносе между столбцами. Например, при переносе карточки в столбец "Сегодня" будет автоматически установлен крайний срок как "сегодня 23:59", а при переносе карточки в стобец "На этой неделе" будет установлен крайний срок "ближайшее воскресенье 23:59"
- При создании карточки, она сразу же назначается на владельца доски и на ней устанавливается крайний срок в соответствии со столбцом, в котором она создана
- Все просроченные карточки переносятся в столбец "Сегодня"
- При простановке флажка "завершено" на крайнем сроке карточки, она автоматически переносится в столбец "Сделано" на самый верх
- При перемещении карточки в столбец "Сделано" проставляется флаг "завершено" на крайнем сроке и снимается, когда карточка перемещается из столбца "Сделано" в другой
- При удалении флажка "завершено" на крайнем сроке карточки, она автоматически переносится в столбец "Сегодня"
- Карточки со сроками в следующем месяце и далее, автоматически переносятся на основную доску, когда подходит их срок
Все действия выполняются от пользователя ассистента Trello, поэтому в истории действий карточек и доски видно, что было сделано вручную, а что автоматически. Так как Ассистент при активном использовании генерирует очень много действий и на каждое из них приходит уведомление, реализован механизм отписки от карточки и подписке заново до и после каждого действия.
Ассистент написан на Scala, компилируется в исполняемый JAR-файл и должен быть развёрнут на сервере. Взаимодействие с Trello происходит через REST API и Webhooks.
Вы можете использовать сервер с Ubuntu 20.04 или выше. Нужно установить JRE и открыть порт.
# Install JRE
sudo apt install default-jre
# Check
java -version
# Open port
sudo ufw allow 8080
Вы можете использовать сервер с Ubuntu 20.04 или выше. Нужно установить сервер PostgreSQL,
создать пароль для пользователя postgres
и создать базу данных assistant
.
# Update indexes
sudo apt update
# Install psql server
sudo apt install postgresql postgresql-contrib
# Make sure psql works & add to autostart
sudo systemctl start postgresql.service
systemctl enable postgresql
# Login as postgres user
sudo -i -u postgres
# psql shell
psql
# Execute in psql shell, change password
ALTER USER postgres PASSWORD 'xxxxxxxxxxxxxxxx';
\q
# Create database
createdb assistant
Временная мера, автоматический ежедневный перенос карточек по столбцам. Добавьте это в cron (crontab -e
):
1 0 * * * curl http://yourserver.com/api/trello/organize_cards
С учётом вашего часового пояса расписание cron будет выглядеть так: 1 (24-TZ) * * *
. Например для UTC+3 (Europe/Moscow)
это будет 1 21 * * *
.
Для работы вам понадобится два аккаунта Trello: личный и для ассистента. Если у вас нет личного аккаунта Trello, создайте его, затем создайте аккаунт для ассистента.
- Создайте личный аккаунт в Трелло (если необходимо)
- Создайте аккаунт для ассистента в Трелло, загрузите аватарку и отключите в настройках уведомления на электронную почту
Из подвашего личого аккаунта Трелло потребуется создать две доски "Текущая" и "Следующая". Вы можете назвать их как угодно, но в этой инструкции будут использоваться такие названия.
- Залогиньтесь в свой личный аккаунт Trello
- Создайте доску "Текущая"
- Для доски "Текущая" создайте столбцы "Сделать", "На этой неделе", "Завтра", "Сегодня", "В процессе", "Делегировано", "Сделано"
- Создайте серую метку "закреплено" на доске "Текущая" (создайте карточку, затем создайте метку, затем удалите карточку)
- Добавьте пользователя Ассистента на доску "Текущая" с обычными (Normal) правами
- Создайте доску "Следующая"
- Для доски "Следующая" создайте столбцы "Сделать" и "Сделано"
- Создайте серую метку "закреплено" на доске "Следующая" (создайте карточку, затем создайте метку, затем удалите карточку)
- Добавьте пользователя Ассистента на доску "Следующая" с обычными (Normal) правами
Вызов API возможен из-под авторизованного пользователя. Для этого потребуется токен и ключ приложения.
Как было отмечено выше, при активном использовании ассистент генерирует очень много действий, каждое из которых генерирует уведомление. Чтобы избежать этого, приходится отписываться от уведомлений карточки до действия и подписываться на неё после каждого действия. Отписку и подписку приходится делать из-под личного пользователя, так что нужно получить токен и ключ приложения для личного пользователя и для пользователя Ассистента.
- Залогиньтесь в свой личный аккаунт Trello
- Получите ключ приложения для личного аккаунта
- Получите токен для личного аккаунта (
https://trello.com/1/authorize?expiration=never&scope=read,write,account&response_type=token&name=Server%20Token&key=<YOUR_KEY>
) - Залогиньтесь в аккаунт Ассистента
- Получите ключ приложения для аккаунта Ассистента
- Получите токен для аккаунта Ассистента (
https://trello.com/1/authorize?expiration=never&scope=read,write,account&response_type=token&name=Server%20Token&key=<YOUR_KEY>
)
Ассистент полностью конфигурируется через единственный файл reference.conf
(src/main/resources/reference.conf
).
Заполните все поля:
assistant.trello.timeZoneCorrection
,целое число — коррекция времени относительно UTC. Для часового пояса UTC+3 (Europe/Moscow) это будет3
assistant.trello.users.assistant.id
, строка — идентификатор пользователя Ассистентаassistant.trello.users.assistant.token
, строка — токен для пользователя Ассистентаassistant.trello.users.assistant.appKey
, строка — ключ приложения для пользователя Ассистентаassistant.trello.users.owner.id
, строка — идентификатор личного пользователяassistant.trello.users.owner.token
, строка — токен личного пользователяassistant.trello.users.owner.appKey
, строка — ключ приложения личного пользователяassistant.trello.limits.cardsPerDay
, целое число — максимальное число карточек в деньassistant.trello.limits.cardsPerWeek
, целое число — максимальное число карточек в неделюassistant.trello.limits.cardsPerMonth
, целое число — максимальное число карточек в месяцassistant.trello.limits.cardsPerYear
, целое число — максимальное число карточек в годassistant.trello.labels.pin.name
, строка — имя метки "закреплено"assistant.trello.boards.current.id
, строка — идентификатор доски "Текущая"assistant.trello.boards.current.columns.todo.id
, строка — идентификатор столбца "Сделать" доски "Текущая"assistant.trello.boards.current.columns.todo.name
, строка — название столбца "Сделать" доски "Текущая"assistant.trello.boards.current.columns.week.id
, строка — идентификатор столбца "На этой неделе" доски "Текущая"assistant.trello.boards.current.columns.week.name
, строка — название столбца "На этой неделе" доски "Текущая"assistant.trello.boards.current.columns.tomorrow.id
, строка — идентификатор столбца "Завтра" доски "Текущая"assistant.trello.boards.current.columns.tomorrow.name
, строка — название столбца "Завтра" доски "Текущая"assistant.trello.boards.current.columns.today.id
, строка — идентификатор столбца "Сегодня" доски "Текущая"assistant.trello.boards.current.columns.today.name
, строка — название столбца "Сегодня" доски "Текущая"assistant.trello.boards.current.columns.inProgress.id
, строка — идентификатор столбца "В процессе" доски "Текущая"assistant.trello.boards.current.columns.inProgress.name
, строка — название столбца "В процессе" доски "Текущая"assistant.trello.boards.current.columns.delegated.id
, строка — идентификатор столбца "Делегировано" доски "Текущая"assistant.trello.boards.current.columns.delegated.name
, строка — название столбца "Делегировано" доски "Текущая"assistant.trello.boards.current.columns.done.id
, строка — идентификатор столбца "Сделано" доски "Текущая"assistant.trello.boards.current.columns.done.name
, строка — название столбца "Сделано" доски "Текущая"assistant.trello.boards.next.columns.todo.id
, строка — идентификатор столбца "Сделать" доски "Следующая"assistant.trello.boards.next.columns.todo.name
, строка — название столбца "Сделать" доски "Следующая"assistant.trello.boards.next.columns.done.id
, строка — идентификатор столбца "Сделано" доски "Следующая"assistant.trello.boards.next.columns.done.name
, строка — название столбца "Сделано" доски "Следующая"assistant.server.host
, строка — хост сервераassistant.server.port
, целое число — порт сервераassistant.db.url
, строка — JDBC-урл для подключения к PostgreSQLassistant.db.user
, строка — пользователь для подключения к PostgreSQLassistant.db.password
, строка — пароль для подключения к PostgreSQLassistant.db.driver
, строка — класс драйвера PostgreSQLassistant.db.connections.poolSize
, строка — размер пула соединений PostgreSQL
Где взять? (везде используеются токен и ключ основного аккаунта Трелло)
- Идентификаторы досок:
https://api.trello.com/1/members/me/boards?key=<APP KEY>&token=<TOKEN>
- Идентификаторы столбцов:
https://api.trello.com/1/boards/<BOARD ID>/lists?key=<APP KEY>&token=<TOKEN>
- Создайте карточки для Ассистента и для основго пользователя на любой доске, назначьте одну на себя, другую на ассистента и достаньте идентификаторы пользователей из
https://api.trello.com/1/boards/<BOARD ID>/cards?key=<APP KEY>&token=<TOKEN>
Скопируйте содержимое в файл src/main/resources/reference.conf
:
assistant {
trello {
timeZoneCorrection=3
users {
assistant {
id="xxxxxxxxxxxxxxxxxxxxxxxx"
appKey="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
token="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
owner {
id="xxxxxxxxxxxxxxxxxxxxxxxx"
appKey="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
token="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
limits {
cardsPerDay=7
cardsPerWeek=49
cardsPerMonth=196
cardsPerYear=2352
}
labels {
pin {
name="закреплено"
}
}
boards {
current {
id="xxxxxxxxxxxxxxxxxxxxxxxx"
columns {
todo {
id="xxxxxxxxxxxxxxxxxxxxxxxx"
name="Сделать"
}
week {
id="xxxxxxxxxxxxxxxxxxxxxxxx"
name="На этой неделе"
}
tomorrow {
id="xxxxxxxxxxxxxxxxxxxxxxxx"
name="Завтра"
}
today {
id="xxxxxxxxxxxxxxxxxxxxxxxx"
name="Сегодня"
}
inProgress {
id="xxxxxxxxxxxxxxxxxxxxxxxx"
name="В процессе"
}
delegated {
id="xxxxxxxxxxxxxxxxxxxxxxxx"
name="Делегировано"
}
done {
id="xxxxxxxxxxxxxxxxxxxxxxxx"
name="Сделано"
}
}
}
next {
id="xxxxxxxxxxxxxxxxxxxxxxxx"
columns {
todo {
id="xxxxxxxxxxxxxxxxxxxxxxxx"
name="Сделать"
}
done {
id="xxxxxxxxxxxxxxxxxxxxxxxx"
name="Сделано"
}
}
}
}
}
server {
host="0.0.0.0"
port=8080
}
db {
url="jdbc:postgresql://postgres/web"
user="postgres"
password="postgres"
driver="org.postgresql.Driver"
connections = {
poolSize = 10
}
}
}
# Get source code
git clone https://github.com/char16t/assistant
git clone https://github.com/char16t/flow
cd flow
sbt +publishLocal
cd ..
cd assistant
# Build
./sbtx assembly
Отправить на сервер приложение можно через scp:
# Deploy
scp target/scala-2.12/assistant-assembly-0.0.1-SNAPSHOT.jar user@yourserver.com:/root/assistant.jar
scp reference.conf user@yourserver.com:/root/assistant.conf
Запуск приложения:
nohup java -Dassistant.config=assistant.conf -jar assistant.jar &> assistant.log &
Проверка, что приложение работает:
curl http://yourserver.com:8080/api/trello
Остановка приложения:
# Get PID of "java" process
top
# Kill it
kill -9 <pid>
Через Webhooks Трелло сообщает о новых событиях, таких как создание и обновление карточек. Нужно создать веб-хуки для обеих досок "Текущая" и "Следующая". Вставьте токен, ключ приложения для вашего личного пользователя Трелло и адрес сервера, на котором уже работает ассистент и выполните:
Здесь также нужно вставить идентификатор доски "Текущая":
curl -X POST -H "Content-Type: application/json" \
https://api.trello.com/1/tokens/<TOKEN>/webhooks/ \
-d '{
"key": "<APP KEY>",
"callbackURL": "http://yourserver.com:8080/api/trello/receive_webhook",
"idModel":"<CURRENT BOARD ID>",
"description": "Assistant Webhook for Daily board"
}'
Придет ответ от Трелло:
{
"id": "xxxxxxxxxxxxxxxxxxxxxxxx",
"description": "Assistant Webhook for Daily board",
"idModel": "xxxxxxxxxxxxxxxxxxxxxxxx",
"callbackURL": "http://assistant.manenkov.com:8080/api/trello/receive_webhook",
"active": true,
"consecutiveFailures": 0,
"firstConsecutiveFailDate": null
}
Аналогично для доски "Следующая":
curl -X POST -H "Content-Type: application/json" \
https://api.trello.com/1/tokens/<TOKEN>/webhooks/ \
-d '{
"key": "<APP KEY>",
"callbackURL": "http://yourserver.com:8080/api/trello/receive_webhook",
"idModel":"<NEXT BOARD ID>",
"description": "Assistant Webhook for Daily Next board"
}'
Придет ответ от Трелло:
{
"id": "xxxxxxxxxxxxxxxxxxxxxxxx",
"description": "Assistant Webhook for Daily Next board",
"idModel": "xxxxxxxxxxxxxxxxxxxxxxxx",
"callbackURL": "http://assistant.manenkov.com:8080/api/trello/receive_webhook",
"active": true,
"consecutiveFailures": 0,
"firstConsecutiveFailDate": null
}