Skip to content

Commit

Permalink
feature: add code examples and add autoSessionStart property (#30)
Browse files Browse the repository at this point in the history
* feature: add code examples and add autoSessionStart property
  • Loading branch information
Drednote authored Jan 21, 2025
1 parent 9f9af42 commit c588b14
Show file tree
Hide file tree
Showing 45 changed files with 1,010 additions and 37 deletions.
19 changes: 0 additions & 19 deletions .gitlab-ci.yml

This file was deleted.

9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ dependencies {

## Usage

### Examples

Code examples you can find in the example's folder.

### Quick Start

Add to `application.yml` your bot token and specify the name of bot
Expand Down Expand Up @@ -662,7 +666,7 @@ All settings tables contain 4 columns:

| Name | Description | Default Value | Required |
|---------------|-------------------------------------------|----------------------------------------------------------|----------|
| enabled | Enable the bot. | true | false |
| enabled | Enable the bot. | true | true |
| name | The name of a bot. Example: TheBestBot. | | false |
| token* | The token of a bot. | <b>must be set by user</b> | true |
| defaultLocale | The default locale for sending responses. | - | false |
Expand All @@ -684,6 +688,7 @@ All settings tables contain 4 columns:
| proxyUrl | The proxy url in format `host:port` or if auth needed `host:port:username:password`. | - | false |
| cacheLiveDuration | Cache lifetime used in `DefaultTelegramBotSession` | 1 | true |
| cacheLiveDurationUnit | The `TimeUnit` which will be applied to `cacheLiveDuration` | hours | true |
| autoSessionStart | Automatically start session when spring context loaded. | true | true |
| longPolling | LongPolling properties. | [LongPolling properties](#Longpolling-properties) | false |

#### LongPolling properties
Expand All @@ -703,7 +708,7 @@ Additional docs <a href="https://core.telegram.org/bots/api">Telegram API docs</
| controllerEnabled | Enabled controller update handling. | true | true |
| scenarioEnabled | Enabled scenario update handling. | true | true |
| setDefaultErrorAnswer | If an exception occurs and no handler processes it, set InternalErrorTelegramResponse as response. | true | true |
| scenarioLockMs | The time that scenario executor will wait if a concurrent interaction was performed. 0 - no limit. | 0 | false |
| scenarioLockMs | The time that scenario executor will wait if a concurrent interaction was performed. 0 - no limit. | 0 | true |
| serializeJavaObjectWithJackson | Whether to serialize Java POJO objects with Jackson to JSON in GenericTelegramResponse. | true | true |
| enabledWarningForScenario | Throws an error with a warning about using scenario safe only when getMaxThreadsPerUser is set to 1, if value set to different value | true | true |

Expand Down
6 changes: 6 additions & 0 deletions examples/controllers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Useful code for controllers and other

### Content:

- Controllers with callbacks
- Logging filter with telegram scope
44 changes: 44 additions & 0 deletions examples/controllers/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.3'
id 'io.spring.dependency-management' version '1.1.0'
}

group = 'io.github.drednote.examples'
version = ''

repositories {
mavenCentral()
}

dependencies {
// change line below to "implementation 'io.github.drednote:spring-boot-starter-telegram:<version>'" if you will start standalone project
implementation(parent.parent)
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'

// need for scenario persister
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation "org.postgresql:postgresql:42.7.4"

testCompileOnly 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'com.h2database:h2:2.3.232'
}

dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:2023.0.3"
}
resolutionStrategy {
cacheDynamicVersionsFor 5, 'minutes'
cacheChangingModulesFor 0, 'minutes'
}
}

test {
useJUnitPlatform()
}
1 change: 1 addition & 0 deletions examples/controllers/settings.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rootProject.name = 'spring-boot-starter-telegram-examples-controllers'
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.github.drednote.examples;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package io.github.drednote.examples.controller;

