Enhanced Java telegram bots runner built on top of the Telegram Bots library.
@tgbotsmodulebot (source code)
Add gradle dependency:
implementation 'com.annimon:tgbots-module:7.10.0'
Or if you don't want to use webhooks:
implementation ('com.annimon:tgbots-module:7.10.0') {
exclude group: 'org.telegram', module: 'telegrambots-webhook'
}
BotModule
interface:public class TestBot implements BotModule {
@Override
public BotHandler botHandler(Config config) {
return new TestBotHandler();
}
}
public class TestBot implements BotModule {
public static void main(String[] args) {
final var profile = (args.length >= 1) ? args[0] : "";
Runner.run(profile, List.of(new TestBot()));
}
// ...
}
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.validation.constraints.NotBlank;
@Data
public class BotConfig {
@NotBlank
@JsonProperty(required = true)
private String token;
@NotBlank
@JsonProperty(required = true)
private String username;
}
testbot.yaml
token: 123456789:ABCDEFGHIJKLM_NOPQRSTUVWXYZ01234567
username: bot
public class TestBot implements BotModule {
// ...
@Override
public BotHandler botHandler(Config config) {
final var configLoader = new YamlConfigLoaderService();
final var configFile = configLoader.configFile("testbot", config.getProfile());
final var botConfig = configLoader.loadFile(configFile, BotConfig.class);
final var botModuleOptions = BotModuleOptions.createDefault(botConfig.getToken());
return new TestBotHandler(botModuleOptions, botConfig);
}
}
config.yaml
(See Webhooks examples):log-level: FINE
webhook:
enabled: false
port: env(PORT:8443)
externalUrl: https://123.45.67.890:$port
internalUrl: http://0.0.0.0:$port
keystorePath: cert/keystore.jks
keystorePassword: env(KEYSTORE_PASSWORD)
modules:
- com.annimon.testbot.TestBot
public class TestBotHandler extends BotHandler {
private final BotConfig botConfig;
public TestBotHandler(BotModuleOptions botModuleOptions, BotConfig botConfig) {
super(botModuleOptions);
this.botConfig = botConfig;
}
@Override
public BotApiMethod<?> onUpdate(@NotNull Update update) {
// your code here
return null;
}
}
Now you can easily switch between webhook and long polling methods by changing the webhook:
enabled
flag in config,yaml
.
Or you can create config-test.yaml
and run the test
profile:
java -cp tgbots-module.jar:testbot.jar:yourfavoritebot.jar com.annimon.telegrambots.Runner test
Heroku starts on a random port, you can get a value from the environment property PORT
:
webhook:
enabled: true
port: env(PORT)
externalUrl: https://yourappname.herokuapp.com
internalUrl: http://0.0.0.0:$port
Use certgen.sh
to generate a certificate (replace SERVERIPADDRESS
with the server's IP address):
JKS=keystore.jks
CERT=public_cert.pem
openssl req -newkey rsa:2048 -sha256 -nodes \
-keyout private.key -x509 \
-days 365 \
-out $CERT \
-subj "/C=US/ST=Utah/L=Location/O=Organization/CN=SERVERIPADDRESS"
openssl pkcs12 -export \
-in $CERT \
-inkey private.key \
-certfile $CERT \
-out keystore.p12
keytool -importkeystore \
-srckeystore keystore.p12 \
-srcstoretype pkcs12 \
-sigalg SHA1withRSA \
-destkeystore $JKS \
-deststoretype pkcs12
rm keystore.p12 private.key
The keystore password will be asked several times during the generation of the certificate. Don't forget to export
it:
export KEYSTORE_PASSWORD=mysupersecretpasswordis123456
Specify generated keystore.jks
and public_cert.pem
paths and your SERVERIPADDRESS
in config.yaml
:
webhook:
enabled: true
port: 8443
externalUrl: https://SERVERIPADDRESS:$port
internalUrl: http://0.0.0.0:$port
keystorePath: cert/keystore.jks
keystorePassword: env(KEYSTORE_PASSWORD)
certificatePublicKeyPath: cert/public_cert.pem