Spring Boot Telegram bot无法通过Java中的webhook工作

rsaldnfx  于 2023-03-29  发布在  Spring
关注(0)|答案(1)|浏览(177)

我正在创建telegram-bot。当我使用longpolling-bot时,它可以正常工作,但我不能创建在webhooks上工作的bot- http-request不会到达在telegraph中注册为webhook-url的端点。
对于本地部署,我使用ngrok应用程序。我尝试使用Postman发送POST请求,它模拟来自telegram-server的http请求,但请求没有到达方法org.telegram.telegrambots.updatesreceivers.RestApi::updateReceived
这是密码:
build.gradle

plugins {
    id "java"
    id "org.springframework.boot" version "3.0.1"
    id "io.spring.dependency-management" version "1.1.0"
}

repositories {
    mavenCentral()
    mavenLocal()
}

group 'com.example'
sourceCompatibility = JavaVersion.VERSION_17

def telegramBotVersion = "6.3.0"

dependencies {

    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'

    implementation 'org.springframework.boot:spring-boot-starter'

    implementation "org.telegram:telegrambots-spring-boot-starter:$telegramBotVersion"
    implementation "org.telegram:telegrambotsextensions:$telegramBotVersion"

    implementation 'javax.ws.rs:javax.ws.rs-api:2.0-m08'
    implementation 'javax.xml.bind:jaxb-api:2.4.0-b180830.0359'

}
package com.example.telegram.bot;

import com.example.telegram.service.TelegramService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.telegram.telegrambots.extensions.bots.commandbot.TelegramWebhookCommandBot;
import org.telegram.telegrambots.meta.api.objects.Update;

@Slf4j
public class WebhookBot extends TelegramWebhookCommandBot {

    private final String name;

    private final String token;

    public WebhookBot(String name, String token) {
        this.name = name;
        this.token = token;
    }

    @Autowired
    private TelegramService telegramService;

    @Override
    public String getBotUsername() {
        return name;
    }

    @Override
    public String getBotToken() {
        return token;
    }

    @Override
    public String getBotPath() {
        return "webhookurl";
    }

    @Override
    public void processNonCommandUpdate(Update update) {
        System.out.println("processNonCommandUpdate");
    }
}
package com.example.telegram.config;

import com.example.telegram.bot.WebhookBot;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.telegram.telegrambots.bots.TelegramWebhookBot;
import org.telegram.telegrambots.meta.TelegramBotsApi;
import org.telegram.telegrambots.meta.api.methods.updates.SetWebhook;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException;
import org.telegram.telegrambots.updatesreceivers.DefaultBotSession;
import org.telegram.telegrambots.updatesreceivers.DefaultWebhook;

@Configuration
@Profile("webhook")
@Slf4j
public class WebHookBotConfig {

    @Value("${telegram.bot.name}")
    private String name; //bot-name

    @Value("${telegram.bot.token}")
    private String token; //bot-token

    @Value("${telegram.bot.webhook.uri}")
    private String webhookUri; // https://7b66-188-130-157-6.eu.ngrok.io/ for example

    @Value("${telegram.bot.webhook.internalUrl}")
    private String internalWebServerUrl; // http://localhost:8080

    @Bean
    public TelegramWebhookBot telegramWebhookBot() throws TelegramApiException {

        DefaultWebhook defaultWebhook = new DefaultWebhook();
        defaultWebhook.setInternalUrl(internalWebServerUrl);

        TelegramBotsApi botsApi = new TelegramBotsApi(DefaultBotSession.class, defaultWebhook);

        WebhookBot telegramBot = new WebhookBot(name, token);

        SetWebhook setWebhook = new SetWebhook();
        setWebhook.setUrl(webhookUri);

        botsApi.registerBot(telegramBot, setWebhook);
        
        return telegramBot;
    }

}
./ngrok http 8080
hjzp0vay

hjzp0vay1#

我也想知道这个问题,我花了一个小时才找到解决办法。
下面是我的解决方案:
您需要创建Web控制器

@RestController
@Validated
public class WebhookController {

    private final WebhookBot webHookBot;

    @Autowired
    public WebhookController(WebhookBot webHookBot) {
        this.webHookBot = webHookBot;
    }

    @GetMapping("/")
    public ResponseEntity<?> main() {
        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).build();
    }

    @PostMapping("/callback")
    public ResponseEntity<?> onUpdateReceived(@RequestBody Update update, @RequestHeader(HttpHeaders.TELEGRAM_SECRET_TOKEN) String secretToken) {
        if (!secretToken.equals(Config.getSecretToken())) {
            System.out.println("Кто-то попытался нас взломать :)");
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
        } else {
            webHookBot.onWebhookUpdateReceived(update);
            return ResponseEntity.status(HttpStatus.OK).build();
        }
    }
}

然后你需要重做你的WebhookBot类

@Service
public class WebhookBot extends TelegramWebhookBot {

    private final UpdateController updateController;

    @Autowired
    public CoreBot(UpdateController updateController) throws TelegramApiException {
        super(Config.getToken()); //Передаем токен Бота
        this.updateController = updateController;
        registerBot();
    }

    @Override
    public BotApiMethod<?> onWebhookUpdateReceived(Update update) {
        updateController.processUpdate(update);
        return null;
    }

    @Override
    public String getBotPath() {
        return "";
    }

    private void registerBot() throws TelegramApiException {
        SetWebhook setWebhook = SetWebhook.builder()
                .url(Config.getWebhookUrl())
                .secretToken(Config.getSecretToken())
                .build();

        Webhook webhook = new DefaultWebhook();
        this.onRegister();
        webhook.registerWebhook(this);
        this.setWebhook(setWebhook);
    }

    @Override
    public String getBotUsername() {
        return Config.getUsername();
    }

    @PostConstruct
    public void init() {
        updateController.registerBot(this);
    }

我用了我的实现一点。但是你可以为自己重做。我希望我的解决方案是一个很好的实践
友情链接:https://github.com/pengrad/java-telegram-bot-api

相关问题