Compare commits

...

16 Commits
master ... docs

Author SHA1 Message Date
c379904d26
Пишу документацию
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-15 02:19:09 +03:00
06729e031d
Пишу документацию
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-14 02:11:04 +03:00
f01acf5d85
Настройка сайта документации 2023-03-13 23:01:25 +03:00
c334f159c9
Настройка сайта документации
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone Build is passing
2023-03-13 22:56:49 +03:00
5f883ca6da
Настройка сайта документации
Some checks failed
continuous-integration/drone/push Build is failing
2023-03-13 22:55:49 +03:00
08e9f8a8ab
Рефакторинг документации 2023-03-13 22:45:23 +03:00
ba7f6df62e
Рефакторинг документации
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-13 19:19:13 +03:00
2ad2f64dfb
Рефакторинг документации 2023-03-13 19:18:55 +03:00
cb9ae97cef
Рефакторинг документации
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-13 19:07:24 +03:00
71ff043a9a
Рефакторинг документации
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is passing
2023-03-13 18:49:49 +03:00
ff4db62d9c
Рефакторинг документации
Some checks failed
continuous-integration/drone/push Build is failing
2023-03-13 18:48:04 +03:00
666cf965ed
Рефакторинг документации
Some checks reported errors
continuous-integration/drone/push Build was killed
2023-03-13 18:45:36 +03:00
0508604290
Рефакторинг документации
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is failing
2023-03-13 18:33:50 +03:00
50feffd2c7
[maven-release-plugin] prepare for next development iteration
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-05 18:59:21 +03:00
0985765fbd
[maven-release-plugin] prepare release v.0.0.51 2023-03-05 18:59:21 +03:00
4d41a2375d
Добавил возможность задавать команды в бота
All checks were successful
continuous-integration/drone/push Build is passing
2023-03-05 18:10:41 +03:00
53 changed files with 661 additions and 306 deletions

View File

@ -97,45 +97,54 @@ steps:
- gpg --pinentry-mode loopback --passphrase $GPG_PASSPHRASE --import gpg.key
- mvn --settings maven-settings.xml -U -P ossrh,release-struchkov-nexus clean deploy
#---
#kind: pipeline
#type: docker
#name: create-docs-site
#
#trigger:
# branch:
# - docs
# - master
#
#steps:
# - name: build site
# image: upagge/mkdocs-material
# environment:
# SSH_DEPLOY_KEY:
# from_secret: SSH_DEPLOY_KEY
# SSH_DEPLOY_HOST:
# from_secret: SSH_DEPLOY_HOST
# SSH_DEPLOY_PORT:
# from_secret: SSH_DEPLOY_PORT
# SSH_DEPLOY_PATH:
# from_secret: SSH_DEPLOY_PATH
# SSH_DEPLOY_USER:
# from_secret: SSH_DEPLOY_USER
# commands:
# - eval $(ssh-agent -s)
# - mkdir -p ~/.ssh
# - echo "$SSH_DEPLOY_KEY" >> ~/.ssh/id_rsa
# - chmod 700 ~/.ssh
# - chmod 600 ~/.ssh/id_rsa
# - ssh-keyscan -p $SSH_DEPLOY_PORT $SSH_DEPLOY_HOST >> ~/.ssh/known_hosts
# - chmod 644 ~/.ssh/known_hosts
# - cd documentation
# - mkdocs build
# - mv site godfather-telegram
# - scp -r -P $SSH_DEPLOY_PORT ./godfather-telegram $SSH_DEPLOY_USER@$SSH_DEPLOY_HOST:$SSH_DEPLOY_PATH
---
kind: pipeline
type: docker
name: create-develop-docs-site
trigger:
branch:
- develop
- docs
clone:
disable: true
steps:
- name: build docs
image: git.struchkov.dev/upagge/mkdocs-material-insiders:latest
volumes:
- name: mkdocs_cache
path: ${DRONE_WORKSPACE}/documentation/ru/.cache
environment:
GIT_SSH:
from_secret: GIT_SSH
GIT_SSH_COMMAND: "ssh -i ~/.ssh/id_rsa -p 222"
commands:
- eval $(ssh-agent -s)
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- echo "$GIT_SSH" >> ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- ssh-keyscan -p 222 git.struchkov.dev >> ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
- git config --global user.name "${DRONE_COMMIT_AUTHOR_NAME}"
- git config --global user.email "${DRONE_COMMIT_AUTHOR_EMAIL}"
- git clone ${DRONE_GIT_SSH_URL} .
- git checkout $DRONE_COMMIT
- cd documentation/spring/ru
- mike deploy --prefix godfather-telegram/spring/ru --branch docs-deploy --push --update-aliases develop
image_pull_secrets:
- DOCKER_AUTH
volumes:
- name: mkdocs_cache
host:
path: /drone/volume/mkdocs_cache/godfather_telegram/spring/ru
---
kind: signature
hmac: bdeec02d3273fc1640c972d68cc52bffa2319ea53470d0c273f42125a1dec127
hmac: 6c79b5d92e5003205bd6ed78ab0b3258665406750751e97354b630ac34c8657e
...

