{"id":20312538,"url":"https://github.com/annimon/tgbots-module","last_synced_at":"2025-04-11T16:51:18.646Z","repository":{"id":43201812,"uuid":"145885852","full_name":"aNNiMON/tgbots-module","owner":"aNNiMON","description":"Enhanced Java telegram bots runner built on top of the Telegram Bots library","archived":false,"fork":false,"pushed_at":"2024-12-02T17:01:42.000Z","size":578,"stargazers_count":15,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-25T12:53:34.049Z","etag":null,"topics":["java","java-library","telegram","telegram-bot","webhook"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aNNiMON.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-23T17:23:05.000Z","updated_at":"2025-03-12T19:31:45.000Z","dependencies_parsed_at":"2024-09-07T18:49:14.367Z","dependency_job_id":"02def1bd-d91b-4641-af69-84b1f97ff875","html_url":"https://github.com/aNNiMON/tgbots-module","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aNNiMON%2Ftgbots-module","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aNNiMON%2Ftgbots-module/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aNNiMON%2Ftgbots-module/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aNNiMON%2Ftgbots-module/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aNNiMON","download_url":"https://codeload.github.com/aNNiMON/tgbots-module/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248442997,"owners_count":21104314,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","java-library","telegram","telegram-bot","webhook"],"created_at":"2024-11-14T18:06:38.090Z","updated_at":"2025-04-11T16:51:18.636Z","avatar_url":"https://github.com/aNNiMON.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tgbots-module\n\nEnhanced Java telegram bots runner built on top of the [Telegram Bots](https://github.com/rubenlagus/TelegramBots) library.\n\n## Why?\n\n - I want separate projects per bots.\n - I want to easily switch between long polling and webhook methods without recompiling the application.\n - I want to easily disable bots without recompiling the application.\n - I want yaml configs to store bot tokens and other data.\n - I want different profiles for configs.\n - I want command system with roles support.\n - I want localization support.\n\n## Example\n\n [@tgbotsmodulebot](https://t.me/tgbotsmodulebot) ([source code](https://github.com/annimon-tutorials/tgbotsmodule-webhook-bot))\n\n \n## Usage\n \n - Add gradle dependency:\n \n    ```groovy\n    implementation 'com.annimon:tgbots-module:8.0.0'\n    ```\n\n- Or if you don't want to use webhooks:\n\n    ```groovy\n    implementation ('com.annimon:tgbots-module:8.0.0') {\n        exclude group: 'org.telegram', module: 'telegrambots-webhook'\n    }\n    ```\n\n - Implement `BotModule` interface:\n \n    ```java\n    public class TestBot implements BotModule {   \n       @Override\n       public BotHandler botHandler(Config config) {\n           return new TestBotHandler();\n       }\n    }\n    ```\n \n - _[Optional]_ Add main method to run single project:\n \n    ```java\n    public class TestBot implements BotModule {   \n       public static void main(String[] args) {\n           final var profile = (args.length \u003e= 1) ? args[0] : \"\";\n           Runner.run(profile, List.of(new TestBot()));\n       }\n       // ...\n    }\n    ```\n \n - _[Optional]_ Add yaml configuration support:\n \n    ```java\n    import lombok.Data;\n    import com.fasterxml.jackson.annotation.JsonProperty;\n    import javax.validation.constraints.NotBlank;\n    \n    @Data\n    public class BotConfig {\n    \n        @NotBlank\n        @JsonProperty(required = true)\n        private String token;\n    \n        @NotBlank\n        @JsonProperty(required = true)\n        private String username;\n    }\n    ```\n    \n    `testbot.yaml`\n    ```yaml\n    token: 123456789:ABCDEFGHIJKLM_NOPQRSTUVWXYZ01234567\n    username: bot\n    ```\n    \n    ```java\n    public class TestBot implements BotModule {   \n       // ...\n       @Override\n       public BotHandler botHandler(Config config) {\n           final var configLoader = new YamlConfigLoaderService();\n           final var configFile = configLoader.configFile(\"testbot\", config.getProfile());\n           final var botConfig = configLoader.loadFile(configFile, BotConfig.class);\n           final var botModuleOptions = BotModuleOptions.createDefault(botConfig.getToken());\n           return new TestBotHandler(botModuleOptions, botConfig);\n       }\n    }\n    ```\n\n - Fill in `config.yaml` (See [Webhooks](#webhooks) examples):\n \n    ```yaml\n    log-level: FINE\n    webhook:\n      enabled: false\n      port: env(PORT:8443)\n      externalUrl: https://123.45.67.890:$port\n      internalUrl: http://0.0.0.0:$port\n      keystorePath: cert/keystore.jks\n      keystorePassword: env(KEYSTORE_PASSWORD)\n    modules:\n      - com.annimon.testbot.TestBot\n    ```\n \n - Happy bots developing:\n \n    ```java\n    public class TestBotHandler extends BotHandler {\n    \n        private final BotConfig botConfig;\n    \n        public TestBotHandler(BotModuleOptions botModuleOptions, BotConfig botConfig) {\n            super(botModuleOptions);\n            this.botConfig = botConfig;\n        }\n    \n        @Override\n        public BotApiMethod\u003c?\u003e onUpdate(@NotNull Update update) {\n            // your code here\n            return null;\n        }\n    }\n    ```\n\nNow you can easily switch between webhook and long polling methods by changing the `webhook:` `enabled` flag in `config,yaml`.\n\nOr you can create `config-test.yaml` and run the `test` profile:\n\n```\njava -cp tgbots-module.jar:testbot.jar:yourfavoritebot.jar com.annimon.telegrambots.Runner test\n```\n\n\n## Webhooks\n\n### Heroku\n\nHeroku starts on a random port, you can get a value from the environment property `PORT`:\n\n ```yaml\n webhook:\n   enabled: true\n   port: env(PORT)\n   externalUrl: https://yourappname.herokuapp.com\n   internalUrl: http://0.0.0.0:$port\n ```\n\n### Self-hosted\n\nUse `certgen.sh` to generate a certificate (replace `SERVERIPADDRESS` with the server's IP address):\n\n```bash\nJKS=keystore.jks\nCERT=public_cert.pem\n\nopenssl req -newkey rsa:2048 -sha256 -nodes \\\n    -keyout private.key -x509 \\\n    -days 365 \\\n    -out $CERT \\\n    -subj \"/C=US/ST=Utah/L=Location/O=Organization/CN=SERVERIPADDRESS\"\n\nopenssl pkcs12 -export \\\n    -in $CERT \\\n    -inkey private.key \\\n    -certfile $CERT \\\n    -out keystore.p12\n\nkeytool -importkeystore \\\n    -srckeystore keystore.p12 \\\n    -srcstoretype pkcs12 \\\n    -sigalg SHA1withRSA \\\n    -destkeystore $JKS \\\n    -deststoretype pkcs12\n\nrm keystore.p12 private.key\n```\n\nThe keystore password will be asked several times during the generation of the certificate. Don't forget to `export` it:\n\n```bash\nexport KEYSTORE_PASSWORD=mysupersecretpasswordis123456\n```\n\nSpecify generated `keystore.jks` and `public_cert.pem` paths and your `SERVERIPADDRESS` in `config.yaml`: \n\n ```yaml\n webhook:\n   enabled: true\n   port: 8443\n   externalUrl: https://SERVERIPADDRESS:$port\n   internalUrl: http://0.0.0.0:$port\n   keystorePath: cert/keystore.jks\n   keystorePassword: env(KEYSTORE_PASSWORD)\n   certificatePublicKeyPath: cert/public_cert.pem\n ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fannimon%2Ftgbots-module","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fannimon%2Ftgbots-module","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fannimon%2Ftgbots-module/lists"}