- Go 95.1%
- Dockerfile 4.9%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
All checks were successful
docker / build-push (push) Successful in 2m18s
|
||
| .forgejo/workflows | ||
| cmd/posse | ||
| internal | ||
| .dockerignore | ||
| .gitignore | ||
| compose.yaml | ||
| Dockerfile | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| README.md | ||
Posse
Posse — пересыльщик сообщений из источников (сейчас RSS/Atom/JsonFeed) в целевые сервисы (Телеграм или Макс).
При этом есть контроль дедупликации засчёт простого бинарного файла с уже обработанными сообщениями.
Запуск в Docker
- Создаём
config.jsonпо образцу ниже - Копируем
compose.yaml - Запускаем
docker compose up -d - Просмотр логов:
docker compose logs -f
Установка из исходников
Требования
- Go 1.25.0 или выше
Сборка
go install gitverse.ru/neonxp/posse@latest
Конфигурация
Конфигурационный файл
Основная конфигурация находится в файле config.json:
{
"db": {
"file": "/data/pose.db"
},
"sources": [
{
"enabled": true,
"feed": "https://neonxp.ru/feed/",
"scrape_interval": "2m"
}
],
"targets": {
"max": {
"enabled": true,
"token": "MAX_TOKEN",
"group": "-77459139486321",
"type": "max"
},
"telegram": {
"enabled": true,
"token": "TELEGRAM_TOKEN",
"group": "-1003888840756",
"type": "telegram",
"proxy": "socks5://proxyuser:proxypassword@proxyhost:1080"
}
}
}
Использование
Запуск
./pose [-config config.json] [-dry]
Флаги:
-configпозволяет указать путь к конфигурационному файлу (по умолчанию:config.json).-dryзапускает только парсинг source, запись в кеш, но не отправляет в цели (по умолчаниюfalse)
Архитектура
Компоненты
Application
Основной компонент, который координирует работу источников и целей:
- Создаёт и управляет источниками данных
- Создаёт и управляет целевыми каналами
- Распределяет элементы из источников по целям
- Управляет жизненным циклом приложения
Source (Источники)
Интерфейс для источников данных:
type Source interface {
Retrive(ctx context.Context) <-chan model.Item
}
Feed — реализация источника для RSS/Atom-лент:
- Периодически опрашивает указанный URL
- Парсит ленту с помощью библиотеки
gofeed - Отправляет элементы в общий канал
Target (Цели)
Интерфейс для целевых каналов:
type Target interface {
Send(ctx context.Context) chan<- model.Item
}
Telegram — реализация цели для Telegram:
- Получает элементы из канала
- Форматирует сообщение в HTML
- Санитайзирует HTML с помощью
bluemonday - Отправляет сообщение в указанный чат/канал
MAX — реализация цели для Telegram:
- Получает элементы из канала
- Форматирует сообщение в HTML
- Санитайзирует HTML с помощью
bluemonday - Отправляет сообщение в указанный чат/канал
Database
Простая база данных для дедупликации:
Exists(string) bool— проверяет, была ли уже обработана записьAppend(string) error— добавляет запись в базуClose() error— закрывает базу данных
База данных хранит ID обработанных элементов в текстовом файле (по одной записи на строку).
Model
Item — модель элемента ленты:
type Item struct {
ID string // Уникальный идентификатор
Date time.Time // Дата публикации
Title string // Заголовок
Summary string // Краткое описание
Link string // Ссылка на оригинал
Img string // URL изображения (опционально)
}
Метод BuildMessage() форматирует элемент в HTML-сообщение для последующей отправки.
Зависимости
github.com/mmcdole/gofeed— парсер RSS/Atom лентgithub.com/microcosm-cc/bluemonday— санитайзер HTMLgithub.com/max-messenger/max-bot-api-client-go- библиотека для Макс
Лицензия
Этот проект распространяется под лицензией GNU General Public License v3.0 (GPLv3).
Подробности см. в файле LICENSE.
Автор
Александр NeonXP Кирюхин — https://neonxp.ru i@neonxp.ru
Лицензия
Copyright (C) 2024 Alexander NeonXP Kiryukhin <i@neonxp.ru>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.