3
.gitignore vendored
View File

@ -77,4 +77,5 @@ com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
/documentation/site/
/documentation/spring/ru/site/
/documentation/spring/ru/.cache/

View File

@ -1,10 +0,0 @@
# Hello Mutiny!
Once you made Mutiny available to your classpath, you can start writing code.
Let's start with this simple program:
## Test
### Test 2
## Test 3

View File

@ -1,122 +0,0 @@
---
hide:
- toc
---
# Варианты добавления в проект
Есть несколько вариантов добавить фреймворк в проект. Изучите их все и выберете подходящий под ваши задачи.
## Spring Boot Starter
Самый простой способ, если у вас небольшой монолитный Spring Boot проект.
=== ":simple-apachemaven: Maven"
```xml
<dependency>
<groupId>dev.struchkov.godfather.telegram</groupId>
<artifactId>telegram-bot-spring-boot-starter</artifactId>
<version>0.0.50-SNAPSHOT</version>
</dependency>
```
=== ":simple-gradle: Gradle"
``` c++
#include <iostream>
int main(void) {
std::cout << "Hello world!" << std::endl;
return 0;
}
```
## Quarkus Extension
На данный момент раздел находится в разработке.
=== ":simple-apachemaven: Maven"
```
```
=== ":simple-gradle: Gradle"
```
```
### Reactive
На данный момент раздел находится в разработке.
## Основные зависимости проекта
Вы можете добавить основные зависимости в свой проект и сконфигурировать его более тонко под ваши нужды. Однако для этого потребуется хорошее знание архитектуры проекта.
Этот вариант подойдет вам, если у вас используется микросервисная архитектура. Так как логично разделить стадии получения, обработки и отправки сообщений на разные сервисы.
Также этот вариант подойдет вам, если вы используете менее популярный фреймворк, так как основные зависимости написаны без привязки к какому-то конкретному фреймворку.
Всего основных зависимостей три:
=== ":simple-spring: Spring"
Эти зависимости подойдут вам, если вы используете SpringBoot 3.0.0+
=== ":simple-apachemaven: Maven"
``` xml title="Позволяет получать сообщения"
```
``` xml title="Содержит всю логику работы"
```
``` xml title="Позволяет отправлять сообщения"
```
=== ":simple-gradle: Gradle"
``` xml title="Позволяет получать сообщения"
```
``` xml title="Содержит всю логику работы"
```
``` xml title="Позволяет отправлять сообщения"
```
=== ":simple-quarkus: Quarkus"
Эти зависимости подойдут вам, если вы используете Quarkus 2.16.0+
=== ":simple-apachemaven: Maven"
``` xml title="Позволяет получать сообщения"
```
``` xml title="Содержит всю логику работы"
```
``` xml title="Позволяет отправлять сообщения"
```
=== ":simple-gradle: Gradle"
``` xml title="Позволяет получать сообщения"
```
``` xml title="Содержит всю логику работы"
```
``` xml title="Позволяет отправлять сообщения"
```

View File

@ -1,10 +0,0 @@
# Hello Mutiny!
Once you made Mutiny available to your classpath, you can start writing code.
Let's start with this simple program:
## Test
### Test 2
## Test 3

View File

@ -1,9 +0,0 @@
---
hide:
- navigation
- comments
title: Home
---
# Godfather Telegram Фреймворк для создания Telegram ботов

View File

