Fitter — сшиватель API/Website's. Большое обновление
- среда, 31 января 2024 г. в 00:00:16
Добрый вечер всем!
С момента выхода предидущей статьи про Fitter прошло достаточно много времени и в связи с этим я хотел поделиться обновлениями, которые были сделаны.
Итак, что появилось:
Написано, какое-никакое README.md , которое регулярно пополняется фишками.
Добавлена возможность использования как библиотека для go.
Добавлена поддержка плагинов на go.
Добавлена поддержка прокси для коннекторов (server/playwright).
Добавлена возможность отправки обновлений в console(stdout)/telegram/http/redis.
Убрано огромное дуплицирование кода с помощью generic.
Добавлена возможность скачивать файлы.
Добавлена возможность делать вычисляемые поля и благодаря этому можно делать супер связки конфигураций(об этом ниже).
Добавлено возможность создавать reference(можно кэшировать данные и переиспользовать их) и инжектить переменные среды.
Добавлена возможность делать fallback на любые поля если оно пустое.
Напоследок хотелось бы показать пример конфигурации которую делал для друга. И так его задача с сохранением орфографии:
ну сначала нужно получить все позиции юзера https://docs.saucerswap.finance/v/developer/saucerswap-v2/liquidity-operations/get-user-positions
потом все пулы https://docs.saucerswap.finance/v/developer/saucerswap-v2/liquidity-operations/fetch-all-pools
и потом заметчить позиции юзера с пулами что бы определить какие позици вне диапазона пула
И так что получилось:
{
"references": {
"AllPoolRef": {
"expire": "60",
"connector_config": {
"response_type": "json",
"url": "https://api.saucerswap.finance/v2/pools/",
"server_config": {
"method": "GET"
}
},
"model": {
"array_config": {
"item_config": {
"fields": {
"tokenA": {
"base_field": {
"type": "string",
"path": "tokenA.symbol"
}
},
"tokenB": {
"base_field": {
"type": "string",
"path": "tokenB.symbol"
}
}
}
}
}
}
},
"AccountIdRef": {
"connector_config": {
"response_type": "json",
"static_config": {
"value": "{{{FromEnv=USER_ID}}}"
}
},
"model": {
"base_field": {
"type": "string"
}
}
}
},
"items": [
{
"name": "user-position",
"connector_config": {
"response_type": "json",
"url": "https://api.saucerswap.finance/V2/nfts/{{{RefName=AccountIdRef}}}/positions",
"server_config": {
"method": "GET"
}
},
"model": {
"array_config": {
"item_config": {
"fields": {
"position": {
"base_field": {
"type": "object",
"generated": {
"formatted": {
"template": "tokenA={{{tokenA.symbol}}} tokenB={{{tokenB.symbol}}}"
}
}
}
},
"value": {
"base_field": {
"type": "object",
"path": "",
"generated": {
"calculated": {
"type": "boolean",
"expression": "any(fromJSON('{{{RefName=AllPoolRef}}}'), {.tokenA == '{{{tokenA.symbol}}}' && .tokenB == '{{{tokenB.symbol}}}'})"
}
}
}
}
}
}
}
},
"trigger_config": {
"scheduler_trigger": {
"interval": 10
}
},
"notifier_config": {
"expression": "any(fRes, {.value == true})",
"telegram_bot": {
"token": "{{{FromEnv=TELEGRAM_TOKEN}}}",
"users_id": [],
"pretty": true
}
}
}
]
}
Тут есть два параметра из среды:
TELEGRAM_TOKEN - строка 95
USER_ID - строка 37
Все что надо было сделать другу это запустить Fitter и добавить в конфиг ID юзеров для нотификации(строка 95):
TELEGRAM_TOKEN=xxx USER_ID=xxx ./fitter --path=./config.json
Расскажу что тут происходит:
Создаем Reference(строка 3) на все пулы и кэшируем на 60 секунд(строка 4). Мы берем и создаем массив объектов с двумя полями(символы двух токенов из пулов).
Создаем Reference(строка 33) на AccountId, это будет просто строка.
Мы создаем item для мониторинга каждые 10 секунд(строка 88) который берет данные с сервера с inject account Id(строка 52), который представляет из себя массив обьектов с двумя полями. Первое позиция(строка 66) - это шаблонная строка с inject результата. Второе это результат проверки содержится ли токены юзера в пуле из Reference(пункт первый) типа boolean.
Дальше мы уведомляем если какое нибудь из полей имеет значение true(строка 93).
Получаем в телегу уведомление:
Result for: user-position
[
{
"position": "tokenA=USDC tokenB=USDC[hts]",
"value": true
},
{
"value": false,
"position": "tokenA=USDC tokenB=USDT"
}
]
PS: false значения можно было игнорировать, но не стал.
Спасибо за внимание, продолжаю работать на проектом!