import io.github.drednote.telegram.core.annotation.TelegramCommand;
import io.github.drednote.telegram.core.annotation.TelegramController;
import io.github.drednote.telegram.core.request.UpdateRequest;
import lombok.RequiredArgsConstructor;
import org.telegram.telegrambots.meta.api.methods.send.SendChatAction;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@TelegramController
@RequiredArgsConstructor
public class CallbackController {

@TelegramCommand("/callback")
public Flux<Object> onCallback(UpdateRequest updateRequest) {
Mono<SendChatAction> typing = Mono.just(SendChatAction.builder()
.chatId(updateRequest.getChatId())
.action(ChatActionType.TYPING.getValue())
.build());

// create callback that will be executed when a long process is finished
Mono<String> callback = Mono.defer(() -> {
try {
// imitate a long process
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return Mono.just("Hello World");
});

return Flux.merge(typing, callback);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.github.drednote.examples.controller;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum ChatActionType {
TYPING("typing");

private final String value;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package io.github.drednote.examples.filter;

import io.github.drednote.telegram.core.annotation.TelegramScope;
import io.github.drednote.telegram.core.request.UpdateRequest;
import io.github.drednote.telegram.filter.post.ConclusivePostUpdateFilter;
import io.github.drednote.telegram.filter.pre.PriorityPreUpdateFilter;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.telegram.telegrambots.meta.api.objects.User;

@Slf4j
@Component
@RequiredArgsConstructor
@TelegramScope
public class LoggingFilter implements PriorityPreUpdateFilter, ConclusivePostUpdateFilter {

private LocalDateTime startTime;

@SneakyThrows
@Override
public void preFilter(@NonNull UpdateRequest request) {
startTime = LocalDateTime.now();
User user = request.getUser();
String userName = user != null ? user.getId() + " - " + user.getUserName() : null;
log.info(
"New request with id {} for userId {}", request.getId(), userName
);
}

@SneakyThrows
@Override
public void postFilter(@NonNull UpdateRequest request) {
if (startTime != null) {
User user = request.getUser();
log.info(
"Request with id {} for userId {} processed for {} ms", request.getId(),
user != null ? user.getId() : null,
ChronoUnit.MILLIS.between(startTime, LocalDateTime.now())
);
}
}

@Override
public int getPreOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}

30 changes: 30 additions & 0 deletions examples/controllers/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
spring:
main:
web-application-type: servlet
application:
name: assistant-bot
jpa:
database: POSTGRESQL
generate-ddl: true
hibernate:
ddl-auto: update
properties:
hibernate:
enable_lazy_load_no_trans: true
dialect: org.hibernate.dialect.PostgreSQLDialect
show_sql: false
format_sql: true
database-platform: org.hibernate.dialect.PostgreSQLDialect
datasource:
url: jdbc:postgresql://localhost:5432/telegram_starter
username: postgres
password: password
driver-class-name: org.postgresql.Driver
hikari:
maximum-pool-size: 30
connection-timeout: 30000
minimum-idle: 3

drednote:
telegram:
token: ${BOT_TOKEN}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.github.drednote.examples;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;

@SpringBootTest
public class ApplicationTest {

@Autowired
private ApplicationContext applicationContext;

@Test
public void contextLoads() {
assertThat(applicationContext).isNotNull();
}
}
14 changes: 14 additions & 0 deletions examples/controllers/src/test/resources/application.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
drednote:
telegram:
token: test
session:
auto-session-start: false

spring:
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1;NON_KEYWORDS=KEY,VALUE
jpa:
properties:
hibernate:
dialect: org.hibernate.dialect.H2Dialect
1 change: 1 addition & 0 deletions examples/get-started/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Code from 'Get-started' section of main README
32 changes: 32 additions & 0 deletions examples/get-started/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.3'
id 'io.spring.dependency-management' version '1.1.0'
}

group = 'io.github.drednote.examples'
version = ''

repositories {
mavenCentral()
}

dependencies {
// change line below to "implementation 'io.github.drednote:spring-boot-starter-telegram:<version>'" if you will start standalone project
implementation(parent.parent)
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:2023.0.3"
}
resolutionStrategy {
cacheDynamicVersionsFor 5, 'minutes'
cacheChangingModulesFor 0, 'minutes'
}
}

test {
useJUnitPlatform()
}
1 change: 1 addition & 0 deletions examples/get-started/settings.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rootProject.name = 'spring-boot-starter-telegram-examples-get-started'
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.github.drednote.examples;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package io.github.drednote.examples.controller;

import io.github.drednote.telegram.core.annotation.TelegramCommand;
import io.github.drednote.telegram.core.annotation.TelegramController;
import io.github.drednote.telegram.core.annotation.TelegramMessage;
import io.github.drednote.telegram.core.annotation.TelegramPatternVariable;
import io.github.drednote.telegram.core.annotation.TelegramRequest;
import io.github.drednote.telegram.core.request.UpdateRequest;
import io.github.drednote.telegram.response.GenericTelegramResponse;
import io.github.drednote.telegram.response.TelegramResponse;
import org.telegram.telegrambots.meta.api.objects.User;

@TelegramController
public class MainController {

@TelegramCommand("/start")
public String onStart(User user) {
return "Hello " + user.getFirstName();
}

@TelegramMessage
public String onMessage(UpdateRequest request) {
return "You sent message with types %s".formatted(request.getMessageTypes());
}

@TelegramMessage("My name is {name:.*}")
public String onPattern(@TelegramPatternVariable("name") String name) {
return "Hello " + name;
}

@TelegramRequest
public TelegramResponse onAll(UpdateRequest request) {
return new GenericTelegramResponse("Unsupported command");
}
}
3 changes: 3 additions & 0 deletions examples/get-started/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
drednote:
telegram:
token: ${BOT_TOKEN}
Loading

0 comments on commit c588b14

Please sign in to comment.