@ -1,95 +0,0 @@
site_name: GodFather Telegram
site_url: https://docs.struchkov.dev/godfather-telegram/
repo_url: https://github.com/Godfather-Bots/telegram-bot
repo_name: Godfather-Bots/telegram-bot
copyright: Copyright &copy; 2018 - 2023 Struchkov Mark
#edit_uri: edit/master/documentation/docs
nav:
- 'index.md'
- 'Быстрый старт':
- 'getting-started/installing-dependencies.md'
- 'getting-started/configuration.md'
# - 'Гайды':
- 'Архитектура':
- 'architecture/concept.md'
# - 'ChangeLog':
theme:
name: material
custom_dir: overrides
language: ru
favicon: assets/favicon.ico
icon:
logo: simple/telegram
repo: fontawesome/brands/github
palette:
- scheme: default
primary: light blue
accent: indigo
toggle:
icon: material/brightness-7
name: Switch to dark mode
- scheme: slate
toggle:
icon: material/brightness-4
name: Switch to light mode
features:
- navigation.instant
- navigation.indexes
- navigation.sections
- navigation.tracking
- navigation.tabs
- navigation.tabs.sticky
- navigation.footer
- search
- search.suggest
- search.highlight
- content.action.edit
- content.code.copy
- toc.follow
plugins:
- social
- meta
- tags
- search:
lang: ru
- git-revision-date-localized:
enable_creation_date: true
markdown_extensions:
- toc:
permalink: true
toc_depth: 3
title: Содержание
- pymdownx.highlight:
anchor_linenums: true
- pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format
- pymdownx.snippets
- pymdownx.inlinehilite
- pymdownx.details
- pymdownx.smartsymbols
- pymdownx.betterem
- pymdownx.tabbed:
alternate_style: true
- pymdownx.emoji:
emoji_index: !!python/name:materialx.emoji.twemoji
emoji_generator: !!python/name:materialx.emoji.to_svg
extra:
generator: false
analytics:
provider: custom
property: foobar
version:
provider: mike
# alternate:
# - name: Русский
# link: /ru/
# lang: ru

View File

@ -0,0 +1,17 @@
=== ":simple-apachemaven: Maven"
``` xml
<!-- https://mvnrepository.com/artifact/dev.struchkov.godfather.telegram/telegram-bot-spring-boot-starter -->
<dependency>
<groupId>dev.struchkov.godfather.telegram</groupId>
<artifactId>telegram-bot-spring-boot-starter</artifactId>
<version>0.0.51</version>
</dependency>
```
=== ":simple-gradle: Gradle"
``` groovy
// https://mvnrepository.com/artifact/dev.struchkov.godfather.telegram/telegram-bot-spring-boot-starter
implementation 'dev.struchkov.godfather.telegram:telegram-bot-spring-boot-starter:0.0.51'
```

View File

@ -0,0 +1,59 @@
# Основная идея
Проект GodFather направлен на унификацию создания ботов для различных мессенджеров сетей.
## Юнит
Базовая сущность фреймворка. Юнит содержит в себе различные лямба выражения, которые встраиваются в процесс обработки сообщений. Именно в написании этих лямбд и заключается основная работа с библиотекой.
Есть несколько разных типов юнитов, подробнее о каждом читайте в отдельном разделе.
Юнит представляет собой некую конфигурацию, которая передается в обработчик юнита. У каждого типа юнита есть свой обработчик.
Юниты могут образовывать связный список, тем самым определяя дерево сценарий бота.
## Сценарий
Для понимания рассмотрим небольшой пример по схеме изображенной ниже. Так же небольшие примеры обработки есть в тестах.
![Типичный сценарий](img/scenario.png){ loading=lazy align=left }
Сценариями в данном случае являются:
* Unit1 —> Unit2 —> Unit5 —> Unit7 —> Unit9
* Unit1 —> Unit2 —> Unit6 —> Unit8;
* Unit1 —> Unit3 —> Unit6 —> Unit8;
* Unit1 —> Unit4 —> Unit9;
* Unit10.
Пользователь присылает боту свое первое сообщение, например, «Привет». Если сообщение удовлетворяет регулярному выражению или содержит необходимое количество ключевых слов Unit1, то возвращается Unit1, то же самое относится к Unit10.
Если оба юнита удовлетворяют запросу пользователя, то будет возвращен юнит с большим приоритетом (поле priority). Если приоритеты равны, то случайный Unit.
В нашем примере, на первое сообщение, пользователь получил Unit1, поэтому следующее сообщение пользователя будет ассоциироваться с множеством: Unit2, Unit3 и Unit4.
## Механизм выбора юнита
Пока сценарий линейный никакой необходимости в определении юнита нет. Однако, когда у вас на одном уровне находится несколько юнитов, то возникает необходимость выбрать юнит для последующей обработки сообщений. (1)
{ .annotate }
1. Обратимся к предыдущей схеме сценария. Как выбрать какой юнит обработать после обработки Unit 1?
Юниты обладают триггерами, которые сигнализируют о том, что данный юнит может обработать запрос от пользователя.
Механизм выбора можно описать несколькими этапами:
* Сначала проверяются триггеры у всех юнитов.
* Все юниты, триггеры которых сработали, являются потенциальными кандидатами на обработку
* Из этих юнитов выбирается юнит с наибольшим приоритетом. Если у них одинаковый приоритет, то выбирается случайный юнит.
Но как выбираются первые юниты (1) для обработки? В начале сценария стоят main юниты. Именно main юниты участвуют в первом раунде выбора обработчика. Чтобы создать main юнит, необходимо в аннотации `@Unit` установить параметр `main = true`.
{ .annotate }
1. На схеме это Unit 1 и Unit 2
Также существуют так называемые глобальные юниты, которые участвуют в каждом раунде выбора. Чтобы создать глобальный unit, необходимо в аннотации `@Unit` установить параметр `global = true`.

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

