├── system.properties ├── src ├── test │ ├── resources │ │ └── application.properties │ └── java │ │ └── com │ │ └── madadipouya │ │ └── telegram │ │ └── corona │ │ └── CoronaApplicationTests.java └── main │ ├── resources │ ├── application.properties │ └── messages │ │ └── messages.properties │ └── java │ └── com │ └── madadipouya │ └── telegram │ └── corona │ ├── utils │ ├── StringUtils.java │ ├── NumberUtils.java │ └── DateTimeUtils.java │ ├── telegram │ ├── model │ │ ├── keyboards │ │ │ ├── Keyboard.java │ │ │ ├── RemoveKeyboard.java │ │ │ ├── LocationKeyboard.java │ │ │ └── ReplyKeyboardMarkup.java │ │ ├── TextFormat.java │ │ ├── ChatAction.java │ │ ├── ActionType.java │ │ ├── inlinequery │ │ │ ├── content │ │ │ │ └── InputTextMessageContent.java │ │ │ ├── reply │ │ │ │ └── InlineQueryReplyMessage.java │ │ │ └── result │ │ │ │ └── InlineQueryResultArticle.java │ │ └── ReplyMessage.java │ ├── TelegramService.java │ └── impl │ │ └── DefaultTelegramService.java │ ├── general │ ├── command │ │ ├── BotCommand.java │ │ ├── Command.java │ │ ├── resolver │ │ │ ├── CommandResolver.java │ │ │ └── impl │ │ │ │ └── DefaultCommandResolver.java │ │ ├── parser │ │ │ ├── CommandParser.java │ │ │ ├── interceptor │ │ │ │ └── InjectCommandToMessagePayload.java │ │ │ └── impl │ │ │ │ └── DefaultCommandParser.java │ │ ├── defaults │ │ │ ├── NopCommand.java │ │ │ ├── CancelCommand.java │ │ │ └── StartCommand.java │ │ └── CommandType.java │ ├── rest │ │ ├── GlobalExceptionHandler.java │ │ ├── dto │ │ │ ├── type │ │ │ │ ├── Document.java │ │ │ │ ├── Video.java │ │ │ │ ├── Audio.java │ │ │ │ ├── Voice.java │ │ │ │ ├── AbstractType.java │ │ │ │ ├── VideoNote.java │ │ │ │ ├── Animation.java │ │ │ │ ├── Game.java │ │ │ │ └── Sticker.java │ │ │ ├── base │ │ │ │ ├── Location.java │ │ │ │ ├── ChatPhoto.java │ │ │ │ ├── MessageEntity.java │ │ │ │ ├── PhotoSize.java │ │ │ │ ├── Venue.java │ │ │ │ ├── Contact.java │ │ │ │ ├── Invoice.java │ │ │ │ ├── InlineQuery.java │ │ │ │ ├── Poll.java │ │ │ │ ├── User.java │ │ │ │ ├── ChosenInlineResult.java │ │ │ │ ├── CallbackQuery.java │ │ │ │ ├── ChatPermissions.java │ │ │ │ ├── Chat.java │ │ │ │ └── Message.java │ │ │ ├── internal │ │ │ │ └── CommandArgumentPair.java │ │ │ └── Update.java │ │ └── TelegramHookController.java │ └── config │ │ ├── RestTemplateConfig.java │ │ ├── SecurityConfig.java │ │ ├── SwaggerConfig.java │ │ └── CacheManagerConfig.java │ ├── i18n │ └── service │ │ ├── I18nService.java │ │ └── impl │ │ └── DefaultI18nService.java │ ├── CoronaApplication.java │ └── virus │ ├── integration │ ├── mathdro │ │ ├── MathdroIntegration.java │ │ ├── remote │ │ │ └── response │ │ │ │ └── CoronaStatistics.java │ │ └── impl │ │ │ └── DefaultMathdroIntegration.java │ └── openstreetmap │ │ ├── OpenStreetMapIntegration.java │ │ ├── DefaultOpenStreetMapIntegration.java │ │ └── remote │ │ └── response │ │ └── OpenStreetMapLocationResponse.java │ └── command │ ├── CoronaInlineEnquiryCommandHandler.java │ ├── CoronaVirusLatestDevelopmentCommand.java │ └── MyLocationCoronaVirusCommand.java ├── hook_update.sh ├── .mvn └── wrapper │ ├── maven-wrapper.properties │ └── MavenWrapperDownloader.java ├── .github ├── ISSUE_TEMPLATE │ ├── bug.md │ └── new-feature.md └── workflows │ └── maven.yml ├── .gitignore ├── README.md ├── pom.xml ├── mvnw.cmd └── mvnw /system.properties: -------------------------------------------------------------------------------- 1 | java.runtime.version=17.0.1 2 | -------------------------------------------------------------------------------- /src/test/resources/application.properties: -------------------------------------------------------------------------------- 1 | telegram.token=TELEGRAM_TOKEN -------------------------------------------------------------------------------- /hook_update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | curl -d "{\"url\": \"$URL/v1/$TOKEN\"}" -H "Content-Type: application/json" -X POST "https://api.telegram.org/bot$TOKEN/setWebhook" 4 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.profiles.active=@spring.profiles.active@ 2 | server.forward-headers-strategy=native 3 | telegram.token= 4 | spring.messages.basename=messages/messages 5 | spring.messages.encoding=UTF-8 -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.2/apache-maven-3.6.2-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug 3 | about: All bug template 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Description 11 | [Write the problem statement] 12 | 13 | ## Expected output 14 | [Write the expected outcome] 15 | 16 | ## Additional note 17 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/utils/StringUtils.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.utils; 2 | 3 | public class StringUtils { 4 | 5 | private StringUtils() { 6 | 7 | } 8 | 9 | public static String getOrDefaultEmpty(String str) { 10 | return org.apache.commons.lang3.StringUtils.isBlank(str) ? org.apache.commons.lang3.StringUtils.EMPTY : str; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/new-feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: New feature 3 | about: All new feature template 4 | title: As a [Someone], I'd like to [something] 5 | labels: new feature 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## Description 11 | In order to [do something], as a [Someone], I'd like to [have something]. 12 | 13 | ## Acceptance criteria 14 | - AC 1 15 | - AC 2 16 | 17 | ## Technical details 18 | Fill technical details 19 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/utils/NumberUtils.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.utils; 2 | 3 | import java.text.NumberFormat; 4 | import java.util.Locale; 5 | 6 | public class NumberUtils { 7 | 8 | private NumberUtils() { 9 | 10 | } 11 | 12 | public static String formatThreeDecimal(int number) { 13 | return NumberFormat.getNumberInstance(Locale.US).format(number); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | 25 | # intellij 26 | .idea/ 27 | *.iml 28 | 29 | # maven target 30 | target/ 31 | 32 | .DS_Store 33 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | name: Java CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v1 12 | - name: Cache 13 | uses: actions/cache@v1.0.3 14 | with: 15 | path: ~/.m2/repository 16 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} 17 | restore-keys: | 18 | ${{ runner.os }}-maven- 19 | - name: Set up JDK 11 20 | uses: actions/setup-java@v1 21 | with: 22 | java-version: 11.0.5 23 | - name: Run tests 24 | run: mvn clean verify 25 | - name: Build with Maven 26 | run: mvn -B package --file pom.xml 27 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/telegram/model/keyboards/Keyboard.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.telegram.model.keyboards; 2 | 3 | /* 4 | * This file is part of COVID-19-Telegram-bot. 5 | * 6 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License version 3 8 | * as published by the Free Software Foundation. 9 | * 10 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * Author(s): 16 | * 17 | * © 2020 Kasra Madadipouya 18 | */ 19 | 20 | public interface Keyboard { 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/command/BotCommand.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.command; 2 | 3 | /* 4 | * This file is part of COVID-19-Telegram-bot. 5 | * 6 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License version 3 8 | * as published by the Free Software Foundation. 9 | * 10 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * Author(s): 16 | * 17 | * © 2020 Kasra Madadipouya 18 | */ 19 | 20 | public interface BotCommand extends Command { 21 | CommandType getSupportedType(); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/i18n/service/I18nService.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.i18n.service; 2 | 3 | /* 4 | * This file is part of COVID-19-Telegram-bot. 5 | * 6 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License version 3 8 | * as published by the Free Software Foundation. 9 | * 10 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * Author(s): 16 | * 17 | * © 2020 Kasra Madadipouya 18 | */ 19 | 20 | public interface I18nService { 21 | 22 | String getMessage(String key, Object... args); 23 | 24 | String getMessageWithEmoji(String key, Object... args); 25 | } -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/command/Command.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.command; 2 | 3 | import com.madadipouya.telegram.corona.general.rest.dto.base.Message; 4 | 5 | /* 6 | * This file is part of COVID-19-Telegram-bot. 7 | * 8 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License version 3 10 | * as published by the Free Software Foundation. 11 | * 12 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * Author(s): 18 | * 19 | * © 2020 Kasra Madadipouya 20 | */ 21 | 22 | public interface Command { 23 | 24 | void execute(Message message, String argument); 25 | } -------------------------------------------------------------------------------- /src/main/resources/messages/messages.properties: -------------------------------------------------------------------------------- 1 | command.start.message=Get the latest COVID-19 progress at your fingertips :grinning:\n\n\ 2 | The bot can operate in both `command` and `inline` modes.\n\ 3 | :red_circle: To get latest world wide statistics, send : `/latest`\n\ 4 | :red_circle: To get statistics on your country, send: `/my_location`\n\ 5 | :red_circle: For `inline` mode just tag the bot using `@covid19_update_bot` and pass a country name or nothing to get statistics of all countries\n\ 6 | :red_circle: Results are updated every *30 minutes*\n\ 7 | :red_circle: Use the bot responsibly and not overload it with your requests\n\ 8 | :red_circle: Data source: [John Hopkins University CSSE](https://coronavirus.jhu.edu/map.html)\n\n\ 9 | _Created by_: [Kasra Madadipouya](https://twitter.com/kasra_mp) 10 | command.corona.virus.latest.statistics.reply=*Country, Confirmed, Deaths, Recovered* 11 | command.corona.virus.location={0} To get statistics of your resident country, need to know your location -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/command/resolver/CommandResolver.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.command.resolver; 2 | 3 | import com.madadipouya.telegram.corona.general.command.Command; 4 | 5 | /* 6 | * This file is part of COVID-19-Telegram-bot. 7 | * 8 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License version 3 10 | * as published by the Free Software Foundation. 11 | * 12 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * Author(s): 18 | * 19 | * © 2020 Kasra Madadipouya 20 | */ 21 | 22 | public interface CommandResolver { 23 | 24 | Command resolve(String commandName); 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/command/parser/CommandParser.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.command.parser; 2 | 3 | import com.madadipouya.telegram.corona.general.rest.dto.Update; 4 | 5 | /* 6 | * This file is part of COVID-19-Telegram-bot. 7 | * 8 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License version 3 10 | * as published by the Free Software Foundation. 11 | * 12 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * Author(s): 18 | * 19 | * © 2020 Kasra Madadipouya 20 | */ 21 | 22 | @FunctionalInterface 23 | public interface CommandParser { 24 | 25 | void parse(Update update); 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/com/madadipouya/telegram/corona/CoronaApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | /* 7 | * This file is part of COVID-19-Telegram-bot. 8 | * 9 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License version 3 11 | * as published by the Free Software Foundation. 12 | * 13 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * Author(s): 19 | * 20 | * © 2020 Kasra Madadipouya 21 | */ 22 | 23 | @SpringBootTest 24 | class CoronaApplicationTests { 25 | 26 | @Test 27 | void contextLoads() { 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/GlobalExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.http.ResponseEntity; 7 | import org.springframework.web.bind.annotation.ExceptionHandler; 8 | import org.springframework.web.bind.annotation.ResponseStatus; 9 | import org.springframework.web.bind.annotation.RestControllerAdvice; 10 | 11 | import java.util.List; 12 | 13 | import static org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace; 14 | 15 | @RestControllerAdvice 16 | public class GlobalExceptionHandler { 17 | private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class); 18 | 19 | @ExceptionHandler(value = { Exception.class }) 20 | @ResponseStatus(HttpStatus.OK) 21 | public ResponseEntity unknownException(Exception ex) { 22 | logger.error(getStackTrace(ex)); 23 | return ResponseEntity.ok("OK!"); 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/telegram/model/TextFormat.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.telegram.model; 2 | 3 | /* 4 | * This file is part of COVID-19-Telegram-bot. 5 | * 6 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License version 3 8 | * as published by the Free Software Foundation. 9 | * 10 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * Author(s): 16 | * 17 | * © 2020 Kasra Madadipouya 18 | */ 19 | 20 | public enum TextFormat { 21 | 22 | MARK_DOWN("Markdown"), 23 | 24 | HTML("HTML"), 25 | 26 | PLAIN_TEXT(""); 27 | 28 | private final String value; 29 | 30 | TextFormat(String value) { 31 | this.value = value; 32 | } 33 | 34 | public String getValue() { 35 | return value; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/type/Document.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.type; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | import java.io.Serializable; 6 | 7 | /* 8 | * This file is part of COVID-19-Telegram-bot. 9 | * 10 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 3 12 | * as published by the Free Software Foundation. 13 | * 14 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * Author(s): 20 | * 21 | * © 2020 Kasra Madadipouya 22 | */ 23 | 24 | public class Document extends AbstractType implements Serializable { 25 | 26 | @JsonProperty("file_name") 27 | private String fileName; 28 | 29 | public String getFileName() { 30 | return fileName; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/base/Location.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.base; 2 | 3 | import java.io.Serializable; 4 | 5 | /* 6 | * This file is part of COVID-19-Telegram-bot. 7 | * 8 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License version 3 10 | * as published by the Free Software Foundation. 11 | * 12 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * Author(s): 18 | * 19 | * © 2020 Kasra Madadipouya 20 | */ 21 | 22 | public class Location implements Serializable { 23 | 24 | private double longitude; 25 | 26 | private double latitude; 27 | 28 | public double getLongitude() { 29 | return longitude; 30 | } 31 | 32 | public double getLatitude() { 33 | return latitude; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/CoronaApplication.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.scheduling.annotation.EnableScheduling; 6 | 7 | /* 8 | * This file is part of COVID-19-Telegram-bot. 9 | * 10 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 3 12 | * as published by the Free Software Foundation. 13 | * 14 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * Author(s): 20 | * 21 | * © 2020 Kasra Madadipouya 22 | */ 23 | 24 | @EnableScheduling 25 | @SpringBootApplication 26 | public class CoronaApplication { 27 | 28 | public static void main(String[] args) { 29 | SpringApplication.run(CoronaApplication.class, args); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/virus/integration/mathdro/MathdroIntegration.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.virus.integration.mathdro; 2 | 3 | import com.madadipouya.telegram.corona.virus.integration.mathdro.remote.response.CoronaStatistics; 4 | 5 | import java.util.List; 6 | 7 | /* 8 | * This file is part of COVID-19-Telegram-bot. 9 | * 10 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 3 12 | * as published by the Free Software Foundation. 13 | * 14 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * Author(s): 20 | * 21 | * © 2020 Kasra Madadipouya 22 | */ 23 | 24 | public interface MathdroIntegration { 25 | 26 | List getLatestCoronaStatisticsFlat(); 27 | 28 | List getLatestCoronaStatistics(); 29 | 30 | String getLatestCoronaStatisticsByCountry(String countryCode); 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/utils/DateTimeUtils.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.utils; 2 | 3 | import java.time.ZoneOffset; 4 | import java.time.ZonedDateTime; 5 | 6 | /* 7 | * This file is part of COVID-19-Telegram-bot. 8 | * 9 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License version 3 11 | * as published by the Free Software Foundation. 12 | * 13 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * Author(s): 19 | * 20 | * © 2020 Kasra Madadipouya 21 | */ 22 | 23 | public class DateTimeUtils { 24 | 25 | private DateTimeUtils() { 26 | 27 | } 28 | 29 | public static ZonedDateTime getOneMinuteAgoTime() { 30 | return ZonedDateTime.now(ZoneOffset.UTC).minusMinutes(1); 31 | } 32 | 33 | public static ZonedDateTime getFiveMinutesAgoTime() { 34 | return ZonedDateTime.now(ZoneOffset.UTC).minusMinutes(5); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/type/Video.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.type; 2 | 3 | import java.io.Serializable; 4 | 5 | /* 6 | * This file is part of COVID-19-Telegram-bot. 7 | * 8 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License version 3 10 | * as published by the Free Software Foundation. 11 | * 12 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * Author(s): 18 | * 19 | * © 2020 Kasra Madadipouya 20 | */ 21 | 22 | public class Video extends AbstractType implements Serializable { 23 | 24 | private int width; 25 | 26 | private int height; 27 | 28 | private int duration; 29 | 30 | public int getWidth() { 31 | return width; 32 | } 33 | 34 | public int getHeight() { 35 | return height; 36 | } 37 | 38 | public int getDuration() { 39 | return duration; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/type/Audio.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.type; 2 | 3 | import java.io.Serializable; 4 | 5 | /* 6 | * This file is part of COVID-19-Telegram-bot. 7 | * 8 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License version 3 10 | * as published by the Free Software Foundation. 11 | * 12 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * Author(s): 18 | * 19 | * © 2020 Kasra Madadipouya 20 | */ 21 | 22 | public class Audio extends AbstractType implements Serializable { 23 | 24 | private int duration; 25 | 26 | private String performer; 27 | 28 | private String title; 29 | 30 | public int getDuration() { 31 | return duration; 32 | } 33 | 34 | public String getPerformer() { 35 | return performer; 36 | } 37 | 38 | public String getTitle() { 39 | return title; 40 | } 41 | } -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/base/ChatPhoto.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.base; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | import java.io.Serializable; 6 | 7 | /* 8 | * This file is part of COVID-19-Telegram-bot. 9 | * 10 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 3 12 | * as published by the Free Software Foundation. 13 | * 14 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * Author(s): 20 | * 21 | * © 2020 Kasra Madadipouya 22 | */ 23 | 24 | public class ChatPhoto implements Serializable { 25 | 26 | @JsonProperty("small_file_id") 27 | private String smallFileId; 28 | 29 | @JsonProperty("big_file_id") 30 | private String bigFileId; 31 | 32 | public String getSmallFileId() { 33 | return smallFileId; 34 | } 35 | 36 | public String getBigFileId() { 37 | return bigFileId; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/telegram/model/ChatAction.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.telegram.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | /* 6 | * This file is part of COVID-19-Telegram-bot. 7 | * 8 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License version 3 10 | * as published by the Free Software Foundation. 11 | * 12 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * Author(s): 18 | * 19 | * © 2020 Kasra Madadipouya 20 | */ 21 | 22 | public class ChatAction { 23 | 24 | @JsonProperty("chat_id") 25 | private long chatId; 26 | 27 | private ActionType action; 28 | 29 | public ChatAction(long chatId, ActionType action) { 30 | this.chatId = chatId; 31 | this.action = action; 32 | } 33 | 34 | public long getChatId() { 35 | return chatId; 36 | } 37 | 38 | public ActionType getAction() { 39 | return action; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/telegram/model/keyboards/RemoveKeyboard.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.telegram.model.keyboards; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | /* 6 | * This file is part of COVID-19-Telegram-bot. 7 | * 8 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License version 3 10 | * as published by the Free Software Foundation. 11 | * 12 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * Author(s): 18 | * 19 | * © 2020 Kasra Madadipouya 20 | */ 21 | 22 | public class RemoveKeyboard implements Keyboard { 23 | 24 | @JsonProperty("remove_keyboard") 25 | private boolean removeKeyboard; 26 | 27 | private boolean selective; 28 | 29 | public RemoveKeyboard() { 30 | this.removeKeyboard = true; 31 | this.selective = false; 32 | } 33 | 34 | public boolean isRemoveKeyboard() { 35 | return removeKeyboard; 36 | } 37 | 38 | public boolean isSelective() { 39 | return selective; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/config/RestTemplateConfig.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.config; 2 | 3 | import org.springframework.boot.web.client.RestTemplateBuilder; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.web.client.RestTemplate; 7 | 8 | import java.time.Duration; 9 | 10 | /* 11 | * This file is part of COVID-19-Telegram-bot. 12 | * 13 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License version 3 15 | * as published by the Free Software Foundation. 16 | * 17 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * Author(s): 23 | * 24 | * © 2020 Kasra Madadipouya 25 | */ 26 | 27 | @Configuration 28 | public class RestTemplateConfig { 29 | 30 | @Bean 31 | RestTemplate configureRestTemplate(RestTemplateBuilder restTemplateBuilder) { 32 | return restTemplateBuilder.setConnectTimeout(Duration.ofSeconds(5)).setReadTimeout(Duration.ofSeconds(5)).build(); 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/telegram/model/ActionType.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.telegram.model; 2 | 3 | /* 4 | * This file is part of COVID-19-Telegram-bot. 5 | * 6 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License version 3 8 | * as published by the Free Software Foundation. 9 | * 10 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * Author(s): 16 | * 17 | * © 2020 Kasra Madadipouya 18 | */ 19 | 20 | public enum ActionType { 21 | 22 | TYPING("typing"), 23 | UPLOAD_PHOTO("upload_photo"), 24 | RECORD_VIDEO("record_video"), 25 | UPLOAD_VIDEO("upload_video"), 26 | RECORD_AUDIO("record_audio"), 27 | UPLOAD_AUDIO("upload_audio"), 28 | UPLOAD_DOCUMENT("upload_document"), 29 | FIND_LOCATION("find_location"), 30 | RECORD_VIDEO_NOTE("record_video_note"), 31 | UPLOAD_VIDEO_NOTE("upload_video_note"); 32 | 33 | private final String value; 34 | 35 | ActionType(String value) { 36 | this.value = value; 37 | } 38 | 39 | public String getValue() { 40 | return value; 41 | } 42 | } -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/base/MessageEntity.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.base; 2 | 3 | import java.io.Serializable; 4 | 5 | /* 6 | * This file is part of COVID-19-Telegram-bot. 7 | * 8 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License version 3 10 | * as published by the Free Software Foundation. 11 | * 12 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * Author(s): 18 | * 19 | * © 2020 Kasra Madadipouya 20 | */ 21 | 22 | public class MessageEntity implements Serializable { 23 | 24 | private String type; 25 | 26 | private int offset; 27 | 28 | private int length; 29 | 30 | private String url; 31 | 32 | private User user; 33 | 34 | public String getType() { 35 | return type; 36 | } 37 | 38 | public int getOffset() { 39 | return offset; 40 | } 41 | 42 | public int getLength() { 43 | return length; 44 | } 45 | 46 | public String getUrl() { 47 | return url; 48 | } 49 | 50 | public User getUser() { 51 | return user; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/base/PhotoSize.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.base; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | import java.io.Serializable; 6 | 7 | /* 8 | * This file is part of COVID-19-Telegram-bot. 9 | * 10 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 3 12 | * as published by the Free Software Foundation. 13 | * 14 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * Author(s): 20 | * 21 | * © 2020 Kasra Madadipouya 22 | */ 23 | 24 | public class PhotoSize implements Serializable { 25 | 26 | @JsonProperty("file_id") 27 | private String fileId; 28 | 29 | private int width; 30 | 31 | private int height; 32 | 33 | @JsonProperty("file_size") 34 | private int fileSize; 35 | 36 | public String getFileId() { 37 | return fileId; 38 | } 39 | 40 | public int getWidth() { 41 | return width; 42 | } 43 | 44 | public int getHeight() { 45 | return height; 46 | } 47 | 48 | public int getFileSize() { 49 | return fileSize; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/command/defaults/NopCommand.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.command.defaults; 2 | 3 | import com.madadipouya.telegram.corona.general.command.Command; 4 | import com.madadipouya.telegram.corona.general.rest.dto.base.Message; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.stereotype.Component; 8 | 9 | /* 10 | * This file is part of COVID-19-Telegram-bot. 11 | * 12 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License version 3 14 | * as published by the Free Software Foundation. 15 | * 16 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * Author(s): 22 | * 23 | * © 2020 Kasra Madadipouya 24 | */ 25 | 26 | @Component 27 | public class NopCommand implements Command { 28 | 29 | private static final Logger logger = LoggerFactory.getLogger(NopCommand.class); 30 | 31 | /* 32 | * It performs no operation, keep the method body empty 33 | * or just log a debug 34 | */ 35 | @Override 36 | public void execute(Message message, String argument) { 37 | logger.debug("do nothing"); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/type/Voice.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.type; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | import java.io.Serializable; 6 | 7 | /* 8 | * This file is part of COVID-19-Telegram-bot. 9 | * 10 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 3 12 | * as published by the Free Software Foundation. 13 | * 14 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * Author(s): 20 | * 21 | * © 2020 Kasra Madadipouya 22 | */ 23 | 24 | public class Voice implements Serializable { 25 | 26 | @JsonProperty("file_id") 27 | private String fileId; 28 | 29 | private int duration; 30 | 31 | @JsonProperty("mime_type") 32 | private String mimeType; 33 | 34 | @JsonProperty("file_size") 35 | private int fileSize; 36 | 37 | public String getFileId() { 38 | return fileId; 39 | } 40 | 41 | public int getDuration() { 42 | return duration; 43 | } 44 | 45 | public String getMimeType() { 46 | return mimeType; 47 | } 48 | 49 | public int getFileSize() { 50 | return fileSize; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/telegram/TelegramService.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.telegram; 2 | 3 | import com.madadipouya.telegram.corona.telegram.model.ActionType; 4 | import com.madadipouya.telegram.corona.telegram.model.TextFormat; 5 | import com.madadipouya.telegram.corona.telegram.model.inlinequery.result.InlineQueryResultArticle; 6 | 7 | import java.util.List; 8 | 9 | /* 10 | * This file is part of COVID-19-Telegram-bot. 11 | * 12 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License version 3 14 | * as published by the Free Software Foundation. 15 | * 16 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * Author(s): 22 | * 23 | * © 2020 Kasra Madadipouya 24 | */ 25 | 26 | public interface TelegramService { 27 | 28 | void reply(long to, String text, TextFormat format); 29 | 30 | void askLocation(long to, String text); 31 | 32 | void cancelAction(long to, int messageId); 33 | 34 | void replyInlineQuery(String queryId, String title, String text, TextFormat format); 35 | 36 | void replyInlineQueryArticles(String queryId, List results); 37 | 38 | void sendAction(long chatId, ActionType action); 39 | } -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/telegram/model/keyboards/LocationKeyboard.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.telegram.model.keyboards; 2 | 3 | import java.util.List; 4 | 5 | /* 6 | * This file is part of COVID-19-Telegram-bot. 7 | * 8 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License version 3 10 | * as published by the Free Software Foundation. 11 | * 12 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * Author(s): 18 | * 19 | * © 2020 Kasra Madadipouya 20 | */ 21 | 22 | public class LocationKeyboard extends ReplyKeyboardMarkup implements Keyboard { 23 | 24 | public LocationKeyboard() { 25 | this(List.of(new KeyboardButton("Share your location", false, true), 26 | new KeyboardButton("/cancel", false, false)), true, true, false); 27 | } 28 | 29 | private LocationKeyboard(KeyboardButton keyboardButton, boolean resizeKeyboard, boolean oneTimeKeyboard, boolean selective) { 30 | this(List.of(keyboardButton), resizeKeyboard, oneTimeKeyboard, selective); 31 | } 32 | 33 | private LocationKeyboard(List keyboards, boolean resizeKeyboard, boolean oneTimeKeyboard, boolean selective) { 34 | super(keyboards, resizeKeyboard, oneTimeKeyboard, selective); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/type/AbstractType.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.type; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.madadipouya.telegram.corona.general.rest.dto.base.PhotoSize; 5 | 6 | import java.io.Serializable; 7 | 8 | /* 9 | * This file is part of COVID-19-Telegram-bot. 10 | * 11 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License version 3 13 | * as published by the Free Software Foundation. 14 | * 15 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * Author(s): 21 | * 22 | * © 2020 Kasra Madadipouya 23 | */ 24 | 25 | public abstract class AbstractType implements Serializable { 26 | 27 | @JsonProperty("file_id") 28 | private String fileId; 29 | 30 | @JsonProperty("mime_type") 31 | private String mimeType; 32 | 33 | @JsonProperty("file_size") 34 | private int fileSize; 35 | 36 | private PhotoSize thumb; 37 | 38 | public String getFileId() { 39 | return fileId; 40 | } 41 | 42 | public String getMimeType() { 43 | return mimeType; 44 | } 45 | 46 | public int getFileSize() { 47 | return fileSize; 48 | } 49 | 50 | public PhotoSize getThumb() { 51 | return thumb; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/config/SecurityConfig.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.http.HttpMethod; 5 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 6 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 7 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 8 | 9 | /* 10 | * This file is part of COVID-19-Telegram-bot. 11 | * 12 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License version 3 14 | * as published by the Free Software Foundation. 15 | * 16 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * Author(s): 22 | * 23 | * © 2020 Kasra Madadipouya 24 | */ 25 | 26 | @Configuration 27 | @EnableWebSecurity 28 | public class SecurityConfig extends WebSecurityConfigurerAdapter { 29 | 30 | private static final String HAS_TELEGRAM_IPS = "hasIpAddress('91.108.4.0/22') or hasIpAddress('149.154.160.0/20')"; 31 | 32 | @Override 33 | protected void configure(HttpSecurity http) throws Exception { 34 | http.csrf().disable().authorizeRequests().antMatchers(HttpMethod.POST, "/v1/**").access(HAS_TELEGRAM_IPS); 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/base/Venue.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.base; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | import java.io.Serializable; 6 | 7 | /* 8 | * This file is part of COVID-19-Telegram-bot. 9 | * 10 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 3 12 | * as published by the Free Software Foundation. 13 | * 14 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * Author(s): 20 | * 21 | * © 2020 Kasra Madadipouya 22 | */ 23 | 24 | public class Venue implements Serializable { 25 | 26 | private Location location; 27 | 28 | private String title; 29 | 30 | private String address; 31 | 32 | @JsonProperty("foursquare_id") 33 | private String fourSquareId; 34 | 35 | @JsonProperty("foursquare_type") 36 | private String fourSquareType; 37 | 38 | public Location getLocation() { 39 | return location; 40 | } 41 | 42 | public String getTitle() { 43 | return title; 44 | } 45 | 46 | public String getAddress() { 47 | return address; 48 | } 49 | 50 | public String getFourSquareId() { 51 | return fourSquareId; 52 | } 53 | 54 | public String getFourSquareType() { 55 | return fourSquareType; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/i18n/service/impl/DefaultI18nService.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.i18n.service.impl; 2 | 3 | import com.madadipouya.telegram.corona.i18n.service.I18nService; 4 | import com.vdurmont.emoji.EmojiParser; 5 | import org.springframework.context.MessageSource; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.util.Locale; 9 | 10 | /* 11 | * This file is part of COVID-19-Telegram-bot. 12 | * 13 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License version 3 15 | * as published by the Free Software Foundation. 16 | * 17 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * Author(s): 23 | * 24 | * © 2020 Kasra Madadipouya 25 | */ 26 | 27 | @Service 28 | public class DefaultI18nService implements I18nService { 29 | 30 | private final MessageSource messageSource; 31 | 32 | public DefaultI18nService(MessageSource messageSource) { 33 | this.messageSource = messageSource; 34 | } 35 | 36 | @Override 37 | public String getMessage(String key, Object... args) { 38 | return messageSource.getMessage(key, args, Locale.getDefault()); 39 | } 40 | 41 | @Override 42 | public String getMessageWithEmoji(String key, Object... args) { 43 | return EmojiParser.parseToUnicode(getMessage(key, args)); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/type/VideoNote.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.type; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.madadipouya.telegram.corona.general.rest.dto.base.PhotoSize; 5 | 6 | import java.io.Serializable; 7 | 8 | /* 9 | * This file is part of COVID-19-Telegram-bot. 10 | * 11 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License version 3 13 | * as published by the Free Software Foundation. 14 | * 15 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * Author(s): 21 | * 22 | * © 2020 Kasra Madadipouya 23 | */ 24 | 25 | public class VideoNote implements Serializable { 26 | 27 | @JsonProperty("file_id") 28 | private String fileId; 29 | 30 | private int length; 31 | 32 | private int duration; 33 | 34 | private PhotoSize thumb; 35 | 36 | @JsonProperty("file_size") 37 | private int fileSize; 38 | 39 | public String getFileId() { 40 | return fileId; 41 | } 42 | 43 | public int getLength() { 44 | return length; 45 | } 46 | 47 | public int getDuration() { 48 | return duration; 49 | } 50 | 51 | public PhotoSize getThumb() { 52 | return thumb; 53 | } 54 | 55 | public int getFileSize() { 56 | return fileSize; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/config/SwaggerConfig.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.context.annotation.Profile; 6 | import springfox.documentation.builders.RequestHandlerSelectors; 7 | import springfox.documentation.spi.DocumentationType; 8 | import springfox.documentation.spring.web.plugins.Docket; 9 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 10 | 11 | import static springfox.documentation.builders.PathSelectors.regex; 12 | 13 | /* 14 | * This file is part of COVID-19-Telegram-bot. 15 | * 16 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 17 | * it under the terms of the GNU General Public License version 3 18 | * as published by the Free Software Foundation. 19 | * 20 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | * GNU General Public License for more details. 24 | * 25 | * Author(s): 26 | * 27 | * © 2020 Kasra Madadipouya 28 | */ 29 | 30 | @Profile("!production") 31 | @EnableSwagger2 32 | @Configuration 33 | public class SwaggerConfig { 34 | 35 | @Bean 36 | public Docket configureSwagger() { 37 | return new Docket(DocumentationType.SWAGGER_2) 38 | .select() 39 | .apis(RequestHandlerSelectors.any()) 40 | .paths(regex("/v1/.*")) 41 | .build(); 42 | } 43 | } -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/base/Contact.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.base; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | import java.io.Serializable; 6 | 7 | /* 8 | * This file is part of COVID-19-Telegram-bot. 9 | * 10 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 3 12 | * as published by the Free Software Foundation. 13 | * 14 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * Author(s): 20 | * 21 | * © 2020 Kasra Madadipouya 22 | */ 23 | 24 | public class Contact implements Serializable { 25 | 26 | @JsonProperty("phone_number") 27 | private String phoneNumber; 28 | 29 | @JsonProperty("first_name") 30 | private String firstName; 31 | 32 | @JsonProperty("last_name") 33 | private String lastName; 34 | 35 | @JsonProperty("user_id") 36 | private int userId; 37 | 38 | private String vcard; 39 | 40 | public String getPhoneNumber() { 41 | return phoneNumber; 42 | } 43 | 44 | public String getFirstName() { 45 | return firstName; 46 | } 47 | 48 | public String getLastName() { 49 | return lastName; 50 | } 51 | 52 | public int getUserId() { 53 | return userId; 54 | } 55 | 56 | public String getVcard() { 57 | return vcard; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/command/defaults/CancelCommand.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.command.defaults; 2 | 3 | import com.madadipouya.telegram.corona.general.command.BotCommand; 4 | import com.madadipouya.telegram.corona.general.command.CommandType; 5 | import com.madadipouya.telegram.corona.general.rest.dto.base.Message; 6 | import com.madadipouya.telegram.corona.telegram.TelegramService; 7 | import org.springframework.stereotype.Component; 8 | 9 | /* 10 | * This file is part of COVID-19-Telegram-bot. 11 | * 12 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License version 3 14 | * as published by the Free Software Foundation. 15 | * 16 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * Author(s): 22 | * 23 | * © 2020 Kasra Madadipouya 24 | */ 25 | 26 | @Component 27 | public class CancelCommand implements BotCommand { 28 | 29 | private final TelegramService telegramService; 30 | 31 | public CancelCommand(TelegramService telegramService) { 32 | this.telegramService = telegramService; 33 | } 34 | 35 | @Override 36 | public void execute(Message message, String argument) { 37 | telegramService.cancelAction(message.getChat().getId(), message.getMessageId()); 38 | } 39 | 40 | @Override 41 | public CommandType getSupportedType() { 42 | return CommandType.CANCEL; 43 | } 44 | } -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/base/Invoice.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.base; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | import java.io.Serializable; 6 | 7 | /* 8 | * This file is part of COVID-19-Telegram-bot. 9 | * 10 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 3 12 | * as published by the Free Software Foundation. 13 | * 14 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * Author(s): 20 | * 21 | * © 2020 Kasra Madadipouya 22 | */ 23 | 24 | public class Invoice implements Serializable { 25 | 26 | private String title; 27 | 28 | private String description; 29 | 30 | @JsonProperty("start_parameter") 31 | private String startParameter; 32 | 33 | // TODO replace it with enum ISO-4217 34 | private String currency; 35 | 36 | // $ 1.45 stores as 145 37 | @JsonProperty("total_amount") 38 | private int totalAmount; 39 | 40 | public String getTitle() { 41 | return title; 42 | } 43 | 44 | public String getDescription() { 45 | return description; 46 | } 47 | 48 | public String getStartParameter() { 49 | return startParameter; 50 | } 51 | 52 | public String getCurrency() { 53 | return currency; 54 | } 55 | 56 | public int getTotalAmount() { 57 | return totalAmount; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/internal/CommandArgumentPair.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.internal; 2 | 3 | import com.madadipouya.telegram.corona.general.command.Command; 4 | import com.madadipouya.telegram.corona.general.rest.dto.base.Message; 5 | import org.apache.commons.lang3.StringUtils; 6 | 7 | /* 8 | * This file is part of COVID-19-Telegram-bot. 9 | * 10 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 3 12 | * as published by the Free Software Foundation. 13 | * 14 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * Author(s): 20 | * 21 | * © 2020 Kasra Madadipouya 22 | */ 23 | 24 | public class CommandArgumentPair { 25 | 26 | private Command command; 27 | 28 | private String argument; 29 | 30 | private Message message; 31 | 32 | public CommandArgumentPair(Command command, Message message) { 33 | this(command, message, StringUtils.EMPTY); 34 | } 35 | 36 | public CommandArgumentPair(Command command, Message message, String argument) { 37 | this.command = command; 38 | this.message = message; 39 | this.argument = argument; 40 | } 41 | 42 | public Command getCommand() { 43 | return command; 44 | } 45 | 46 | public Message getMessage() { 47 | return message; 48 | } 49 | 50 | public String getArgument() { 51 | return argument; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/telegram/model/inlinequery/content/InputTextMessageContent.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.telegram.model.inlinequery.content; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.madadipouya.telegram.corona.telegram.model.TextFormat; 5 | 6 | /* 7 | * This file is part of COVID-19-Telegram-bot. 8 | * 9 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License version 3 11 | * as published by the Free Software Foundation. 12 | * 13 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * Author(s): 19 | * 20 | * © 2020 Kasra Madadipouya 21 | */ 22 | 23 | public class InputTextMessageContent { 24 | 25 | @JsonProperty("message_text") 26 | private String messageText; 27 | 28 | @JsonProperty("parse_mode") 29 | private String parseMode; 30 | 31 | @JsonProperty("disable_web_page_preview") 32 | private boolean disableWebPagePreview; 33 | 34 | public InputTextMessageContent(String messageText, TextFormat parseMode) { 35 | this.messageText = messageText; 36 | this.parseMode = parseMode.getValue(); 37 | this.disableWebPagePreview = true; 38 | } 39 | 40 | public String getMessageText() { 41 | return messageText; 42 | } 43 | 44 | public String getParseMode() { 45 | return parseMode; 46 | } 47 | 48 | public boolean isDisableWebPagePreview() { 49 | return disableWebPagePreview; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/command/parser/interceptor/InjectCommandToMessagePayload.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.command.parser.interceptor; 2 | 3 | import com.madadipouya.telegram.corona.general.command.parser.CommandParser; 4 | import com.madadipouya.telegram.corona.general.rest.dto.Update; 5 | import org.aspectj.lang.JoinPoint; 6 | import org.aspectj.lang.annotation.Aspect; 7 | import org.aspectj.lang.annotation.Before; 8 | import org.springframework.core.annotation.Order; 9 | import org.springframework.stereotype.Component; 10 | 11 | /* 12 | * This file is part of COVID-19-Telegram-bot. 13 | * 14 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 15 | * it under the terms of the GNU General Public License version 3 16 | * as published by the Free Software Foundation. 17 | * 18 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * Author(s): 24 | * 25 | * © 2020 Kasra Madadipouya 26 | */ 27 | 28 | @Order(0) 29 | @Aspect 30 | @Component 31 | public class InjectCommandToMessagePayload { 32 | 33 | private final CommandParser commandParser; 34 | 35 | public InjectCommandToMessagePayload(CommandParser commandParser) { 36 | this.commandParser = commandParser; 37 | } 38 | 39 | @Before(value = "execution(* com.madadipouya.telegram.corona.general.rest.TelegramHookController.listen(..)) && args(update)") 40 | public void addCommandDetailsToMessage(JoinPoint joinPoint, Update update) { 41 | commandParser.parse(update); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/type/Animation.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.type; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | import java.io.Serializable; 6 | 7 | /* 8 | * This file is part of COVID-19-Telegram-bot. 9 | * 10 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 3 12 | * as published by the Free Software Foundation. 13 | * 14 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * Author(s): 20 | * 21 | * © 2020 Kasra Madadipouya 22 | */ 23 | 24 | public class Animation extends AbstractType implements Serializable { 25 | 26 | private int width; 27 | 28 | private int height; 29 | 30 | private int duration; 31 | 32 | @JsonProperty("file_name") 33 | private String fileName; 34 | 35 | public int getWidth() { 36 | return width; 37 | } 38 | 39 | public void setWidth(int width) { 40 | this.width = width; 41 | } 42 | 43 | public int getHeight() { 44 | return height; 45 | } 46 | 47 | public void setHeight(int height) { 48 | this.height = height; 49 | } 50 | 51 | public int getDuration() { 52 | return duration; 53 | } 54 | 55 | public void setDuration(int duration) { 56 | this.duration = duration; 57 | } 58 | 59 | public String getFileName() { 60 | return fileName; 61 | } 62 | 63 | public void setFileName(String fileName) { 64 | this.fileName = fileName; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/base/InlineQuery.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.base; 2 | 3 | /* 4 | * This file is part of COVID-19-Telegram-bot. 5 | * 6 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License version 3 8 | * as published by the Free Software Foundation. 9 | * 10 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * Author(s): 16 | * 17 | * © 2020 Kasra Madadipouya 18 | */ 19 | 20 | public class InlineQuery { 21 | 22 | private String id; 23 | 24 | private User from; 25 | 26 | private Location location; 27 | 28 | private String query; 29 | 30 | private String offset; 31 | 32 | public String getId() { 33 | return id; 34 | } 35 | 36 | public void setId(String id) { 37 | this.id = id; 38 | } 39 | 40 | public User getFrom() { 41 | return from; 42 | } 43 | 44 | public void setFrom(User from) { 45 | this.from = from; 46 | } 47 | 48 | public Location getLocation() { 49 | return location; 50 | } 51 | 52 | public void setLocation(Location location) { 53 | this.location = location; 54 | } 55 | 56 | public String getQuery() { 57 | return query; 58 | } 59 | 60 | public void setQuery(String query) { 61 | this.query = query; 62 | } 63 | 64 | public String getOffset() { 65 | return offset; 66 | } 67 | 68 | public void setOffset(String offset) { 69 | this.offset = offset; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/base/Poll.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.base; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | import java.io.Serializable; 6 | import java.util.List; 7 | 8 | /* 9 | * This file is part of COVID-19-Telegram-bot. 10 | * 11 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License version 3 13 | * as published by the Free Software Foundation. 14 | * 15 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * Author(s): 21 | * 22 | * © 2020 Kasra Madadipouya 23 | */ 24 | 25 | public class Poll implements Serializable { 26 | 27 | private String id; 28 | 29 | private String question; 30 | 31 | private List options; 32 | 33 | @JsonProperty("is_closed") 34 | private boolean closed; 35 | 36 | public String getId() { 37 | return id; 38 | } 39 | 40 | public String getQuestion() { 41 | return question; 42 | } 43 | 44 | public List getOptions() { 45 | return options; 46 | } 47 | 48 | public boolean isClosed() { 49 | return closed; 50 | } 51 | 52 | public static class PollOption implements Serializable { 53 | 54 | private String text; 55 | 56 | @JsonProperty("voter_count") 57 | private int voterCount; 58 | 59 | public String getText() { 60 | return text; 61 | } 62 | 63 | public int getVoterCount() { 64 | return voterCount; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/command/CommandType.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.command; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | 5 | import java.util.Arrays; 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | /* 10 | * This file is part of COVID-19-Telegram-bot. 11 | * 12 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License version 3 14 | * as published by the Free Software Foundation. 15 | * 16 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * Author(s): 22 | * 23 | * © 2020 Kasra Madadipouya 24 | */ 25 | 26 | public enum CommandType { 27 | CANCEL("/cancel"), 28 | START("/start"), 29 | CORONA_VIRUS_LATEST("/latest"), 30 | CORONA_VIRUS_MY_LOCATION_UPDATE("/my_location"), 31 | NO_OP(StringUtils.EMPTY); 32 | 33 | private final String value; 34 | 35 | private static Map commands = new HashMap<>(); 36 | 37 | static { 38 | Arrays.stream(CommandType.values()).forEach(command -> commands.put(command.value, command)); 39 | } 40 | 41 | CommandType(String value) { 42 | this.value = value; 43 | } 44 | 45 | public String getValue() { 46 | return value; 47 | } 48 | 49 | public static CommandType getCommand(String command) { 50 | CommandType enumCommand = commands.get(command); 51 | if (enumCommand == null) { 52 | throw new IllegalArgumentException(String.format("No constant with text %s found", command)); 53 | } 54 | return enumCommand; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/base/User.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.base; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | import java.io.Serializable; 6 | 7 | /* 8 | * This file is part of COVID-19-Telegram-bot. 9 | * 10 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 3 12 | * as published by the Free Software Foundation. 13 | * 14 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * Author(s): 20 | * 21 | * © 2020 Kasra Madadipouya 22 | */ 23 | 24 | public class User implements Serializable { 25 | 26 | private int id; 27 | 28 | @JsonProperty("is_bot") 29 | private boolean bot; 30 | 31 | @JsonProperty("first_name") 32 | private String firstName; 33 | 34 | @JsonProperty("last_name") 35 | private String lastName; 36 | 37 | private String username; 38 | 39 | @JsonProperty("language_code") 40 | private String languageCode; 41 | 42 | //https://en.wikipedia.org/wiki/IETF_language_tag 43 | // TODO replace above with enum 44 | 45 | public int getId() { 46 | return id; 47 | } 48 | 49 | public boolean isBot() { 50 | return bot; 51 | } 52 | 53 | public String getFirstName() { 54 | return firstName; 55 | } 56 | 57 | public String getLastName() { 58 | return lastName; 59 | } 60 | 61 | public String getUsername() { 62 | return username; 63 | } 64 | 65 | public String getLanguageCode() { 66 | return languageCode; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/virus/integration/openstreetmap/OpenStreetMapIntegration.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.virus.integration.openstreetmap; 2 | 3 | import com.madadipouya.telegram.corona.virus.integration.openstreetmap.remote.response.OpenStreetMapLocationResponse; 4 | 5 | /* 6 | * This file is part of COVID-19-Telegram-bot. 7 | * 8 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License version 3 10 | * as published by the Free Software Foundation. 11 | * 12 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * Author(s): 18 | * 19 | * © 2020 Kasra Madadipouya 20 | */ 21 | 22 | /** 23 | * This service is responsible to get physical address of a geographical location 24 | */ 25 | public interface OpenStreetMapIntegration { 26 | 27 | /** 28 | * Gets country code of a geographical location 29 | * 30 | * @param latitude Latitude of location to get the address for 31 | * @param longitude Longitude of location to get the address for 32 | * @return Physical address of the location contains the full address 33 | */ 34 | String getCountryCodeOfGeoLocation(double latitude, double longitude); 35 | 36 | /** 37 | * Gets physical address of a geographical location 38 | * 39 | * @param latitude Latitude of location to get the address for 40 | * @param longitude Longitude of location to get the address for 41 | * @return {@link OpenStreetMapLocationResponse} The physical address of the location 42 | */ 43 | OpenStreetMapLocationResponse getReverseGeocoding(double latitude, double longitude); 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/type/Game.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.type; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.madadipouya.telegram.corona.general.rest.dto.base.MessageEntity; 5 | import com.madadipouya.telegram.corona.general.rest.dto.base.PhotoSize; 6 | 7 | import java.io.Serializable; 8 | import java.util.List; 9 | 10 | /* 11 | * This file is part of COVID-19-Telegram-bot. 12 | * 13 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License version 3 15 | * as published by the Free Software Foundation. 16 | * 17 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * Author(s): 23 | * 24 | * © 2020 Kasra Madadipouya 25 | */ 26 | 27 | public class Game implements Serializable { 28 | 29 | private String title; 30 | 31 | private String description; 32 | 33 | @JsonProperty("photo") 34 | private List photos; 35 | 36 | private String text; 37 | 38 | @JsonProperty("text_entities") 39 | private List textEntities; 40 | 41 | private Animation animation; 42 | 43 | public String getTitle() { 44 | return title; 45 | } 46 | 47 | public String getDescription() { 48 | return description; 49 | } 50 | 51 | public List getPhotos() { 52 | return photos; 53 | } 54 | 55 | public String getText() { 56 | return text; 57 | } 58 | 59 | public List getTextEntities() { 60 | return textEntities; 61 | } 62 | 63 | public Animation getAnimation() { 64 | return animation; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/telegram/model/inlinequery/reply/InlineQueryReplyMessage.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.telegram.model.inlinequery.reply; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.madadipouya.telegram.corona.telegram.model.inlinequery.result.InlineQueryResultArticle; 5 | 6 | import java.util.List; 7 | 8 | /* 9 | * This file is part of COVID-19-Telegram-bot. 10 | * 11 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License version 3 13 | * as published by the Free Software Foundation. 14 | * 15 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * Author(s): 21 | * 22 | * © 2020 Kasra Madadipouya 23 | */ 24 | 25 | public class InlineQueryReplyMessage { 26 | 27 | @JsonProperty("inline_query_id") 28 | private final String inlineQueryId; 29 | 30 | private final List results; 31 | 32 | @JsonProperty("cache_time") 33 | private final int cacheTimeSeconds; 34 | 35 | public InlineQueryReplyMessage(String inlineQueryId, InlineQueryResultArticle inlineQueryResult) { 36 | this(inlineQueryId, List.of(inlineQueryResult)); 37 | } 38 | 39 | public InlineQueryReplyMessage(String inlineQueryId, List inlineQueryResult) { 40 | this.inlineQueryId = inlineQueryId; 41 | this.results = inlineQueryResult; 42 | this.cacheTimeSeconds = 120; 43 | } 44 | 45 | public String getInlineQueryId() { 46 | return inlineQueryId; 47 | } 48 | 49 | public List getResults() { 50 | return results; 51 | } 52 | 53 | public int getCacheTimeSeconds() { 54 | return cacheTimeSeconds; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/command/defaults/StartCommand.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.command.defaults; 2 | 3 | import com.madadipouya.telegram.corona.general.command.BotCommand; 4 | import com.madadipouya.telegram.corona.general.command.CommandType; 5 | import com.madadipouya.telegram.corona.general.rest.dto.base.Message; 6 | import com.madadipouya.telegram.corona.i18n.service.I18nService; 7 | import com.madadipouya.telegram.corona.telegram.TelegramService; 8 | import com.madadipouya.telegram.corona.telegram.model.TextFormat; 9 | import org.springframework.stereotype.Component; 10 | 11 | import static com.madadipouya.telegram.corona.general.command.CommandType.START; 12 | 13 | /* 14 | * This file is part of COVID-19-Telegram-bot. 15 | * 16 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 17 | * it under the terms of the GNU General Public License version 3 18 | * as published by the Free Software Foundation. 19 | * 20 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | * GNU General Public License for more details. 24 | * 25 | * Author(s): 26 | * 27 | * © 2020 Kasra Madadipouya 28 | */ 29 | 30 | @Component 31 | public class StartCommand implements BotCommand { 32 | 33 | private final TelegramService telegramService; 34 | 35 | private I18nService i18nService; 36 | 37 | public StartCommand(TelegramService telegramService, I18nService i18nService) { 38 | this.telegramService = telegramService; 39 | this.i18nService = i18nService; 40 | } 41 | 42 | @Override 43 | public void execute(Message message, String argument) { 44 | telegramService.reply(message.getChat().getId(), i18nService.getMessageWithEmoji("command.start.message"), TextFormat.MARK_DOWN); 45 | } 46 | 47 | @Override 48 | public CommandType getSupportedType() { 49 | return START; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/base/ChosenInlineResult.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.base; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | /* 6 | * This file is part of COVID-19-Telegram-bot. 7 | * 8 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License version 3 10 | * as published by the Free Software Foundation. 11 | * 12 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * Author(s): 18 | * 19 | * © 2020 Kasra Madadipouya 20 | */ 21 | 22 | public class ChosenInlineResult { 23 | 24 | @JsonProperty("result_id") 25 | private String resultId; 26 | 27 | private User from; 28 | 29 | private Location location; 30 | 31 | @JsonProperty("inline_message_id") 32 | private String inlineMessageId; 33 | 34 | private String query; 35 | 36 | public String getResultId() { 37 | return resultId; 38 | } 39 | 40 | public void setResultId(String resultId) { 41 | this.resultId = resultId; 42 | } 43 | 44 | public User getFrom() { 45 | return from; 46 | } 47 | 48 | public void setFrom(User from) { 49 | this.from = from; 50 | } 51 | 52 | public Location getLocation() { 53 | return location; 54 | } 55 | 56 | public void setLocation(Location location) { 57 | this.location = location; 58 | } 59 | 60 | public String getInlineMessageId() { 61 | return inlineMessageId; 62 | } 63 | 64 | public void setInlineMessageId(String inlineMessageId) { 65 | this.inlineMessageId = inlineMessageId; 66 | } 67 | 68 | public String getQuery() { 69 | return query; 70 | } 71 | 72 | public void setQuery(String query) { 73 | this.query = query; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/telegram/model/inlinequery/result/InlineQueryResultArticle.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.telegram.model.inlinequery.result; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.madadipouya.telegram.corona.telegram.model.TextFormat; 5 | import com.madadipouya.telegram.corona.telegram.model.inlinequery.content.InputTextMessageContent; 6 | 7 | /* 8 | * This file is part of COVID-19-Telegram-bot. 9 | * 10 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 3 12 | * as published by the Free Software Foundation. 13 | * 14 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * Author(s): 20 | * 21 | * © 2020 Kasra Madadipouya 22 | */ 23 | 24 | public class InlineQueryResultArticle { 25 | 26 | private final String type = "article"; 27 | 28 | private String id; 29 | 30 | private String title; 31 | 32 | @JsonProperty("input_message_content") 33 | private InputTextMessageContent inputMessageContent; 34 | 35 | public InlineQueryResultArticle(String id, String title, String text, TextFormat format) { 36 | this(id, title, new InputTextMessageContent(text, format)); 37 | } 38 | 39 | public InlineQueryResultArticle(String id, String title, InputTextMessageContent inputTextMessageContent) { 40 | this.id = id; 41 | this.title = title; 42 | this.inputMessageContent = inputTextMessageContent; 43 | } 44 | 45 | public String getType() { 46 | return type; 47 | } 48 | 49 | public String getId() { 50 | return id; 51 | } 52 | 53 | public String getTitle() { 54 | return title; 55 | } 56 | 57 | public InputTextMessageContent getInputMessageContent() { 58 | return inputMessageContent; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/TelegramHookController.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest; 2 | 3 | import com.madadipouya.telegram.corona.virus.command.CoronaInlineEnquiryCommandHandler; 4 | import com.madadipouya.telegram.corona.general.rest.dto.Update; 5 | import org.springframework.web.bind.annotation.PostMapping; 6 | import org.springframework.web.bind.annotation.RequestBody; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | import java.util.Objects; 11 | 12 | /* 13 | * This file is part of COVID-19-Telegram-bot. 14 | * 15 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 16 | * it under the terms of the GNU General Public License version 3 17 | * as published by the Free Software Foundation. 18 | * 19 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | * GNU General Public License for more details. 23 | * 24 | * Author(s): 25 | * 26 | * © 2020 Kasra Madadipouya 27 | */ 28 | 29 | @RestController 30 | @RequestMapping(value = "/v1") 31 | public class TelegramHookController { 32 | 33 | private final CoronaInlineEnquiryCommandHandler coronaInlineEnquiryCommandHandler; 34 | 35 | public TelegramHookController(CoronaInlineEnquiryCommandHandler coronaInlineEnquiryCommandHandler) { 36 | this.coronaInlineEnquiryCommandHandler = coronaInlineEnquiryCommandHandler; 37 | } 38 | 39 | @PostMapping("/${telegram.token}") 40 | public void listen(@RequestBody Update update) { 41 | update.getCommandArgumentPairs().stream().filter(ca -> Objects.nonNull(ca.getCommand())) 42 | .forEach(ca -> ca.getCommand().execute(ca.getMessage(), ca.getArgument())); 43 | 44 | if (update.hasInlineQuery()) { 45 | coronaInlineEnquiryCommandHandler.handle(update.getInlineQuery().getId(), update.getInlineQuery().getQuery()); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/base/CallbackQuery.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.base; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import org.apache.commons.lang3.StringUtils; 5 | 6 | import java.io.Serializable; 7 | import java.util.Objects; 8 | 9 | /* 10 | * This file is part of COVID-19-Telegram-bot. 11 | * 12 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 13 | * it under the terms of the GNU General Public License version 3 14 | * as published by the Free Software Foundation. 15 | * 16 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU General Public License for more details. 20 | * 21 | * Author(s): 22 | * 23 | * © 2020 Kasra Madadipouya 24 | */ 25 | 26 | public class CallbackQuery implements Serializable { 27 | 28 | private String id; 29 | 30 | private User from; 31 | 32 | private Message message; 33 | 34 | @JsonProperty("inline_message_id") 35 | private String inlineMessageId; 36 | 37 | @JsonProperty("chat_instance") 38 | private String chatInstance; 39 | 40 | private String data; 41 | 42 | @JsonProperty("game_short_name") 43 | private String gameShortName; 44 | 45 | public String getId() { 46 | return id; 47 | } 48 | 49 | public User getFrom() { 50 | return from; 51 | } 52 | 53 | public Message getMessage() { 54 | return message; 55 | } 56 | 57 | public String getInlineMessageId() { 58 | return inlineMessageId; 59 | } 60 | 61 | public String getChatInstance() { 62 | return chatInstance; 63 | } 64 | 65 | public String getData() { 66 | return data; 67 | } 68 | 69 | public String getGameShortName() { 70 | return gameShortName; 71 | } 72 | 73 | public String getMessageText() { 74 | return Objects.nonNull(getMessage()) ? getMessage().getText() : StringUtils.EMPTY; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/command/resolver/impl/DefaultCommandResolver.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.command.resolver.impl; 2 | 3 | import com.madadipouya.telegram.corona.general.command.BotCommand; 4 | import com.madadipouya.telegram.corona.general.command.Command; 5 | import com.madadipouya.telegram.corona.general.command.CommandType; 6 | import com.madadipouya.telegram.corona.general.command.resolver.CommandResolver; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.Optional; 12 | import java.util.stream.Collectors; 13 | 14 | /* 15 | * This file is part of COVID-19-Telegram-bot. 16 | * 17 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 18 | * it under the terms of the GNU General Public License version 3 19 | * as published by the Free Software Foundation. 20 | * 21 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 | * GNU General Public License for more details. 25 | * 26 | * Author(s): 27 | * 28 | * © 2020 Kasra Madadipouya 29 | */ 30 | 31 | @Service 32 | public class DefaultCommandResolver implements CommandResolver { 33 | 34 | private final Map botCommandMap; 35 | 36 | public DefaultCommandResolver(List botCommands) { 37 | botCommandMap = botCommands.stream().map(command -> Map.entry(command.getSupportedType(), command)) 38 | .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); 39 | } 40 | 41 | @Override 42 | public Command resolve(String commandName) { 43 | return resolveBotCommand(commandName).orElse(botCommandMap.get(CommandType.NO_OP)); 44 | } 45 | 46 | private Optional resolveBotCommand(String commandName) { 47 | try { 48 | return Optional.ofNullable(botCommandMap.get(CommandType.getCommand(commandName))); 49 | } catch (IllegalArgumentException noCommandTypeFoundException) { 50 | return Optional.empty(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/virus/integration/mathdro/remote/response/CoronaStatistics.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.virus.integration.mathdro.remote.response; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | import static com.madadipouya.telegram.corona.utils.NumberUtils.formatThreeDecimal; 6 | 7 | /* 8 | * This file is part of COVID-19-Telegram-bot. 9 | * 10 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 3 12 | * as published by the Free Software Foundation. 13 | * 14 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * Author(s): 20 | * 21 | * © 2020 Kasra Madadipouya 22 | */ 23 | 24 | public class CoronaStatistics { 25 | 26 | @JsonProperty("countryRegion") 27 | private String country; 28 | 29 | @JsonProperty("provinceState") 30 | private String state; 31 | 32 | private int confirmed; 33 | 34 | private int recovered; 35 | 36 | private int deaths; 37 | 38 | @JsonProperty("iso2") 39 | private String countryCode; 40 | 41 | public CoronaStatistics(String country, String countryCode, int confirmed, int recovered, int deaths) { 42 | this.country = country; 43 | this.countryCode = countryCode; 44 | this.confirmed = confirmed; 45 | this.recovered = recovered; 46 | this.deaths = deaths; 47 | } 48 | 49 | public String getCountry() { 50 | return country; 51 | } 52 | 53 | public String getState() { 54 | return state; 55 | } 56 | 57 | public String getCountryCode() { 58 | return countryCode; 59 | } 60 | 61 | public int getConfirmed() { 62 | return confirmed; 63 | } 64 | 65 | public int getRecovered() { 66 | return recovered; 67 | } 68 | 69 | public int getDeaths() { 70 | return deaths; 71 | } 72 | 73 | public String getAsString() { 74 | return String.format("%s, %s, %s, %s", country, formatThreeDecimal(confirmed), 75 | formatThreeDecimal(deaths), formatThreeDecimal(recovered)); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/type/Sticker.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.type; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | import java.io.Serializable; 6 | 7 | /* 8 | * This file is part of COVID-19-Telegram-bot. 9 | * 10 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 3 12 | * as published by the Free Software Foundation. 13 | * 14 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * Author(s): 20 | * 21 | * © 2020 Kasra Madadipouya 22 | */ 23 | 24 | public class Sticker extends AbstractType implements Serializable { 25 | 26 | private int width; 27 | 28 | private int height; 29 | 30 | @JsonProperty("is_animated") 31 | private boolean animated; 32 | 33 | private String emoji; 34 | 35 | @JsonProperty("set_name") 36 | private String name; 37 | 38 | @JsonProperty("mask_position") 39 | private MaskPosition maskPosition; 40 | 41 | public int getWidth() { 42 | return width; 43 | } 44 | 45 | public int getHeight() { 46 | return height; 47 | } 48 | 49 | public boolean isAnimated() { 50 | return animated; 51 | } 52 | 53 | public String getEmoji() { 54 | return emoji; 55 | } 56 | 57 | public String getName() { 58 | return name; 59 | } 60 | 61 | public MaskPosition getMaskPosition() { 62 | return maskPosition; 63 | } 64 | 65 | public static class MaskPosition implements Serializable { 66 | 67 | private String point; 68 | 69 | @JsonProperty("x_shift") 70 | private double xShift; 71 | 72 | @JsonProperty("y_shift") 73 | private double yShift; 74 | 75 | private double scale; 76 | 77 | public String getPoint() { 78 | return point; 79 | } 80 | 81 | public double getxShift() { 82 | return xShift; 83 | } 84 | 85 | public double getyShift() { 86 | return yShift; 87 | } 88 | 89 | public double getScale() { 90 | return scale; 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/base/ChatPermissions.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.base; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | import java.io.Serializable; 6 | 7 | /* 8 | * This file is part of COVID-19-Telegram-bot. 9 | * 10 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 3 12 | * as published by the Free Software Foundation. 13 | * 14 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * Author(s): 20 | * 21 | * © 2020 Kasra Madadipouya 22 | */ 23 | 24 | public class ChatPermissions implements Serializable { 25 | 26 | @JsonProperty("can_send_messages") 27 | private boolean canSendMessages; 28 | 29 | @JsonProperty("can_send_media_messages") 30 | private boolean canSendMediaMessages; 31 | 32 | @JsonProperty("can_send_polls") 33 | private boolean canSendPolls; 34 | 35 | @JsonProperty("can_send_other_messages") 36 | private boolean canSendOtherMessages; 37 | 38 | @JsonProperty("can_add_web_pages_previews") 39 | private boolean canAddWebPagesPreviews; 40 | 41 | @JsonProperty("can_change_info") 42 | private boolean canChangeInfo; 43 | 44 | @JsonProperty("can_invite_users") 45 | private boolean canInviteUsers; 46 | 47 | @JsonProperty("can_pin_messages") 48 | private boolean canPinMessages; 49 | 50 | public boolean hasPermissionToSendMessages() { 51 | return canSendMessages; 52 | } 53 | 54 | public boolean hasPermissionToSendMediaMessages() { 55 | return canSendMediaMessages; 56 | } 57 | 58 | public boolean hasPermissionToSendPolls() { 59 | return canSendPolls; 60 | } 61 | 62 | public boolean hasPermissionToSendOtherMessages() { 63 | return canSendOtherMessages; 64 | } 65 | 66 | public boolean hasPermissionToAddWebPagesPreviews() { 67 | return canAddWebPagesPreviews; 68 | } 69 | 70 | public boolean hasPermissionToChangeInfo() { 71 | return canChangeInfo; 72 | } 73 | 74 | public boolean hasPermissionToInviteUsers() { 75 | return canInviteUsers; 76 | } 77 | 78 | public boolean hasPermissionToPinMessages() { 79 | return canPinMessages; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/telegram/model/ReplyMessage.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.telegram.model; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.madadipouya.telegram.corona.telegram.model.keyboards.Keyboard; 5 | 6 | /* 7 | * This file is part of COVID-19-Telegram-bot. 8 | * 9 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License version 3 11 | * as published by the Free Software Foundation. 12 | * 13 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * Author(s): 19 | * 20 | * © 2020 Kasra Madadipouya 21 | */ 22 | 23 | public class ReplyMessage { 24 | 25 | @JsonProperty("chat_id") 26 | private final long chatId; 27 | 28 | @JsonProperty("reply_to_message_id") 29 | private final int messageId; 30 | 31 | private final String text; 32 | 33 | @JsonProperty("parse_mode") 34 | private final String textFormat; 35 | 36 | @JsonProperty("disable_web_page_preview") 37 | private final boolean disableWebPagePreview; 38 | 39 | @JsonProperty("reply_markup") 40 | private final Keyboard keyboard; 41 | 42 | public ReplyMessage(long chatId, int messageId, String text, TextFormat textFormat) { 43 | this(chatId, messageId, text, textFormat, null, false); 44 | } 45 | 46 | public ReplyMessage(long chatId, String text, Keyboard keyboard) { 47 | this(chatId, -1, text, TextFormat.PLAIN_TEXT, keyboard, false); 48 | } 49 | 50 | public ReplyMessage(long chatId, int messageId, String text, TextFormat textFormat, 51 | Keyboard keyboard, boolean disableWebPagePreview) { 52 | this.chatId = chatId; 53 | this.text = text; 54 | this.messageId = messageId; 55 | this.textFormat = textFormat.getValue(); 56 | this.keyboard = keyboard; 57 | this.disableWebPagePreview = disableWebPagePreview; 58 | } 59 | 60 | public long getChatId() { 61 | return chatId; 62 | } 63 | 64 | public int getMessageId() { 65 | return messageId; 66 | } 67 | 68 | public String getText() { 69 | return text; 70 | } 71 | 72 | public String getTextFormat() { 73 | return textFormat; 74 | } 75 | 76 | public Keyboard getKeyboard() { 77 | return keyboard; 78 | } 79 | 80 | public boolean isDisableWebPagePreview() { 81 | return disableWebPagePreview; 82 | } 83 | 84 | } 85 | 86 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/virus/integration/openstreetmap/DefaultOpenStreetMapIntegration.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.virus.integration.openstreetmap; 2 | 3 | import com.madadipouya.telegram.corona.virus.integration.openstreetmap.remote.response.OpenStreetMapLocationResponse; 4 | import org.springframework.cache.annotation.Cacheable; 5 | import org.springframework.http.HttpEntity; 6 | import org.springframework.http.HttpHeaders; 7 | import org.springframework.stereotype.Service; 8 | import org.springframework.web.client.RestTemplate; 9 | 10 | import java.util.List; 11 | 12 | import static com.madadipouya.telegram.corona.general.config.CacheManagerConfig.OPEN_STREET_CACHE; 13 | import static java.lang.String.format; 14 | import static org.springframework.http.HttpMethod.GET; 15 | import static org.springframework.http.MediaType.APPLICATION_JSON; 16 | 17 | /* 18 | * This file is part of COVID-19-Telegram-bot. 19 | * 20 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 21 | * it under the terms of the GNU General Public License version 3 22 | * as published by the Free Software Foundation. 23 | * 24 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 25 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27 | * GNU General Public License for more details. 28 | * 29 | * Author(s): 30 | * 31 | * © 2020 Kasra Madadipouya 32 | */ 33 | 34 | @Service 35 | public class DefaultOpenStreetMapIntegration implements OpenStreetMapIntegration { 36 | private static final String API_URL = "https://nominatim.openstreetmap.org/reverse?format=json&lat=%s&lon=%s&zoom=18&addressdetails=1"; 37 | 38 | private final RestTemplate restTemplate; 39 | 40 | public DefaultOpenStreetMapIntegration(RestTemplate restTemplate) { 41 | this.restTemplate = restTemplate; 42 | } 43 | 44 | @Override 45 | @Cacheable(value = OPEN_STREET_CACHE, key = "{ #latitude, #longitude }") 46 | public String getCountryCodeOfGeoLocation(double latitude, double longitude) { 47 | return getReverseGeocoding(latitude, longitude).getAddress().getCountryCode(); 48 | } 49 | 50 | @Override 51 | public OpenStreetMapLocationResponse getReverseGeocoding(double latitude, double longitude) { 52 | HttpHeaders headers = new HttpHeaders(); 53 | headers.setAccept(List.of(APPLICATION_JSON)); 54 | headers.setContentType(APPLICATION_JSON); 55 | headers.set("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:58.0) Gecko/20100101 Firefox/58.0"); 56 | HttpEntity entity = new HttpEntity<>("parameters", headers); 57 | return restTemplate.exchange(format(API_URL, latitude, longitude), 58 | GET, entity, OpenStreetMapLocationResponse.class).getBody(); 59 | } 60 | } -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/base/Chat.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.base; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | import java.io.Serializable; 6 | 7 | /* 8 | * This file is part of COVID-19-Telegram-bot. 9 | * 10 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 3 12 | * as published by the Free Software Foundation. 13 | * 14 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * Author(s): 20 | * 21 | * © 2020 Kasra Madadipouya 22 | */ 23 | 24 | public class Chat implements Serializable { 25 | 26 | private long id; 27 | 28 | // TODO Replace with enum 'Type of chat, can be either “private”, “group”, “supergroup” or “channel”' 29 | private String type; 30 | 31 | private String title; 32 | 33 | private String username; 34 | 35 | @JsonProperty("first_name") 36 | private String firstName; 37 | 38 | @JsonProperty("last_name") 39 | private String lastName; 40 | 41 | private ChatPhoto photo; 42 | 43 | private String description; 44 | 45 | @JsonProperty("invite_link") 46 | private String inviteLink; 47 | 48 | @JsonProperty("pinned_message") 49 | private Message pinnedMessage; 50 | 51 | private ChatPermissions permissions; 52 | 53 | @JsonProperty("sticker_set_name") 54 | private String stickerSetName; 55 | 56 | @JsonProperty("can_set_sticker_set") 57 | private boolean stickerSetAssignable; 58 | 59 | public long getId() { 60 | return id; 61 | } 62 | 63 | public String getType() { 64 | return type; 65 | } 66 | 67 | public String getTitle() { 68 | return title; 69 | } 70 | 71 | public String getUsername() { 72 | return username; 73 | } 74 | 75 | public String getFirstName() { 76 | return firstName; 77 | } 78 | 79 | public String getLastName() { 80 | return lastName; 81 | } 82 | 83 | public ChatPhoto getPhoto() { 84 | return photo; 85 | } 86 | 87 | public String getDescription() { 88 | return description; 89 | } 90 | 91 | public String getInviteLink() { 92 | return inviteLink; 93 | } 94 | 95 | public Message getPinnedMessage() { 96 | return pinnedMessage; 97 | } 98 | 99 | public ChatPermissions getPermissions() { 100 | return permissions; 101 | } 102 | 103 | public String getStickerSetName() { 104 | return stickerSetName; 105 | } 106 | 107 | public boolean isStickerSetAssignable() { 108 | return stickerSetAssignable; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/telegram/model/keyboards/ReplyKeyboardMarkup.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.telegram.model.keyboards; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | 5 | import java.util.List; 6 | 7 | /* 8 | * This file is part of COVID-19-Telegram-bot. 9 | * 10 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License version 3 12 | * as published by the Free Software Foundation. 13 | * 14 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * Author(s): 20 | * 21 | * © 2020 Kasra Madadipouya 22 | */ 23 | 24 | public class ReplyKeyboardMarkup implements Keyboard { 25 | 26 | @JsonProperty("keyboard") 27 | private final List> keyboards; 28 | 29 | @JsonProperty("resize_keyboard") 30 | private final boolean resizeKeyboard; 31 | 32 | @JsonProperty("one_time_keyboard") 33 | private final boolean oneTimeKeyboard; 34 | 35 | private final boolean selective; 36 | 37 | protected ReplyKeyboardMarkup(KeyboardButton keyboardButton, boolean resizeKeyboard, boolean oneTimeKeyboard, boolean selective) { 38 | this(List.of(keyboardButton), resizeKeyboard, oneTimeKeyboard, selective); 39 | } 40 | 41 | protected ReplyKeyboardMarkup(List keyboards, boolean resizeKeyboard, boolean oneTimeKeyboard, boolean selective) { 42 | this.keyboards = List.of(keyboards); 43 | this.resizeKeyboard = resizeKeyboard; 44 | this.oneTimeKeyboard = oneTimeKeyboard; 45 | this.selective = selective; 46 | } 47 | 48 | public List> getKeyboards() { 49 | return keyboards; 50 | } 51 | 52 | public boolean isResizeKeyboard() { 53 | return resizeKeyboard; 54 | } 55 | 56 | public boolean isOneTimeKeyboard() { 57 | return oneTimeKeyboard; 58 | } 59 | 60 | public boolean isSelective() { 61 | return selective; 62 | } 63 | 64 | 65 | public static class KeyboardButton { 66 | 67 | private final String text; 68 | 69 | @JsonProperty("request_contact") 70 | private final boolean requestContact; 71 | 72 | @JsonProperty("request_location") 73 | private final boolean requestLocation; 74 | 75 | public KeyboardButton(String text, boolean requestContact, boolean requestLocation) { 76 | this.text = text; 77 | this.requestContact = requestContact; 78 | this.requestLocation = requestLocation; 79 | } 80 | 81 | public String getText() { 82 | return text; 83 | } 84 | 85 | public boolean isRequestContact() { 86 | return requestContact; 87 | } 88 | 89 | public boolean isRequestLocation() { 90 | return requestLocation; 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # COVID-19-Telegram-bot 2 | A Telegram bot to get latest progress on COVID-19 3 | 4 | ## Architecture 5 | 6 | The project is written with on Spring Boot. No Telegram library, framework or whatsoever is used in this project. 7 | All the telegram integration is done through direct REST calls. 8 | 9 | ## Data source 10 | The [@covid19_update_bot](https://telegram.me/covid19_update_bot) bot gets data from [covid-19-api](https://github.com/mathdroid/covid-19-api) created by Muhammad Mustadi. Data is scrapped from [John Hopkins University CSSE](https://coronavirus.jhu.edu/map.html). 11 | 12 | ## How to set up the project 13 | 14 | ### Prerequisites 15 | 16 | - JDK 11 17 | 18 | ### Run in local 19 | 20 | Follow the steps to get it run in local. 21 | 22 | #### Add tokens to `application.properties` 23 | 24 | Set Telegram token in `application.properties`. 25 | 26 | Or alternatively export them as environment variable. For example, 27 | 28 | ```bash 29 | $ export TELEGRAM_TOKEN=[telegram_token] 30 | ``` 31 | 32 | #### Run the application 33 | 34 | Run the project in console, 35 | 36 | ```bash 37 | $ ./mvnw spring-boot:run 38 | ``` 39 | 40 | #### Run Ngrok 41 | 42 | Download Ngrok from [here](https://ngrok.com/download) and run it as follow, 43 | 44 | ```bash 45 | $ ./ngrok http 8080 46 | ``` 47 | 48 | #### Update Telegram hook 49 | 50 | Update the bot hook using `hook-update.sh`. 51 | 52 | Before running the script, export the following environment variables, 53 | 54 | ```bash 55 | $ export URL=[ngrok_url] 56 | $ export TOKEN=[bot_token] 57 | ``` 58 | 59 | And finally run the script, 60 | 61 | ```bash 62 | $ ./hook_update.sh 63 | ``` 64 | 65 | ### Mimic production environment 66 | 67 | To mimic the production environment, run the project with the `production` profile as follows, 68 | 69 | ```bash 70 | $ ./mvnw spring-boot:run -Pproduction 71 | ``` 72 | 73 | ### Production deployment 74 | 75 | To deploy the project to production, ensure the following environment variable is exported, 76 | 77 | ```bash 78 | SPRING_PROFILES_ACTIVE = production 79 | ``` 80 | 81 | The rest of the process is more or less similar to run the project in local. 82 | 83 | 84 | ## Important notes 85 | 86 | - In production profile, swagger-ui is disabled. 87 | - Only API calls that come from Telegram servers are accepted, the rest is ignored, see `SecurityConfig.java`. 88 | 89 | ## Support 90 | 91 | Check my site [@geekyhacker.com](https://geekyhacker.com) 92 | 93 | ## Contact 94 | * kasra@madadipouya.com 95 | 96 | ## License 97 |