View File

@ -0,0 +1,16 @@
# Устройство юнитов
## Приоритет
## Триггеры
Позволяют указать при каком условии данный юнит будет выбран для обработки.
### `triggerCheck()`
Позволяет реализовать любую проверку. Принимает на вход `Predicate` с полученным сообщением.
### `triggerPhrase()`
## Ответ

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,3 @@
# Change.Log
## 1.0.0

View File

@ -0,0 +1,65 @@
# Hello GodFather
Начнем разработку бота с простого примера. Поздороваемся с пользователем.
## Регистрация бота
Сначала нужно зарегистрировать бота и получить токен в Telegram.
[:robot: Зарегистрировать бота](@BotFather){ .md-button }
## Зависимости
--8<-- ".dependencies.md"
## Конфигурация
Теперь необходимо указать данные для подключения к боту в Telegram.
``` yaml title="application.yml"
telegram:
bot:
username: username_bot
token: your_token
```
### Прокси
Если телеграм заблокирован у вашего хостера/провайдера, вы можете использовать прокси
``` yaml title="application.yml" hl_lines="5-11"
telegram:
bot:
username: username_bot
token: your_token
proxy:
enable: true
host: PROXY_HOST
port: PROXY_PORT
type: PROXY_TYPE
user: PROXY_USERNAME
password: PROXY_PASSWORD
```
## Первый юнит
Теперь создаем класс конфигурации юнитов и добавляем первый юнит (1).
{ .annotate }
1. Юниты это базовая сущность фреймворка
``` java
@Component
public class GeneralMenu implements UnitConfiguration {
@Unit(value = GENERAL_MENU, main = true)
public AnswerText<Mail> generalMenu() {
return AnswerText.<Mail>builder()
.answer(boxAnswer("Hello!"))
.build();
}
}
```
Вот и все, можете запустить ваше приложение и написать боту в телеграм. Если вы все сделали правильно, то он ответит вам.

View File

@ -0,0 +1,2 @@
# Безопасность

View File

@ -0,0 +1,36 @@
---
hide:
- comments
- navigation
---
# GodFather Bot - Фреймворк для создания Telegram ботов
Данный фреймворк обладает мощным API для создания диалоговых Telegram ботов.
!!! note ""
Данный фреймворк имеет версии как для SpringBoot :simple-spring:, так и для Quarkus Reactive :simple-quarkus:.
Посмотрите, как легко сделать Hello World:
``` java
@Component
public class GeneralMenu implements UnitConfiguration {
@Unit(value = GENERAL_MENU, main = true)
public AnswerText<Mail> generalMenu() {
return AnswerText.<Mail>builder()
.answer(boxAnswer("Hello, World!"))
.build();
}
}
```
## Добавляем зависимости
Чтобы начать, выберете свой сборщик вкладку и добавьте зависимости в проект.
--8<-- ".dependencies.md"

View File