98 | License 99 |

100 | COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 101 | it under the terms of the GNU General Public License version 3 102 | as published by the Free Software Foundation. 103 | 104 | COVID-19-Telegram-bot is distributed in the hope that it will be useful, 105 | but WITHOUT ANY WARRANTY; without even the implied warranty of 106 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 107 | GNU General Public License for more details. 108 | 109 | Author(s): 110 | 111 | © 2020 Kasra Madadipouya 112 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/virus/command/CoronaInlineEnquiryCommandHandler.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.virus.command; 2 | 3 | import com.madadipouya.telegram.corona.virus.integration.mathdro.MathdroIntegration; 4 | import com.madadipouya.telegram.corona.virus.integration.mathdro.remote.response.CoronaStatistics; 5 | import com.madadipouya.telegram.corona.i18n.service.I18nService; 6 | import com.madadipouya.telegram.corona.telegram.TelegramService; 7 | import com.madadipouya.telegram.corona.telegram.model.TextFormat; 8 | import com.madadipouya.telegram.corona.telegram.model.inlinequery.result.InlineQueryResultArticle; 9 | import org.apache.commons.lang3.StringUtils; 10 | import org.springframework.stereotype.Component; 11 | 12 | import java.util.List; 13 | import java.util.UUID; 14 | import java.util.stream.Collectors; 15 | 16 | import static com.madadipouya.telegram.corona.utils.NumberUtils.formatThreeDecimal; 17 | 18 | /* 19 | * This file is part of COVID-19-Telegram-bot. 20 | * 21 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 22 | * it under the terms of the GNU General Public License version 3 23 | * as published by the Free Software Foundation. 24 | * 25 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 | * GNU General Public License for more details. 29 | * 30 | * Author(s): 31 | * 32 | * © 2020 Kasra Madadipouya 33 | */ 34 | 35 | @Component 36 | public class CoronaInlineEnquiryCommandHandler { 37 | 38 | private final MathdroIntegration mathdroIntegration; 39 | 40 | private final TelegramService telegramService; 41 | 42 | private final I18nService i18nService; 43 | 44 | public CoronaInlineEnquiryCommandHandler(MathdroIntegration mathdroIntegration, TelegramService telegramService, 45 | I18nService i18nService) { 46 | this.mathdroIntegration = mathdroIntegration; 47 | this.telegramService = telegramService; 48 | this.i18nService = i18nService; 49 | } 50 | 51 | 52 | public void handle(String id, String query) { 53 | if(StringUtils.isNotBlank(query)) { 54 | List results = mathdroIntegration.getLatestCoronaStatistics().stream() 55 | .filter(r -> StringUtils.startsWithIgnoreCase(r.getCountry(), query)).limit(50) 56 | .map(r -> new InlineQueryResultArticle(UUID.randomUUID().toString(), 57 | r.getCountry(), constructDescription(r), TextFormat.MARK_DOWN)) 58 | .collect(Collectors.toList()); 59 | telegramService.replyInlineQueryArticles(id, results); 60 | } 61 | } 62 | 63 | private String constructDescription(CoronaStatistics coronaStatistics) { 64 | return String.format("*Country:* %s %n*Confirmed:* %s %n*Deaths:* %s %n*Recovered:* %s", 65 | coronaStatistics.getCountry(), formatThreeDecimal(coronaStatistics.getConfirmed()), 66 | formatThreeDecimal(coronaStatistics.getDeaths()), 67 | formatThreeDecimal(coronaStatistics.getRecovered())); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/virus/command/CoronaVirusLatestDevelopmentCommand.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.virus.command; 2 | 3 | import com.madadipouya.telegram.corona.telegram.model.ActionType; 4 | import com.madadipouya.telegram.corona.virus.integration.mathdro.MathdroIntegration; 5 | import com.madadipouya.telegram.corona.general.command.BotCommand; 6 | import com.madadipouya.telegram.corona.general.command.CommandType; 7 | import com.madadipouya.telegram.corona.general.rest.dto.base.Message; 8 | import com.madadipouya.telegram.corona.i18n.service.I18nService; 9 | import com.madadipouya.telegram.corona.telegram.TelegramService; 10 | import com.madadipouya.telegram.corona.telegram.model.TextFormat; 11 | import org.springframework.stereotype.Component; 12 | 13 | /* 14 | * This file is part of COVID-19-Telegram-bot. 15 | * 16 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 17 | * it under the terms of the GNU General Public License version 3 18 | * as published by the Free Software Foundation. 19 | * 20 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | * GNU General Public License for more details. 24 | * 25 | * Author(s): 26 | * 27 | * © 2020 Kasra Madadipouya 28 | */ 29 | 30 | @Component 31 | public class CoronaVirusLatestDevelopmentCommand implements BotCommand { 32 | 33 | private final MathdroIntegration mathdroIntegration; 34 | 35 | private final TelegramService telegramService; 36 | 37 | private final I18nService i18nService; 38 | 39 | public CoronaVirusLatestDevelopmentCommand(MathdroIntegration mathdroIntegration, TelegramService telegramService, 40 | I18nService i18nService) { 41 | this.mathdroIntegration = mathdroIntegration; 42 | this.telegramService = telegramService; 43 | this.i18nService = i18nService; 44 | } 45 | 46 | @Override 47 | public void execute(Message message, String argument) { 48 | telegramService.sendAction(message.getChat().getId(), ActionType.TYPING); 49 | StringBuilder replyMessage = new StringBuilder("```"); 50 | mathdroIntegration.getLatestCoronaStatisticsFlat().forEach(row -> { 51 | if(replyMessage.length() > 3800) { 52 | replyMessage.append("\n```"); 53 | replyMessage.append(i18nService.getMessage("command.corona.virus.latest.statistics.reply")); 54 | telegramService.reply(message.getChat().getId(), replyMessage.toString(), TextFormat.MARK_DOWN); 55 | replyMessage.setLength(0); 56 | replyMessage.append("```"); 57 | } 58 | replyMessage.append(String.format("%n%s",row)); 59 | }); 60 | replyMessage.append("\n```"); 61 | replyMessage.append(i18nService.getMessage("command.corona.virus.latest.statistics.reply")); 62 | telegramService.reply(message.getChat().getId(), replyMessage.toString(), TextFormat.MARK_DOWN); 63 | } 64 | 65 | @Override 66 | public CommandType getSupportedType() { 67 | return CommandType.CORONA_VIRUS_LATEST; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/config/CacheManagerConfig.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.config; 2 | 3 | import com.github.benmanes.caffeine.cache.Caffeine; 4 | import com.github.benmanes.caffeine.cache.RemovalCause; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.cache.CacheManager; 8 | import org.springframework.cache.annotation.CacheEvict; 9 | import org.springframework.cache.annotation.EnableCaching; 10 | import org.springframework.cache.caffeine.CaffeineCache; 11 | import org.springframework.cache.support.SimpleCacheManager; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.scheduling.annotation.Scheduled; 15 | 16 | import java.util.List; 17 | import java.util.concurrent.TimeUnit; 18 | 19 | /* 20 | * This file is part of COVID-19-Telegram-bot. 21 | * 22 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 23 | * it under the terms of the GNU General Public License version 3 24 | * as published by the Free Software Foundation. 25 | * 26 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 27 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 28 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 29 | * GNU General Public License for more details. 30 | * 31 | * Author(s): 32 | * 33 | * © 2020 Kasra Madadipouya 34 | */ 35 | 36 | @Configuration 37 | @EnableCaching 38 | public class CacheManagerConfig { 39 | 40 | private final Logger logger = LoggerFactory.getLogger(CacheManagerConfig.class); 41 | 42 | public static final String OPEN_STREET_CACHE = "openStreetCache"; 43 | 44 | public static final String CORONA_ALL_STATISTICS_CACHE = "coronaAllStatisticsCache"; 45 | 46 | public static final String CORONA_ALL_STATISTICS_FLAT_CACHE = "coronaAllStatisticsCacheFlat"; 47 | 48 | public static final String CORONA_COUNTRY_STATISTICS_CACHE = "coronaCountryStatisticsCache"; 49 | 50 | @Bean 51 | public CacheManager cacheManager() { 52 | SimpleCacheManager cacheManager = new SimpleCacheManager(); 53 | 54 | CaffeineCache openStreetCache = new CaffeineCache(OPEN_STREET_CACHE, Caffeine.newBuilder() 55 | .maximumSize(1000) 56 | .expireAfterWrite(30, TimeUnit.MINUTES) 57 | .build()); 58 | 59 | CaffeineCache coronaAllStatisticsCache = new CaffeineCache(CORONA_ALL_STATISTICS_CACHE, Caffeine.newBuilder() 60 | .maximumSize(10) 61 | .build()); 62 | 63 | CaffeineCache coronaAllStatisticsFlatCache = new CaffeineCache(CORONA_ALL_STATISTICS_FLAT_CACHE, Caffeine.newBuilder() 64 | .maximumSize(10) 65 | .build()); 66 | 67 | CaffeineCache coronaCountryStatisticsCache = new CaffeineCache(CORONA_COUNTRY_STATISTICS_CACHE, Caffeine.newBuilder() 68 | .maximumSize(1000) 69 | .build()); 70 | 71 | cacheManager.setCaches(List.of(openStreetCache, coronaAllStatisticsCache, coronaAllStatisticsFlatCache, coronaCountryStatisticsCache)); 72 | return cacheManager; 73 | } 74 | 75 | // run every 30 minutes 76 | @Scheduled(cron = "0 0/30 * * * ?") 77 | @CacheEvict(value = {CORONA_ALL_STATISTICS_CACHE, CORONA_ALL_STATISTICS_FLAT_CACHE, CORONA_COUNTRY_STATISTICS_CACHE}, allEntries = true) 78 | public void evictCoronaCaches() { 79 | logger.info("Evicted all Corona caches!"); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/virus/command/MyLocationCoronaVirusCommand.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.virus.command; 2 | 3 | import com.madadipouya.telegram.corona.telegram.model.ActionType; 4 | import com.madadipouya.telegram.corona.virus.integration.mathdro.MathdroIntegration; 5 | import com.madadipouya.telegram.corona.virus.integration.openstreetmap.OpenStreetMapIntegration; 6 | import com.madadipouya.telegram.corona.general.command.BotCommand; 7 | import com.madadipouya.telegram.corona.general.command.CommandType; 8 | import com.madadipouya.telegram.corona.general.rest.dto.base.Message; 9 | import com.madadipouya.telegram.corona.i18n.service.I18nService; 10 | import com.madadipouya.telegram.corona.telegram.TelegramService; 11 | import org.springframework.stereotype.Component; 12 | 13 | import static com.madadipouya.telegram.corona.general.command.CommandType.CORONA_VIRUS_MY_LOCATION_UPDATE; 14 | import static com.madadipouya.telegram.corona.telegram.model.TextFormat.MARK_DOWN; 15 | 16 | /* 17 | * This file is part of COVID-19-Telegram-bot. 18 | * 19 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 20 | * it under the terms of the GNU General Public License version 3 21 | * as published by the Free Software Foundation. 22 | * 23 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 24 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 25 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26 | * GNU General Public License for more details. 27 | * 28 | * Author(s): 29 | * 30 | * © 2020 Kasra Madadipouya 31 | */ 32 | 33 | @Component 34 | public class MyLocationCoronaVirusCommand implements BotCommand { 35 | 36 | private final TelegramService telegramService; 37 | 38 | private final I18nService i18nService; 39 | 40 | private final OpenStreetMapIntegration openStreetMapIntegration; 41 | 42 | private MathdroIntegration mathdroIntegration; 43 | 44 | public MyLocationCoronaVirusCommand(TelegramService telegramService, I18nService i18nService, 45 | OpenStreetMapIntegration openStreetMapIntegration, MathdroIntegration mathdroIntegration) { 46 | this.telegramService = telegramService; 47 | this.i18nService = i18nService; 48 | this.openStreetMapIntegration = openStreetMapIntegration; 49 | this.mathdroIntegration = mathdroIntegration; 50 | } 51 | 52 | @Override 53 | public void execute(Message message, String argument) { 54 | if (hasLocationInfo(message)) { 55 | telegramService.sendAction(message.getChat().getId(), ActionType.FIND_LOCATION); 56 | String countryCode = openStreetMapIntegration.getCountryCodeOfGeoLocation(message.getLocation().getLatitude(), message.getLocation().getLongitude()); 57 | telegramService.reply(message.getChat().getId(), getCoronaVirusStatsForCountry(countryCode), MARK_DOWN); 58 | } else { 59 | telegramService.askLocation(message.getChat().getId(), i18nService.getMessage("command.corona.virus.location", CORONA_VIRUS_MY_LOCATION_UPDATE.getValue())); 60 | } 61 | } 62 | 63 | private String getCoronaVirusStatsForCountry(String countryCode) { 64 | return String.format("%s%n```%n%s%n```", 65 | i18nService.getMessage("command.corona.virus.latest.statistics.reply"), 66 | mathdroIntegration.getLatestCoronaStatisticsByCountry(countryCode)); 67 | } 68 | 69 | @Override 70 | public CommandType getSupportedType() { 71 | return CORONA_VIRUS_MY_LOCATION_UPDATE; 72 | } 73 | 74 | private boolean hasLocationInfo(Message message) { 75 | return message.getLocation() != null; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/Update.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.madadipouya.telegram.corona.general.rest.dto.base.CallbackQuery; 5 | import com.madadipouya.telegram.corona.general.rest.dto.base.ChosenInlineResult; 6 | import com.madadipouya.telegram.corona.general.rest.dto.base.InlineQuery; 7 | import com.madadipouya.telegram.corona.general.rest.dto.base.Message; 8 | import com.madadipouya.telegram.corona.general.rest.dto.internal.CommandArgumentPair; 9 | 10 | import java.io.Serializable; 11 | import java.util.List; 12 | import java.util.Objects; 13 | import java.util.stream.Stream; 14 | 15 | /* 16 | * This file is part of COVID-19-Telegram-bot. 17 | * 18 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 19 | * it under the terms of the GNU General Public License version 3 20 | * as published by the Free Software Foundation. 21 | * 22 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 | * GNU General Public License for more details. 26 | * 27 | * Author(s): 28 | * 29 | * © 2020 Kasra Madadipouya 30 | */ 31 | 32 | public class Update implements Serializable { 33 | 34 | @JsonProperty("update_id") 35 | private int updateId; 36 | 37 | private Message message; 38 | 39 | @JsonProperty("edited_message") 40 | private Message editedMessage; 41 | 42 | @JsonProperty("channel_post") 43 | private Message channelPost; 44 | 45 | @JsonProperty("edited_channel_post") 46 | private Message editedChannelPost; 47 | 48 | @JsonProperty("inline_query") 49 | private InlineQuery inlineQuery; 50 | 51 | @JsonProperty("chosen_inline_result") 52 | private ChosenInlineResult chosenInlineResult; 53 | 54 | @JsonProperty("callback_query") 55 | private CallbackQuery callbackQuery; 56 | 57 | private List commandArgumentPairs; 58 | 59 | // TODO support inline, etc. https://core.telegram.org/bots/api#update 60 | 61 | private void setUpdateId(int updateId) { 62 | this.updateId = updateId; 63 | } 64 | 65 | private void setMessage(Message message) { 66 | this.message = message; 67 | } 68 | 69 | private void setEditedMessage(Message editedMessage) { 70 | this.editedMessage = editedMessage; 71 | } 72 | 73 | private void setChannelPost(Message channelPost) { 74 | this.channelPost = channelPost; 75 | } 76 | 77 | private void setEditedChannelPost(Message editedChannelPost) { 78 | this.editedChannelPost = editedChannelPost; 79 | } 80 | 81 | public CallbackQuery getCallbackQuery() { 82 | return callbackQuery; 83 | } 84 | 85 | public boolean hasCallbackQuery() { 86 | return Objects.nonNull(callbackQuery); 87 | } 88 | 89 | private void setCallbackQuery(CallbackQuery callbackQuery) { 90 | this.callbackQuery = callbackQuery; 91 | } 92 | 93 | public List getCommandArgumentPairs() { 94 | return commandArgumentPairs; 95 | } 96 | 97 | public void setCommandArgumentPairs(List commandArgumentPairs) { 98 | this.commandArgumentPairs = commandArgumentPairs; 99 | } 100 | 101 | public Message getFirstAvailableMessage() { 102 | return getMessages().filter(Objects::nonNull).findFirst().orElse(new Message()); 103 | } 104 | 105 | public boolean hasInlineQuery() { 106 | return (inlineQuery != null) && message == null && editedMessage == null && callbackQuery == null; 107 | } 108 | 109 | private Stream getMessages() { 110 | return Stream.of(message, editedMessage, channelPost, editedChannelPost).filter(Objects::nonNull); 111 | } 112 | 113 | public InlineQuery getInlineQuery() { 114 | return inlineQuery; 115 | } 116 | 117 | public ChosenInlineResult getChosenInlineResult() { 118 | return chosenInlineResult; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/virus/integration/mathdro/impl/DefaultMathdroIntegration.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.virus.integration.mathdro.impl; 2 | 3 | import com.madadipouya.telegram.corona.virus.integration.mathdro.MathdroIntegration; 4 | import com.madadipouya.telegram.corona.virus.integration.mathdro.remote.response.CoronaStatistics; 5 | import org.apache.commons.lang3.StringUtils; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.cache.annotation.Cacheable; 8 | import org.springframework.core.ParameterizedTypeReference; 9 | import org.springframework.http.HttpMethod; 10 | import org.springframework.http.ResponseEntity; 11 | import org.springframework.stereotype.Service; 12 | import org.springframework.web.client.RestTemplate; 13 | 14 | import java.util.LinkedHashMap; 15 | import java.util.List; 16 | import java.util.Map; 17 | import java.util.Set; 18 | import java.util.stream.Collectors; 19 | 20 | import static com.madadipouya.telegram.corona.general.config.CacheManagerConfig.CORONA_ALL_STATISTICS_CACHE; 21 | import static com.madadipouya.telegram.corona.general.config.CacheManagerConfig.CORONA_ALL_STATISTICS_FLAT_CACHE; 22 | import static com.madadipouya.telegram.corona.general.config.CacheManagerConfig.CORONA_COUNTRY_STATISTICS_CACHE; 23 | import static com.madadipouya.telegram.corona.utils.StringUtils.getOrDefaultEmpty; 24 | 25 | /* 26 | * This file is part of COVID-19-Telegram-bot. 27 | * 28 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 29 | * it under the terms of the GNU General Public License version 3 30 | * as published by the Free Software Foundation. 31 | * 32 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 33 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 34 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 35 | * GNU General Public License for more details. 36 | * 37 | * Author(s): 38 | * 39 | * © 2020 Kasra Madadipouya 40 | */ 41 | 42 | @Service 43 | public class DefaultMathdroIntegration implements MathdroIntegration { 44 | 45 | private static final String API_URL = "https://covid19.mathdro.id/api/confirmed"; 46 | 47 | private static final Set AUTONOMOUS_STATES = Set.of("Hong Kong", "Macau"); 48 | 49 | private final RestTemplate restTemplate; 50 | 51 | @Autowired 52 | private MathdroIntegration self; 53 | 54 | public DefaultMathdroIntegration(RestTemplate restTemplate) { 55 | this.restTemplate = restTemplate; 56 | } 57 | 58 | @Override 59 | @Cacheable(value = CORONA_ALL_STATISTICS_FLAT_CACHE) 60 | public List getLatestCoronaStatisticsFlat() { 61 | return self.getLatestCoronaStatistics().stream().map(CoronaStatistics::getAsString).collect(Collectors.toList()); 62 | } 63 | 64 | @Override 65 | @Cacheable(value = CORONA_ALL_STATISTICS_CACHE) 66 | public List getLatestCoronaStatistics() { 67 | ResponseEntity> responseEntity = restTemplate.exchange(API_URL, HttpMethod.GET, 68 | null, new ParameterizedTypeReference>() { 69 | }); 70 | if (!responseEntity.getStatusCode().is2xxSuccessful() || responseEntity.getBody() == null) { 71 | return List.of(); 72 | } 73 | Map results = new LinkedHashMap<>(); 74 | List coronaStatistics = responseEntity.getBody(); 75 | coronaStatistics.forEach(coronaRecord -> { 76 | if (AUTONOMOUS_STATES.contains(getOrDefaultEmpty(coronaRecord.getState()))) { 77 | results.put(coronaRecord.getState(), new CoronaStatistics(coronaRecord.getState(), 78 | coronaRecord.getCountryCode(), coronaRecord.getConfirmed(), coronaRecord.getRecovered(), 79 | coronaRecord.getDeaths())); 80 | } else { 81 | results.merge(coronaRecord.getCountry(), coronaRecord, (v1, v2) -> 82 | new CoronaStatistics(v1.getCountry(), v1.getCountryCode(), 83 | v1.getConfirmed() + v2.getConfirmed(), 84 | v1.getRecovered() + v2.getRecovered(), 85 | v1.getDeaths() + v2.getDeaths())); 86 | } 87 | }); 88 | return results.values().stream() 89 | .sorted((o1, o2) -> o1.getConfirmed() < o2.getConfirmed() ? -1 : o1 == o2 || o1.getConfirmed() == o2.getConfirmed() ? 0 : 1) 90 | .collect(Collectors.toList()); 91 | } 92 | 93 | @Override 94 | @Cacheable(value = CORONA_COUNTRY_STATISTICS_CACHE, key = "{ #countryCode }") 95 | public String getLatestCoronaStatisticsByCountry(String countryCode) { 96 | return self.getLatestCoronaStatistics().stream().filter(r -> StringUtils.equalsAnyIgnoreCase(countryCode, r.getCountryCode())) 97 | .findFirst().map(CoronaStatistics::getAsString).orElse(StringUtils.EMPTY); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/virus/integration/openstreetmap/remote/response/OpenStreetMapLocationResponse.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.virus.integration.openstreetmap.remote.response; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | 6 | import java.util.List; 7 | 8 | /* 9 | * This file is part of COVID-19-Telegram-bot. 10 | * 11 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License version 3 13 | * as published by the Free Software Foundation. 14 | * 15 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * Author(s): 21 | * 22 | * © 2020 Kasra Madadipouya 23 | */ 24 | 25 | @JsonIgnoreProperties(ignoreUnknown = true) 26 | public class OpenStreetMapLocationResponse { 27 | 28 | public OpenStreetMapLocationResponse() { 29 | this.address = null; 30 | this.boundingBox = null; 31 | this.displayName = ""; 32 | this.latitude = ""; 33 | this.longitude = ""; 34 | this.license = ""; 35 | this.osmId = ""; 36 | this.osmType = ""; 37 | } 38 | 39 | @JsonProperty("place_id") 40 | private String placeId; 41 | 42 | @JsonProperty("license") 43 | private String license; 44 | 45 | @JsonProperty("osm_type") 46 | private String osmType; 47 | 48 | @JsonProperty("osm_id") 49 | private String osmId; 50 | 51 | @JsonProperty("lat") 52 | private String latitude; 53 | 54 | @JsonProperty("lon") 55 | private String longitude; 56 | 57 | @JsonProperty("display_name") 58 | private String displayName; 59 | 60 | @JsonProperty("address") 61 | private Address address; 62 | 63 | @JsonProperty("boundingbox") 64 | private List boundingBox; 65 | 66 | public String getPlaceId() { 67 | return placeId; 68 | } 69 | 70 | public void setPlaceId(String placeId) { 71 | this.placeId = placeId; 72 | } 73 | 74 | public String getLicense() { 75 | return license; 76 | } 77 | 78 | public void setLicense(String license) { 79 | this.license = license; 80 | } 81 | 82 | public String getOsmType() { 83 | return osmType; 84 | } 85 | 86 | public void setOsmType(String osmType) { 87 | this.osmType = osmType; 88 | } 89 | 90 | public String getOsmId() { 91 | return osmId; 92 | } 93 | 94 | public void setOsmId(String osmId) { 95 | this.osmId = osmId; 96 | } 97 | 98 | public String getLatitude() { 99 | return latitude; 100 | } 101 | 102 | public void setLatitude(String latitude) { 103 | this.latitude = latitude; 104 | } 105 | 106 | public String getLongitude() { 107 | return longitude; 108 | } 109 | 110 | public void setLongitude(String longitude) { 111 | this.longitude = longitude; 112 | } 113 | 114 | public String getDisplayName() { 115 | return displayName; 116 | } 117 | 118 | public void setDisplayName(String displayName) { 119 | this.displayName = displayName; 120 | } 121 | 122 | public Address getAddress() { 123 | return address; 124 | } 125 | 126 | public void setAddress(Address address) { 127 | this.address = address; 128 | } 129 | 130 | public List getBoundingBox() { 131 | return boundingBox; 132 | } 133 | 134 | public void setBoundingBox(List boundingBox) { 135 | this.boundingBox = boundingBox; 136 | } 137 | 138 | public static class Address { 139 | 140 | public Address() { 141 | this.country = ""; 142 | this.countryCode = ""; 143 | this.road = ""; 144 | this.state = ""; 145 | } 146 | 147 | private String road; 148 | private String state; 149 | private String country; 150 | @JsonProperty("country_code") 151 | private String countryCode; 152 | 153 | public String getRoad() { 154 | return road; 155 | } 156 | 157 | public void setRoad(String road) { 158 | this.road = road; 159 | } 160 | 161 | public String getState() { 162 | return state; 163 | } 164 | 165 | public void setState(String state) { 166 | this.state = state; 167 | } 168 | 169 | public String getCountry() { 170 | return country; 171 | } 172 | 173 | public void setCountry(String country) { 174 | this.country = country; 175 | } 176 | 177 | public String getCountryCode() { 178 | return countryCode; 179 | } 180 | 181 | public void setCountryCode(String countryCode) { 182 | this.countryCode = countryCode; 183 | } 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2019 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import java.net.*; 18 | import java.io.*; 19 | import java.nio.channels.*; 20 | import java.util.Properties; 21 | 22 | public class MavenWrapperDownloader { 23 | 24 | private static final String WRAPPER_VERSION = "0.5.5"; 25 | /** 26 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 27 | */ 28 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" 29 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; 30 | 31 | /** 32 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 33 | * use instead of the default one. 34 | */ 35 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 36 | ".mvn/wrapper/maven-wrapper.properties"; 37 | 38 | /** 39 | * Path where the maven-wrapper.jar will be saved to. 40 | */ 41 | private static final String MAVEN_WRAPPER_JAR_PATH = 42 | ".mvn/wrapper/maven-wrapper.jar"; 43 | 44 | /** 45 | * Name of the property which should be used to override the default download url for the wrapper. 46 | */ 47 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 48 | 49 | public static void main(String args[]) { 50 | System.out.println("- Downloader started"); 51 | File baseDirectory = new File(args[0]); 52 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 53 | 54 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 55 | // wrapperUrl parameter. 56 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 57 | String url = DEFAULT_DOWNLOAD_URL; 58 | if (mavenWrapperPropertyFile.exists()) { 59 | FileInputStream mavenWrapperPropertyFileInputStream = null; 60 | try { 61 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 62 | Properties mavenWrapperProperties = new Properties(); 63 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 64 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 65 | } catch (IOException e) { 66 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 67 | } finally { 68 | try { 69 | if (mavenWrapperPropertyFileInputStream != null) { 70 | mavenWrapperPropertyFileInputStream.close(); 71 | } 72 | } catch (IOException e) { 73 | // Ignore ... 74 | } 75 | } 76 | } 77 | System.out.println("- Downloading from: " + url); 78 | 79 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 80 | if (!outputFile.getParentFile().exists()) { 81 | if (!outputFile.getParentFile().mkdirs()) { 82 | System.out.println( 83 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 84 | } 85 | } 86 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 87 | try { 88 | downloadFileFromURL(url, outputFile); 89 | System.out.println("Done"); 90 | System.exit(0); 91 | } catch (Throwable e) { 92 | System.out.println("- Error downloading"); 93 | e.printStackTrace(); 94 | System.exit(1); 95 | } 96 | } 97 | 98 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 99 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { 100 | String username = System.getenv("MVNW_USERNAME"); 101 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); 102 | Authenticator.setDefault(new Authenticator() { 103 | @Override 104 | protected PasswordAuthentication getPasswordAuthentication() { 105 | return new PasswordAuthentication(username, password); 106 | } 107 | }); 108 | } 109 | URL website = new URL(urlString); 110 | ReadableByteChannel rbc; 111 | rbc = Channels.newChannel(website.openStream()); 112 | FileOutputStream fos = new FileOutputStream(destination); 113 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 114 | fos.close(); 115 | rbc.close(); 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/telegram/impl/DefaultTelegramService.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.telegram.impl; 2 | 3 | import com.madadipouya.telegram.corona.telegram.TelegramService; 4 | import com.madadipouya.telegram.corona.telegram.model.ActionType; 5 | import com.madadipouya.telegram.corona.telegram.model.ChatAction; 6 | import com.madadipouya.telegram.corona.telegram.model.ReplyMessage; 7 | import com.madadipouya.telegram.corona.telegram.model.TextFormat; 8 | import com.madadipouya.telegram.corona.telegram.model.inlinequery.reply.InlineQueryReplyMessage; 9 | import com.madadipouya.telegram.corona.telegram.model.inlinequery.result.InlineQueryResultArticle; 10 | import com.madadipouya.telegram.corona.telegram.model.keyboards.Keyboard; 11 | import com.madadipouya.telegram.corona.telegram.model.keyboards.LocationKeyboard; 12 | import com.madadipouya.telegram.corona.telegram.model.keyboards.RemoveKeyboard; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | import org.springframework.beans.factory.annotation.Value; 16 | import org.springframework.stereotype.Service; 17 | import org.springframework.web.client.HttpStatusCodeException; 18 | import org.springframework.web.client.RestTemplate; 19 | 20 | import java.util.List; 21 | 22 | import static java.lang.String.format; 23 | 24 | /* 25 | * This file is part of COVID-19-Telegram-bot. 26 | * 27 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 28 | * it under the terms of the GNU General Public License version 3 29 | * as published by the Free Software Foundation. 30 | * 31 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 32 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 33 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 34 | * GNU General Public License for more details. 35 | * 36 | * Author(s): 37 | * 38 | * © 2020 Kasra Madadipouya 39 | */ 40 | 41 | @Service 42 | public class DefaultTelegramService implements TelegramService { 43 | 44 | private static final String BASE_URL = "https://api.telegram.org/bot%s/%s"; 45 | 46 | private static final String SEND_MESSAGE = "sendMessage"; 47 | 48 | private static final String ANSWER_INLINE_QUERY = "answerInlineQuery"; 49 | 50 | private static final String CANCEL_MESSAGE = "Affirmative"; 51 | 52 | private static final String SEND_CHAT_ACTION = "sendChatAction"; 53 | 54 | private static final Logger logger = LoggerFactory.getLogger(DefaultTelegramService.class); 55 | 56 | @Value("${telegram.token}") 57 | private String token; 58 | 59 | private final RestTemplate restTemplate; 60 | 61 | public DefaultTelegramService(RestTemplate restTemplate) { 62 | this.restTemplate = restTemplate; 63 | } 64 | 65 | @Override 66 | public void reply(long to, String text, TextFormat format) { 67 | replyInternal(to, 0, text, format, new RemoveKeyboard()); 68 | } 69 | 70 | @Override 71 | public void askLocation(long to, String text) { 72 | replyInternal(to, 0, text, TextFormat.PLAIN_TEXT, new LocationKeyboard()); 73 | } 74 | 75 | @Override 76 | public void cancelAction(long to, int messageId) { 77 | replyInternal(to, messageId, CANCEL_MESSAGE, TextFormat.PLAIN_TEXT, new RemoveKeyboard()); 78 | } 79 | 80 | @Override 81 | public void replyInlineQuery(String queryId, String title, String text, TextFormat format) { 82 | try { 83 | restTemplate.postForEntity(format(BASE_URL, token, ANSWER_INLINE_QUERY), new InlineQueryReplyMessage(queryId, 84 | new InlineQueryResultArticle(queryId, title, text, format)), String.class); 85 | } catch (HttpStatusCodeException ex) { 86 | logger.error("Got error while sending sending edit reply message."); 87 | logger.error("Message = {}", text); 88 | logger.error("Response code = {}", ex.getResponseBodyAsString()); 89 | } 90 | } 91 | 92 | @Override 93 | public void replyInlineQueryArticles(String queryId, List results) { 94 | try { 95 | restTemplate.postForEntity(format(BASE_URL, token, ANSWER_INLINE_QUERY), new InlineQueryReplyMessage(queryId, results), String.class); 96 | } catch (HttpStatusCodeException ex) { 97 | logger.error("Got error while sending sending edit reply message."); 98 | logger.error("Response code = {}", ex.getResponseBodyAsString()); 99 | } 100 | } 101 | 102 | private void replyInternal(long to, int messageId, String text, TextFormat format, Keyboard keyboard) { 103 | try { 104 | restTemplate.postForEntity(format(BASE_URL, token, SEND_MESSAGE), new ReplyMessage(to, messageId, text, format, keyboard, true), String.class); 105 | } catch (HttpStatusCodeException ex) { 106 | logger.error("Got error while sending sending edit reply message."); 107 | logger.error("Message = {}", text); 108 | logger.error("Response code = {}", ex.getResponseBodyAsString()); 109 | } 110 | } 111 | 112 | @Override 113 | public void sendAction(long chatId, ActionType action) { 114 | try { 115 | restTemplate.postForEntity(format(BASE_URL, token, SEND_CHAT_ACTION), new ChatAction(chatId, action), String.class); 116 | } catch(HttpStatusCodeException ex) { 117 | logger.warn(ex.getResponseBodyAsString()); 118 | } 119 | } 120 | } -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.2.5.RELEASE 9 | 10 | 11 | com.madadipouya.telegram.corona 12 | covid19 13 | 0.0.1-SNAPSHOT 14 | COVID-19-Telegram-Bot 15 | COVID-19 Telegram Bot 16 | 17 | 18 | 11 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-aop 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter-cache 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-security 37 | 38 | 39 | com.github.ben-manes.caffeine 40 | caffeine 41 | 42 | 43 | io.springfox 44 | springfox-swagger2 45 | 2.9.2 46 | compile 47 | 48 | 49 | io.springfox 50 | springfox-swagger-ui 51 | 2.9.2 52 | 53 | 54 | org.jsoup 55 | jsoup 56 | 1.14.2 57 | 58 | 59 | org.apache.commons 60 | commons-lang3 61 | 3.9 62 | 63 | 64 | org.apache.commons 65 | commons-text 66 | 1.8 67 | 68 | 69 | org.apache.commons 70 | commons-collections4 71 | 4.4 72 | 73 | 74 | commons-io 75 | commons-io 76 | 2.7 77 | 78 | 79 | com.rometools 80 | rome-opml 81 | 1.12.2 82 | 83 | 84 | com.vdurmont 85 | emoji-java 86 | 5.1.1 87 | 88 | 89 | com.google.guava 90 | guava 91 | 29.0-jre 92 | 93 | 94 | org.springframework.boot 95 | spring-boot-devtools 96 | runtime 97 | true 98 | 99 | 100 | org.springframework.boot 101 | spring-boot-starter-test 102 | test 103 | 104 | 105 | org.junit.vintage 106 | junit-vintage-engine 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | production 115 | 116 | production 117 | 118 | 119 | 120 | 121 | org.springframework.boot 122 | spring-boot-maven-plugin 123 | 124 | 125 | run-app 126 | compile 127 | 128 | run 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | org.springframework.boot 142 | spring-boot-maven-plugin 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" 124 | 125 | FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 162 | if ERRORLEVEL 1 goto error 163 | goto end 164 | 165 | :error 166 | set ERROR_CODE=1 167 | 168 | :end 169 | @endlocal & set ERROR_CODE=%ERROR_CODE% 170 | 171 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 172 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 173 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 174 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 175 | :skipRcPost 176 | 177 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 178 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 179 | 180 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 181 | 182 | exit /B %ERROR_CODE% 183 | -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/command/parser/impl/DefaultCommandParser.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.command.parser.impl; 2 | 3 | import com.google.common.collect.Iterables; 4 | import com.madadipouya.telegram.corona.general.command.Command; 5 | import com.madadipouya.telegram.corona.general.command.resolver.CommandResolver; 6 | import com.madadipouya.telegram.corona.general.command.parser.CommandParser; 7 | import com.madadipouya.telegram.corona.general.rest.dto.Update; 8 | import com.madadipouya.telegram.corona.general.rest.dto.base.CallbackQuery; 9 | import com.madadipouya.telegram.corona.general.rest.dto.base.Message; 10 | import com.madadipouya.telegram.corona.general.rest.dto.base.MessageEntity; 11 | import com.madadipouya.telegram.corona.general.rest.dto.internal.CommandArgumentPair; 12 | import org.apache.commons.lang3.SerializationUtils; 13 | import org.springframework.stereotype.Service; 14 | 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | import java.util.Optional; 18 | import java.util.stream.Collectors; 19 | 20 | import static java.util.Objects.isNull; 21 | import static java.util.Objects.nonNull; 22 | import static org.apache.commons.lang3.StringUtils.isBlank; 23 | import static org.apache.commons.lang3.StringUtils.substring; 24 | import static org.apache.commons.lang3.StringUtils.trimToEmpty; 25 | 26 | /* 27 | * This file is part of COVID-19-Telegram-bot. 28 | * 29 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 30 | * it under the terms of the GNU General Public License version 3 31 | * as published by the Free Software Foundation. 32 | * 33 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 34 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 35 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 36 | * GNU General Public License for more details. 37 | * 38 | * Author(s): 39 | * 40 | * © 2020 Kasra Madadipouya 41 | */ 42 | 43 | @Service 44 | public class DefaultCommandParser implements CommandParser { 45 | 46 | private static final String BOT_COMMAND = "bot_command"; 47 | 48 | private final CommandResolver commandResolver; 49 | 50 | public DefaultCommandParser(CommandResolver commandResolver) { 51 | this.commandResolver = commandResolver; 52 | } 53 | 54 | @Override 55 | public void parse(Update update) { 56 | Message message = update.getFirstAvailableMessage(); 57 | update.setCommandArgumentPairs(List.of(parseMessage(message), parseReplyMessage(message), 58 | parseCallbackQueryByMessage(update), parseCallbackQueryByCallbackData(update)) 59 | .stream().flatMap(List::stream).collect(Collectors.toList())); 60 | } 61 | 62 | private List parseMessage(Message message) { 63 | return isBlank(message.getText()) && isNull(message.getEntities()) ? List.of() : 64 | extractCommandArgumentPairs(message); 65 | } 66 | 67 | private List parseReplyMessage(Message message) { 68 | return nonNull(message.getReplyToMessage()) ? 69 | extractCommandArgumentPairs(message.getReplyToMessage(), Optional.of(message)) : 70 | List.of(); 71 | } 72 | 73 | private List parseCallbackQueryByMessage(Update update) { 74 | if (update.hasCallbackQuery()) { 75 | CallbackQuery callbackQuery = update.getCallbackQuery(); 76 | return List.of(new CommandArgumentPair( 77 | commandResolver.resolve(callbackQuery.getMessageText()), 78 | SerializationUtils.clone(callbackQuery.getMessage()), 79 | callbackQuery.getData())); 80 | } 81 | return List.of(); 82 | } 83 | 84 | private List parseCallbackQueryByCallbackData(Update update) { 85 | if (update.hasCallbackQuery()) { 86 | CallbackQuery callbackQuery = update.getCallbackQuery(); 87 | return List.of(new CommandArgumentPair(commandResolver.resolve(callbackQuery.getData()), 88 | SerializationUtils.clone(callbackQuery.getMessage()), 89 | callbackQuery.getData())); 90 | } 91 | return List.of(); 92 | } 93 | 94 | private List extractCommandArgumentPairs(Message message) { 95 | return extractCommandArgumentPairs(message, Optional.empty()); 96 | } 97 | 98 | private List extractCommandArgumentPairs(Message message, Optional messageToSet) { 99 | Message commandArgMessage = messageToSet.orElse(message); 100 | List entities = message.getEntities(); 101 | List commandArgumentPairs = new ArrayList<>(); 102 | int entitiesSize = entities.size(); 103 | for (int i = 0; i < entitiesSize; i++) { 104 | MessageEntity entity = entities.get(i); 105 | if (isBotEntity(entity)) { 106 | String argument = isLastEntity(i, entitiesSize) ? 107 | trimToEmpty(substring(message.getText(), entity.getOffset() + entity.getLength(), message.getText().length())) : 108 | extractArgument(message, i); 109 | commandArgumentPairs.add(new CommandArgumentPair(resolveCommand(message, i), SerializationUtils.clone(commandArgMessage), argument)); 110 | } else if (!commandArgumentPairs.isEmpty()) { 111 | CommandArgumentPair lastBotCommand = Iterables.getLast(commandArgumentPairs); 112 | commandArgumentPairs.remove((commandArgumentPairs.size() - 1)); 113 | commandArgumentPairs.add(new CommandArgumentPair(lastBotCommand.getCommand(), lastBotCommand.getMessage(), 114 | String.format("%s %s", lastBotCommand.getArgument(), isLastEntity(i, entitiesSize) ? 115 | trimToEmpty(substring(message.getText(), entity.getOffset(), message.getText().length())) : 116 | extractArgument(message, i)))); 117 | } 118 | } 119 | return commandArgumentPairs; 120 | } 121 | 122 | private Command resolveCommand(Message message, int offset) { 123 | return commandResolver.resolve(extractCommand(message, offset)); 124 | } 125 | 126 | private String extractCommand(Message message, int offset) { 127 | MessageEntity messageEntity = message.getEntities().get(offset); 128 | return trimToEmpty(substring(message.getText(), messageEntity.getOffset(), 129 | messageEntity.getOffset() + messageEntity.getLength())); 130 | } 131 | 132 | private String extractArgument(Message message, int offset) { 133 | MessageEntity messageEntity = message.getEntities().get(offset); 134 | return trimToEmpty(substring(message.getText(), 135 | messageEntity.getOffset() + messageEntity.getLength(), message.getEntities().get(offset + 1).getOffset())); 136 | } 137 | 138 | private boolean isBotEntity(MessageEntity messageEntity) { 139 | return BOT_COMMAND.equals(messageEntity.getType()); 140 | } 141 | 142 | private boolean isLastEntity(int offset, int entityListSize) { 143 | return offset + 1 == entityListSize; 144 | } 145 | } -------------------------------------------------------------------------------- /src/main/java/com/madadipouya/telegram/corona/general/rest/dto/base/Message.java: -------------------------------------------------------------------------------- 1 | package com.madadipouya.telegram.corona.general.rest.dto.base; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import com.madadipouya.telegram.corona.general.rest.dto.type.*; 5 | 6 | import java.io.Serializable; 7 | import java.util.List; 8 | 9 | import static org.apache.commons.lang3.StringUtils.trimToEmpty; 10 | 11 | /* 12 | * This file is part of COVID-19-Telegram-bot. 13 | * 14 | * COVID-19-Telegram-bot is free software; you can redistribute it and/or modify 15 | * it under the terms of the GNU General Public License version 3 16 | * as published by the Free Software Foundation. 17 | * 18 | * COVID-19-Telegram-bot is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * Author(s): 24 | * 25 | * © 2020 Kasra Madadipouya 26 | */ 27 | 28 | public class Message implements Serializable { 29 | 30 | @JsonProperty("message_id") 31 | private int messageId; 32 | 33 | private User from; 34 | 35 | private int date; 36 | 37 | private Chat chat; 38 | 39 | @JsonProperty("forward_from") 40 | private User forwardFrom; 41 | 42 | @JsonProperty("forward_from_chat") 43 | private User forwardFromChat; 44 | 45 | @JsonProperty("forward_from_message_id") 46 | private int forwardFromMessageId; 47 | 48 | @JsonProperty("forward_signature") 49 | private String forwardSignature; 50 | 51 | @JsonProperty("forward_sender_name") 52 | private String forwardSenderName; 53 | 54 | @JsonProperty("forward_date") 55 | private int forwardDate; 56 | 57 | @JsonProperty("reply_to_message") 58 | private Message replyToMessage; 59 | 60 | @JsonProperty("edit_date") 61 | private int editDate; 62 | 63 | @JsonProperty("media_group_id") 64 | private String mediaGroupId; 65 | 66 | @JsonProperty("author_signature") 67 | private String authorSignature; 68 | 69 | private String text; 70 | 71 | private List entities; 72 | 73 | @JsonProperty("caption_entities") 74 | private List captionEntities; 75 | 76 | private Audio audio; 77 | 78 | private Document document; 79 | 80 | private Animation animation; 81 | 82 | private Game game; 83 | 84 | @JsonProperty("photo") 85 | private List photos; 86 | 87 | private Sticker sticker; 88 | 89 | private Video video; 90 | 91 | private Voice voice; 92 | 93 | @JsonProperty("video_note") 94 | private VideoNote videoNote; 95 | 96 | private String caption; 97 | 98 | private Contact contact; 99 | 100 | private Location location; 101 | 102 | private Venue venue; 103 | 104 | private Poll poll; 105 | 106 | @JsonProperty("new_chat_members") 107 | private List newChatMembers; 108 | 109 | @JsonProperty("left_chat_member") 110 | private User leftChatMember; 111 | 112 | @JsonProperty("new_chat_title") 113 | private String newChatTitle; 114 | 115 | @JsonProperty("new_chat_photo") 116 | private List newChatPhotos; 117 | 118 | @JsonProperty("delete_chat_photo") 119 | private boolean deleteChatPhoto; 120 | 121 | @JsonProperty("group_chat_created") 122 | private boolean groupChatCreated; 123 | 124 | @JsonProperty("super_group_chat_created") 125 | private boolean superGroupChatCreated; 126 | 127 | @JsonProperty("channel_chat_created") 128 | private boolean channelChatCreated; 129 | 130 | @JsonProperty("migrate_to_chat_id") 131 | private int migrateToChatId; 132 | 133 | @JsonProperty("migrate_from_chat_id") 134 | private int migrateFromChatId; 135 | 136 | @JsonProperty("pinned_message") 137 | private Message pinnedMessage; 138 | 139 | private Invoice invoice; 140 | 141 | /*@JsonProperty("successful_payment") 142 | private SuccessfulPayment successfulPayment;*/ 143 | 144 | @JsonProperty("connected_website") 145 | private String connectedWebsite; 146 | 147 | /*@JsonProperty("passport_data") 148 | private PassportData passportData; 149 | 150 | @JsonProperty("reply_markup") 151 | private InlineKeyboadMarkup replyMarkup;*/ 152 | 153 | // TODO complete the mapping 154 | 155 | public int getMessageId() { 156 | return messageId; 157 | } 158 | 159 | public User getFrom() { 160 | return from; 161 | } 162 | 163 | public int getDate() { 164 | return date; 165 | } 166 | 167 | public Chat getChat() { 168 | return chat; 169 | } 170 | 171 | public User getForwardFrom() { 172 | return forwardFrom; 173 | } 174 | 175 | public User getForwardFromChat() { 176 | return forwardFromChat; 177 | } 178 | 179 | public int getForwardFromMessageId() { 180 | return forwardFromMessageId; 181 | } 182 | 183 | public String getForwardSignature() { 184 | return forwardSignature; 185 | } 186 | 187 | public String getForwardSenderName() { 188 | return forwardSenderName; 189 | } 190 | 191 | public int getForwardDate() { 192 | return forwardDate; 193 | } 194 | 195 | public Message getReplyToMessage() { 196 | return replyToMessage; 197 | } 198 | 199 | public int getEditDate() { 200 | return editDate; 201 | } 202 | 203 | public String getMediaGroupId() { 204 | return mediaGroupId; 205 | } 206 | 207 | public String getAuthorSignature() { 208 | return authorSignature; 209 | } 210 | 211 | public String getText() { 212 | return trimToEmpty(text); 213 | } 214 | 215 | public List getEntities() { 216 | return entities == null ? List.of() : entities; 217 | } 218 | 219 | public List getCaptionEntities() { 220 | return captionEntities; 221 | } 222 | 223 | public Audio getAudio() { 224 | return audio; 225 | } 226 | 227 | public Document getDocument() { 228 | return document; 229 | } 230 | 231 | public Animation getAnimation() { 232 | return animation; 233 | } 234 | 235 | public Game getGame() { 236 | return game; 237 | } 238 | 239 | public List getPhotos() { 240 | return photos; 241 | } 242 | 243 | public Sticker getSticker() { 244 | return sticker; 245 | } 246 | 247 | public Video getVideo() { 248 | return video; 249 | } 250 | 251 | public Voice getVoice() { 252 | return voice; 253 | } 254 | 255 | public VideoNote getVideoNote() { 256 | return videoNote; 257 | } 258 | 259 | public String getCaption() { 260 | return caption; 261 | } 262 | 263 | public Contact getContact() { 264 | return contact; 265 | } 266 | 267 | public Location getLocation() { 268 | return location; 269 | } 270 | 271 | public Venue getVenue() { 272 | return venue; 273 | } 274 | 275 | public Poll getPoll() { 276 | return poll; 277 | } 278 | 279 | public List getNewChatMembers() { 280 | return newChatMembers; 281 | } 282 | 283 | public User getLeftChatMember() { 284 | return leftChatMember; 285 | } 286 | 287 | public String getNewChatTitle() { 288 | return newChatTitle; 289 | } 290 | 291 | public List getNewChatPhotos() { 292 | return newChatPhotos; 293 | } 294 | 295 | public boolean isDeleteChatPhoto() { 296 | return deleteChatPhoto; 297 | } 298 | 299 | public boolean isGroupChatCreated() { 300 | return groupChatCreated; 301 | } 302 | 303 | public boolean isSuperGroupChatCreated() { 304 | return superGroupChatCreated; 305 | } 306 | 307 | public boolean isChannelChatCreated() { 308 | return channelChatCreated; 309 | } 310 | 311 | public int getMigrateToChatId() { 312 | return migrateToChatId; 313 | } 314 | 315 | public int getMigrateFromChatId() { 316 | return migrateFromChatId; 317 | } 318 | 319 | public Message getPinnedMessage() { 320 | return pinnedMessage; 321 | } 322 | 323 | public Invoice getInvoice() { 324 | return invoice; 325 | } 326 | 327 | public String getConnectedWebsite() { 328 | return connectedWebsite; 329 | } 330 | } 331 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | fi 118 | 119 | if [ -z "$JAVA_HOME" ]; then 120 | javaExecutable="`which javac`" 121 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 122 | # readlink(1) is not available as standard on Solaris 10. 123 | readLink=`which readlink` 124 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 125 | if $darwin ; then 126 | javaHome="`dirname \"$javaExecutable\"`" 127 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 128 | else 129 | javaExecutable="`readlink -f \"$javaExecutable\"`" 130 | fi 131 | javaHome="`dirname \"$javaExecutable\"`" 132 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 133 | JAVA_HOME="$javaHome" 134 | export JAVA_HOME 135 | fi 136 | fi 137 | fi 138 | 139 | if [ -z "$JAVACMD" ] ; then 140 | if [ -n "$JAVA_HOME" ] ; then 141 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 142 | # IBM's JDK on AIX uses strange locations for the executables 143 | JAVACMD="$JAVA_HOME/jre/sh/java" 144 | else 145 | JAVACMD="$JAVA_HOME/bin/java" 146 | fi 147 | else 148 | JAVACMD="`which java`" 149 | fi 150 | fi 151 | 152 | if [ ! -x "$JAVACMD" ] ; then 153 | echo "Error: JAVA_HOME is not defined correctly." >&2 154 | echo " We cannot execute $JAVACMD" >&2 155 | exit 1 156 | fi 157 | 158 | if [ -z "$JAVA_HOME" ] ; then 159 | echo "Warning: JAVA_HOME environment variable is not set." 160 | fi 161 | 162 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 163 | 164 | # traverses directory structure from process work directory to filesystem root 165 | # first directory with .mvn subdirectory is considered project base directory 166 | find_maven_basedir() { 167 | 168 | if [ -z "$1" ] 169 | then 170 | echo "Path not specified to find_maven_basedir" 171 | return 1 172 | fi 173 | 174 | basedir="$1" 175 | wdir="$1" 176 | while [ "$wdir" != '/' ] ; do 177 | if [ -d "$wdir"/.mvn ] ; then 178 | basedir=$wdir 179 | break 180 | fi 181 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 182 | if [ -d "${wdir}" ]; then 183 | wdir=`cd "$wdir/.."; pwd` 184 | fi 185 | # end of workaround 186 | done 187 | echo "${basedir}" 188 | } 189 | 190 | # concatenates all lines of a file 191 | concat_lines() { 192 | if [ -f "$1" ]; then 193 | echo "$(tr -s '\n' ' ' < "$1")" 194 | fi 195 | } 196 | 197 | BASE_DIR=`find_maven_basedir "$(pwd)"` 198 | if [ -z "$BASE_DIR" ]; then 199 | exit 1; 200 | fi 201 | 202 | ########################################################################################## 203 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 204 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 205 | ########################################################################################## 206 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 207 | if [ "$MVNW_VERBOSE" = true ]; then 208 | echo "Found .mvn/wrapper/maven-wrapper.jar" 209 | fi 210 | else 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 213 | fi 214 | if [ -n "$MVNW_REPOURL" ]; then 215 | jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" 216 | else 217 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar" 218 | fi 219 | while IFS="=" read key value; do 220 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 221 | esac 222 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 223 | if [ "$MVNW_VERBOSE" = true ]; then 224 | echo "Downloading from: $jarUrl" 225 | fi 226 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 227 | if $cygwin; then 228 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 229 | fi 230 | 231 | if command -v wget > /dev/null; then 232 | if [ "$MVNW_VERBOSE" = true ]; then 233 | echo "Found wget ... using wget" 234 | fi 235 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 236 | wget "$jarUrl" -O "$wrapperJarPath" 237 | else 238 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" 239 | fi 240 | elif command -v curl > /dev/null; then 241 | if [ "$MVNW_VERBOSE" = true ]; then 242 | echo "Found curl ... using curl" 243 | fi 244 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 245 | curl -o "$wrapperJarPath" "$jarUrl" -f 246 | else 247 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 248 | fi 249 | 250 | else 251 | if [ "$MVNW_VERBOSE" = true ]; then 252 | echo "Falling back to using Java to download" 253 | fi 254 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 255 | # For Cygwin, switch paths to Windows format before running javac 256 | if $cygwin; then 257 | javaClass=`cygpath --path --windows "$javaClass"` 258 | fi 259 | if [ -e "$javaClass" ]; then 260 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 261 | if [ "$MVNW_VERBOSE" = true ]; then 262 | echo " - Compiling MavenWrapperDownloader.java ..." 263 | fi 264 | # Compiling the Java class 265 | ("$JAVA_HOME/bin/javac" "$javaClass") 266 | fi 267 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 268 | # Running the downloader 269 | if [ "$MVNW_VERBOSE" = true ]; then 270 | echo " - Running MavenWrapperDownloader.java ..." 271 | fi 272 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 273 | fi 274 | fi 275 | fi 276 | fi 277 | ########################################################################################## 278 | # End of extension 279 | ########################################################################################## 280 | 281 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 282 | if [ "$MVNW_VERBOSE" = true ]; then 283 | echo $MAVEN_PROJECTBASEDIR 284 | fi 285 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 286 | 287 | # For Cygwin, switch paths to Windows format before running java 288 | if $cygwin; then 289 | [ -n "$M2_HOME" ] && 290 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 291 | [ -n "$JAVA_HOME" ] && 292 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 293 | [ -n "$CLASSPATH" ] && 294 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 295 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 296 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 297 | fi 298 | 299 | # Provide a "standardized" way to retrieve the CLI args that will 300 | # work with both Windows and non-Windows executions. 301 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 302 | export MAVEN_CMD_LINE_ARGS 303 | 304 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 305 | 306 | exec "$JAVACMD" \ 307 | $MAVEN_OPTS \ 308 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 309 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 310 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 311 | --------------------------------------------------------------------------------