@ -0,0 +1,77 @@
.md-typeset .admonition, .md-typeset details {
font-size: 0.75rem;
}
.md-typeset h1, .md-typeset h2 {
font-weight: 500;
}
.md-typeset h2 {
margin-top: 4rem;
}
.md-typeset h3 {
margin-top: 2.2rem;
}
.md-typeset mark {
background-color: #fff3bc;
margin: -4px -4px -6px;
padding: 4px 4px 6px;
}
@keyframes heart {
0%, 40%, 80%, 100% {
transform: scale(1);
}
20%, 60% {
transform: scale(1.15);
}
}
.heart {
animation: heart 1000ms infinite;
}
@keyframes ninja-disappear {
0% {
opacity: 1;
}
50% {
opacity: 0.3;
}
100% {
opacity: 1;
}
}
.ninja-disappear {
animation: ninja-disappear 3000ms infinite;
animation-delay: 1500ms;
}
@keyframes jingle-bell-swing {
0% {
transform: rotate(0deg);
}
50% {
transform: rotate(10deg);
}
100% {
transform: rotate(0deg);
}
}
.jingle-bell {
animation: jingle-bell-swing 2s ease-in-out infinite;
transform-origin: center;
}
@media(min-width: 768px) {
.frontpage-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
column-gap: 2em;
row-gap: 1em;
}
}

View File

@ -0,0 +1,26 @@
---
description: Спонсорская поддержка делает проект устойчивым, так как она окупает время сопровождающих этого проекта.
hide:
- comments
- navigation
---
# :heart:{ .heart } Поддержать разработку
Спонсорская поддержка делает проект устойчивым, так как она окупает время сопровождающих этого проекта - очень дефицитный ресурс, который тратится на разработку новых функций, исправление ошибок, повышение стабильности, решение проблем и общую поддержку. ==Самое большое узкое место в Open Source - это время.==
***
Вы можете выбрать любой удобный способ поддержки разработки:
- Банковская карта: [https://www.tinkoff.ru/cf/4iU6NB3uzqx](https://www.tinkoff.ru/cf/4iU6NB3uzqx)
- Крипта:
* BTC (Taproot): `bc1pt49vnp43c4mktk6309zlq3020dzd0p89gc8d90zzn4sgjvck56xs0t86vy`
* ETH: `0x7668C802Bd71Be965671D4Bbb1AD90C7f7f32921`
* USDT (ERC-20): `0x7668C802Bd71Be965671D4Bbb1AD90C7f7f32921`
* DAI (ERC-20): `0x7668C802Bd71Be965671D4Bbb1AD90C7f7f32921`
* BNB: `0xDa41aC95f606850f2E01ba775e521Cd385AA7D03`
* USD: `0xDa41aC95f606850f2E01ba775e521Cd385AA7D03`
* DAI: `0xDa41aC95f606850f2E01ba775e521Cd385AA7D03`

View File

@ -0,0 +1,135 @@
site_name: GodFather Telegram
site_url: https://docs.struchkov.dev/godfather-telegram/spring/ru
repo_url: https://github.com/Godfather-Bots/telegram-bot
repo_name: Godfather-Bots/telegram-bot
copyright: Copyright &copy; 2018 - 2023 Struchkov Mark
#edit_uri: edit/master/documentation/docs
nav:
- О проекте:
- index.md
- Конфигурация:
- Hello World!: getting-started/hello-godfather.md
- Юниты:
- architecture/unit.md
- architecture/unit/answer-text.md
- architecture/unit/answer-check.md
- Гайды:
- Безопасность: guides/security.md
- Циклическая зависимость: guides/cyclic.md
- Архитектура:
- Основная идея: architecture/general.md
- ChangeLog: changelog/index.md
- Поддержать: support-development.md
theme:
name: material
custom_dir: overrides
language: ru
favicon: assets/favicon.ico
icon:
logo: simple/telegram
repo: fontawesome/brands/github
palette:
- media: "(prefers-color-scheme)"
primary: light blue
accent: indigo
scheme: default
toggle:
icon: material/brightness-auto
name: Switch to light mode
- media: "(prefers-color-scheme: light)"
primary: light blue
accent: indigo
toggle:
icon: material/brightness-7
name: Switch to dark mode
- media: "(prefers-color-scheme: dark)"
scheme: slate
toggle:
icon: material/brightness-4
name: Switch to system preference
features:
- navigation.instant
- navigation.indexes
- navigation.sections
- navigation.tracking
- navigation.footer
- navigation.tabs
- navigation.tabs.sticky
- navigation.prune
- search
- search.suggest
- search.highlight
- content.action.edit
- content.code.copy
- content.code.annotate
- content.tooltips
- toc.follow
- toc.integrate
plugins:
- social
- typeset
# - blog:
# blog_toc: true
# post_date_format: short
# post_url_format: "{slug}"
# archive_toc: true
# categories: false
# authors: false
# - optimize:
# optimize_jpg_quality: 90
- tags
- search:
lang: ru
markdown_extensions:
- pymdownx.details
- pymdownx.superfences
- pymdownx.inlinehilite
- pymdownx.snippets:
auto_append:
- includes/abbreviations.md
- pymdownx.critic
- pymdownx.caret
- pymdownx.keys
- pymdownx.mark
- pymdownx.tilde
- attr_list
- def_list
- pymdownx.tasklist:
custom_checkbox: true
- pymdownx.highlight:
anchor_linenums: true
line_spans: __span
pygments_lang_class: true
- pymdownx.tabbed:
alternate_style: true
- pymdownx.emoji:
emoji_index: !!python/name:materialx.emoji.twemoji
emoji_generator: !!python/name:materialx.emoji.to_svg
- admonition
- abbr
- md_in_html
- footnotes
- toc:
toc_depth: 3
title: Содержание
permalink: ⚓︎
extra_css:
- stylesheets/extra.css
extra:
generator: false
analytics:
provider: custom
property: foobar
version:
provider: mike
# alternate:
# - name: Русский
# link: /ru/
# lang: ru

View File

@ -4,7 +4,7 @@
<groupId>dev.struchkov.godfather.telegram</groupId>
<artifactId>telegram-bot</artifactId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>

View File

@ -4,7 +4,7 @@
<parent>
<artifactId>telegram-bot</artifactId>
<groupId>dev.struchkov.godfather.telegram</groupId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<artifactId>telegram-consumer</artifactId>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>dev.struchkov.godfather.telegram</groupId>
<artifactId>telegram-consumer</artifactId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<artifactId>telegram-consumer-main</artifactId>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>dev.struchkov.godfather.telegram</groupId>
<artifactId>telegram-consumer</artifactId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<artifactId>telegram-consumer-quarkus</artifactId>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>dev.struchkov.godfather.telegram</groupId>
<artifactId>telegram-consumer</artifactId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<artifactId>telegram-consumer-simple</artifactId>

View File

@ -4,7 +4,7 @@
<parent>
<artifactId>telegram-bot</artifactId>
<groupId>dev.struchkov.godfather.telegram</groupId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<artifactId>telegram-context</artifactId>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>dev.struchkov.godfather.telegram</groupId>
<artifactId>telegram-context</artifactId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<artifactId>telegram-context-main</artifactId>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>dev.struchkov.godfather.telegram</groupId>
<artifactId>telegram-context</artifactId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<artifactId>telegram-context-quarkus</artifactId>

View File

@ -1,9 +1,12 @@
package dev.struchkov.godfather.telegram.quarkus.context.service;
import dev.struchkov.godfather.telegram.domain.ChatAction;
import dev.struchkov.godfather.telegram.domain.ClientBotCommand;
import io.smallrye.mutiny.Uni;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
public interface TelegramService {
Uni<Void> executeAction(@NotNull String personId, ChatAction chatAction);
@ -12,4 +15,6 @@ public interface TelegramService {
Uni<Void> unPinMessage(@NotNull String personId, @NotNull String messageId);
Uni<Void> addCommand(@NotNull Collection<ClientBotCommand> botCommands);
}

View File

@ -4,7 +4,7 @@
<parent>
<artifactId>telegram-context</artifactId>
<groupId>dev.struchkov.godfather.telegram</groupId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<artifactId>telegram-context-simple</artifactId>

View File

@ -1,8 +1,11 @@
package dev.struchkov.godfather.telegram.simple.context.service;
import dev.struchkov.godfather.telegram.domain.ClientBotCommand;
import dev.struchkov.godfather.telegram.domain.ChatAction;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
public interface TelegramService {
void executeAction(@NotNull String personId, ChatAction chatAction);
@ -11,4 +14,6 @@ public interface TelegramService {
void unPinMessage(@NotNull String personId, @NotNull String messageId);
void addCommand(@NotNull Collection<ClientBotCommand> botCommands);
}

View File

@ -4,7 +4,7 @@
<parent>
<groupId>dev.struchkov.godfather.telegram</groupId>
<artifactId>telegram-bot</artifactId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<modules>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>dev.struchkov.godfather.telegram</groupId>
<artifactId>telegram-core</artifactId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<artifactId>telegram-core-main</artifactId>

View File

@ -4,7 +4,7 @@
<parent>
<artifactId>telegram-core</artifactId>
<groupId>dev.struchkov.godfather.telegram</groupId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<artifactId>telegram-core-quarkus</artifactId>

View File

@ -1,22 +1,36 @@
package dev.struchkov.godfather.telegram.quarkus.core.service;
import dev.struchkov.godfather.telegram.domain.ChatAction;
import dev.struchkov.godfather.telegram.domain.ClientBotCommand;
import dev.struchkov.godfather.telegram.main.context.TelegramConnect;
import dev.struchkov.godfather.telegram.quarkus.context.service.TelegramService;
import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.Uni;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.telegram.telegrambots.meta.api.methods.ActionType;
import org.telegram.telegrambots.meta.api.methods.commands.SetMyCommands;
import org.telegram.telegrambots.meta.api.methods.pinnedmessages.PinChatMessage;
import org.telegram.telegrambots.meta.api.methods.pinnedmessages.UnpinChatMessage;
import org.telegram.telegrambots.meta.api.methods.send.SendChatAction;
import org.telegram.telegrambots.meta.api.objects.commands.BotCommand;
import org.telegram.telegrambots.meta.bots.AbsSender;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.stream.Collectors;
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
import static dev.struchkov.haiti.utils.Checker.checkNull;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toList;
public class TelegramServiceImpl implements TelegramService {
@ -58,6 +72,58 @@ public class TelegramServiceImpl implements TelegramService {
.replaceWithVoid();
}
@Override
public Uni<Void> addCommand(@NotNull Collection<ClientBotCommand> botCommands) {
return Uni.combine().all()
.unis(
Uni.createFrom().item(
botCommands.stream()
.filter(command -> checkNotNull(command.getLang()))
.collect(
Collectors.groupingBy(
ClientBotCommand::getLang,
mapping(clientCommand -> BotCommand.builder().command(clientCommand.getKey()).description(clientCommand.getDescription()).build(), toList())
)
)
),
Uni.createFrom().item(
botCommands.stream()
.filter(command -> checkNull(command.getLang()))
.map(clientCommand -> BotCommand.builder().command(clientCommand.getKey()).description(clientCommand.getDescription()).build())
.toList()
)
).asTuple()
.call(t -> {
final List<BotCommand> noLangCommands = t.getItem2();
if (checkNotEmpty(noLangCommands)) {
return Uni.createFrom().completionStage(
getExecuteAsync(
SetMyCommands.builder().commands(noLangCommands).build()
)
);
}
return Uni.createFrom().voidItem();
})
.call(t -> {
final Map<String, List<BotCommand>> commandMap = t.getItem1();
return Multi.createFrom().iterable(commandMap.entrySet())
.call(entry -> Uni.createFrom().completionStage(getExecuteAsync(SetMyCommands.builder().languageCode(entry.getKey()).commands(entry.getValue()).build())))
.collect().asList().replaceWithVoid();
})
.replaceWithVoid();
}
private CompletableFuture<Boolean> getExecuteAsync(SetMyCommands myCommands) {
try {
return absSender.executeAsync(myCommands);
} catch (TelegramApiRequestException e) {
log.error(e.getApiResponse());
} catch (TelegramApiException e) {
log.error(e.getMessage());
}
return CompletableFuture.completedFuture(null);
}
private CompletableFuture<Boolean> getExecuteAsync(UnpinChatMessage unpinChatMessage) {
try {
return absSender.executeAsync(unpinChatMessage);

View File

@ -4,7 +4,7 @@
<parent>
<groupId>dev.struchkov.godfather.telegram</groupId>
<artifactId>telegram-core</artifactId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<artifactId>telegram-core-simple</artifactId>

View File

@ -1,19 +1,33 @@
package dev.struchkov.godfather.telegram.simple.core.service;
import dev.struchkov.godfather.telegram.domain.ChatAction;
import dev.struchkov.godfather.telegram.domain.ClientBotCommand;
import dev.struchkov.godfather.telegram.main.context.TelegramConnect;
import dev.struchkov.godfather.telegram.simple.context.service.TelegramService;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.telegram.telegrambots.meta.api.methods.ActionType;
import org.telegram.telegrambots.meta.api.methods.commands.SetMyCommands;
import org.telegram.telegrambots.meta.api.methods.pinnedmessages.PinChatMessage;
import org.telegram.telegrambots.meta.api.methods.pinnedmessages.UnpinChatMessage;
import org.telegram.telegrambots.meta.api.methods.send.SendChatAction;
import org.telegram.telegrambots.meta.api.objects.commands.BotCommand;
import org.telegram.telegrambots.meta.bots.AbsSender;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
import static dev.struchkov.haiti.utils.Checker.checkNull;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toList;
public class TelegramServiceImpl implements TelegramService {
private static final Logger log = LoggerFactory.getLogger(TelegramServiceImpl.class);
@ -29,6 +43,7 @@ public class TelegramServiceImpl implements TelegramService {
final SendChatAction sendChatAction = new SendChatAction();
sendChatAction.setChatId(personId);
sendChatAction.setAction(ActionType.valueOf(chatAction.name()));
try {
absSender.execute(sendChatAction);
} catch (TelegramApiRequestException e) {
@ -66,4 +81,35 @@ public class TelegramServiceImpl implements TelegramService {
}
}
@Override
public void addCommand(@NotNull Collection<ClientBotCommand> botCommands) {
final Map<String, List<BotCommand>> commandMap = botCommands.stream()
.filter(command -> checkNotNull(command.getLang()))
.collect(
Collectors.groupingBy(
ClientBotCommand::getLang,
mapping(clientCommand -> BotCommand.builder().command(clientCommand.getKey()).description(clientCommand.getDescription()).build(), toList())
)
);
final List<@NotNull BotCommand> noLangCommands = botCommands.stream()
.filter(command -> checkNull(command.getLang()))
.map(clientCommand -> BotCommand.builder().command(clientCommand.getKey()).description(clientCommand.getDescription()).build())
.toList();
try {
if (checkNotEmpty(noLangCommands)) {
absSender.execute(SetMyCommands.builder().commands(noLangCommands).build());
}
for (Map.Entry<String, List<BotCommand>> entry : commandMap.entrySet()) {
absSender.execute(SetMyCommands.builder().languageCode(entry.getKey()).commands(entry.getValue()).build());
}
} catch (TelegramApiRequestException e) {
log.error(e.getApiResponse());
} catch (TelegramApiException e) {
log.error(e.getMessage());
}
}
}

View File

@ -4,7 +4,7 @@
<parent>
<groupId>dev.struchkov.godfather.telegram</groupId>
<artifactId>telegram-bot</artifactId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<artifactId>telegram-domain</artifactId>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>dev.struchkov.godfather.telegram</groupId>
<artifactId>telegram-domain</artifactId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<artifactId>telegram-domain-main</artifactId>

View File

@ -0,0 +1,33 @@
package dev.struchkov.godfather.telegram.domain;
public class ClientBotCommand {
private String key;
private String description;
private String lang;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getLang() {
return lang;
}
public void setLang(String lang) {
this.lang = lang;
}
}

View File

@ -4,7 +4,7 @@
<parent>
<groupId>dev.struchkov.godfather.telegram</groupId>
<artifactId>telegram-domain</artifactId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<artifactId>telegram-domain-quarkus</artifactId>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>dev.struchkov.godfather.telegram</groupId>
<artifactId>telegram-domain</artifactId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<artifactId>telegram-domain-simple</artifactId>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>dev.struchkov.godfather.telegram</groupId>
<artifactId>telegram-bot</artifactId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<artifactId>telegram-sender</artifactId>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>dev.struchkov.godfather.telegram</groupId>
<artifactId>telegram-sender</artifactId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<artifactId>telegram-sender-main</artifactId>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>dev.struchkov.godfather.telegram</groupId>
<artifactId>telegram-sender</artifactId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<artifactId>telegram-sender-quarkus</artifactId>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>dev.struchkov.godfather.telegram</groupId>
<artifactId>telegram-sender</artifactId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<artifactId>telegram-sender-simple</artifactId>

View File

@ -4,7 +4,7 @@
<parent>
<groupId>dev.struchkov.godfather.telegram</groupId>
<artifactId>telegram-bot</artifactId>
<version>0.0.51-SNAPSHOT</version>
<version>0.0.52-SNAPSHOT</version>
</parent>
<artifactId>telegram-simple</artifactId>