diff --git a/build.gradle b/build.gradle index a869778..ef8e389 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { } group 'es.sralloza' -version '0.3.4' +version '0.4.0' repositories { mavenCentral() diff --git a/scripts/provision-data/run.sh b/scripts/provision-data/run.sh index fdad2b9..7a9bc5a 100755 --- a/scripts/provision-data/run.sh +++ b/scripts/provision-data/run.sh @@ -6,13 +6,17 @@ baseURL="${1:-http://localhost:8080}" apiKey=$(cat .env | grep ADMIN_API_KEY | cut -d '=' -f2) userId=$(cat .env | grep TELEGRAM_CREATOR_ID | cut -d '=' -f2) -echo "+Creating user" +echo "+Creating users" curl -H "x-token: $apiKey" -H 'Content-Type: application/json' --data '{"id":"'$userId'","username":"admin"}' $baseURL/api/v1/users -sS echo "" +curl -H "x-token: $apiKey" -H 'Content-Type: application/json' --data '{"id":"extra-user","username":"extra"}' $baseURL/api/v1/users -sS +echo "" -echo "+Creating chore type" +echo "+Creating chore types" curl -H "x-token: $apiKey" -H 'Content-Type: application/json' --data '{"description":"Laundry","id":"laundry","name":"Laundry"}' $baseURL/api/v1/chore-types -sS echo "" +curl -H "x-token: $apiKey" -H 'Content-Type: application/json' --data '{"description":"Laundry","id":"gardening","name":"Gardening"}' $baseURL/api/v1/chore-types -sS +echo "" echo "+Creating weekly chores" curl -X POST -H "x-token: $apiKey" $baseURL/api/v1/weekly-chores/current -sS diff --git a/src/main/java/bot/ChoreManagementBot.java b/src/main/java/bot/ChoreManagementBot.java index 2415102..1839c66 100644 --- a/src/main/java/bot/ChoreManagementBot.java +++ b/src/main/java/bot/ChoreManagementBot.java @@ -30,6 +30,7 @@ import static org.telegram.abilitybots.api.objects.Locality.USER; import static org.telegram.abilitybots.api.objects.Privacy.PUBLIC; +import static utils.Internationalization.translateWeekId; @Slf4j public class ChoreManagementBot extends BaseChoreManagementBot { @@ -86,7 +87,7 @@ public Ability createWeeklyChores() { helper.handleException((Exception) throwable, chatId); return null; } - helper.sendMessage(String.format(BotMessages.WEEKLY_CHORES_CREATED, weekId), chatId, false); + helper.sendMessage(String.format(BotMessages.WEEKLY_CHORES_CREATED, result.getWeekId()), chatId, false); return null; }, executor); } else { @@ -175,10 +176,10 @@ private void processMsg(MessageContext ctx) { .handleAsync(helper.exceptionHandler(chatId), executor); break; case UserMessages.SKIP: - silent.forceReply(BotMessages.ASK_FOR_WEEK_TO_SKIP, ctx.chatId()); + helper.forceReplyWithMarkdown(BotMessages.ASK_FOR_WEEK_TO_SKIP_MD_SAFE, chatId); break; case UserMessages.UNSKIP: - silent.forceReply(BotMessages.ASK_FOR_WEEK_TO_UNSKIP, ctx.chatId()); + helper.forceReplyWithMarkdown(BotMessages.ASK_FOR_WEEK_TO_UNSKIP_MD_SAFE, chatId); break; case UserMessages.TRANSFER: helper.sendMessage(BotMessages.NOT_IMPLEMENTED, chatId, true); @@ -194,18 +195,14 @@ private void processReplyMsg(MessageContext ctx) { var replyMsg = ctx.update().getMessage().getReplyToMessage().getText(); var chatId = ctx.chatId().toString(); - switch (replyMsg) { - case BotMessages.ASK_FOR_WEEK_TO_SKIP: - service.skipWeek(chatId, userMessage) - .handle(helper.replyHandler(ctx, String.format(BotMessages.WEEK_SKIPPED, userMessage))); - break; - case BotMessages.ASK_FOR_WEEK_TO_UNSKIP: - service.unSkipWeek(chatId, userMessage) - .handle(helper.replyHandler(ctx, String.format(BotMessages.WEEK_UNSKIPPED, userMessage))); - break; - default: - helper.sendMessage(BotMessages.UNDEFINED_COMMAND, chatId, false); - break; + if (BotMessages.ASK_FOR_WEEK_TO_SKIP_RAW.equals(replyMsg)) { + service.skipWeek(chatId, translateWeekId(userMessage)) + .handle(helper.replyHandler(ctx, BotMessages.WEEK_SKIPPED)); + } else if (BotMessages.ASK_FOR_WEEK_TO_UNSKIP_RAW.equals(replyMsg)) { + service.unSkipWeek(chatId, translateWeekId(userMessage)) + .handle(helper.replyHandler(ctx, BotMessages.WEEK_UNSKIPPED)); + } else { + helper.sendMessage(BotMessages.UNDEFINED_COMMAND, chatId, false); } } diff --git a/src/main/java/constants/BotMessages.java b/src/main/java/constants/BotMessages.java index 94c04d6..96662b6 100644 --- a/src/main/java/constants/BotMessages.java +++ b/src/main/java/constants/BotMessages.java @@ -11,8 +11,19 @@ public class BotMessages { public static final String TASK_COMPLETED = "Tarea completada"; public static final String UNDEFINED_COMMAND = "Comando indefinido"; - public static final String ASK_FOR_WEEK_TO_SKIP = "Escribe la semana que quieres saltar (ej: 2022.03)"; - public static final String ASK_FOR_WEEK_TO_UNSKIP = "Escribe la semana que quieres restablecer (ej: 2022.03)"; + + public static final String EXTRA_WEEK_IDS = "Puedes utilizar también las palabras clave *actual*, *anterior* y *siguiente*."; + public static final String ASK_FOR_WEEK_TO_SKIP = "Escribe la semana que quieres saltar (ej: 2022.03)\n" + EXTRA_WEEK_IDS; + public static final String ASK_FOR_WEEK_TO_UNSKIP = "Escribe la semana que quieres restablecer (ej: 2022.03)\n" + EXTRA_WEEK_IDS; + + public static final String ASK_FOR_WEEK_TO_SKIP_MD_SAFE = ASK_FOR_WEEK_TO_SKIP. + replace("(", "\\(").replace(")", "\\)").replace(".", "\\."); + public static final String ASK_FOR_WEEK_TO_UNSKIP_MD_SAFE = ASK_FOR_WEEK_TO_UNSKIP. + replace("(", "\\(").replace(")", "\\)").replace(".", "\\."); + + public static final String ASK_FOR_WEEK_TO_SKIP_RAW = ASK_FOR_WEEK_TO_SKIP.replace("*", ""); + public static final String ASK_FOR_WEEK_TO_UNSKIP_RAW = ASK_FOR_WEEK_TO_UNSKIP.replace("*", ""); + public static final String UNKNOWN_ERROR = "Ha ocurrido un error no contemplado\\. Se ha enviado más" + " información al administrador para resolver el problema\\."; public static final String NO_TICKETS_FOUND = "No se han encontrado tickets"; diff --git a/src/main/java/helpers/BotHelper.java b/src/main/java/helpers/BotHelper.java index bacaec1..83a5eee 100644 --- a/src/main/java/helpers/BotHelper.java +++ b/src/main/java/helpers/BotHelper.java @@ -5,6 +5,7 @@ import exceptions.APIException; import lombok.extern.slf4j.Slf4j; import models.QueryType; +import models.WeekId; import org.telegram.abilitybots.api.bot.AbilityBot; import org.telegram.abilitybots.api.objects.MessageContext; import org.telegram.abilitybots.api.sender.MessageSender; @@ -14,6 +15,7 @@ import org.telegram.telegrambots.meta.api.methods.updatingmessages.DeleteMessage; import org.telegram.telegrambots.meta.api.methods.updatingmessages.EditMessageText; import org.telegram.telegrambots.meta.api.objects.InputFile; +import org.telegram.telegrambots.meta.api.objects.replykeyboard.ForceReplyKeyboard; import org.telegram.telegrambots.meta.exceptions.TelegramApiException; import services.MessagesService; @@ -52,6 +54,23 @@ public void sendMessage(String msgStr, String chatId, boolean markdown) { } } + public void forceReplyWithMarkdown(String message, String chatId) { + SendMessage msg = new SendMessage(); + msg.setText(message); + msg.setChatId(chatId); + ForceReplyKeyboard kb = new ForceReplyKeyboard(); + kb.setForceReply(true); + kb.setSelective(true); + msg.setReplyMarkup(kb); + msg.enableMarkdownV2(true); + + try { + sender.execute(msg); + } catch (TelegramApiException e) { + handleException(e, chatId); + } + } + public void sendImage(String chatId, File file) { InputFile inputFile = new InputFile(file); SendPhoto message = new SendPhoto(); @@ -133,12 +152,13 @@ public BiFunction callbackQueryHandler(MessageContext ctx }; } - public BiFunction replyHandler(MessageContext ctx, String messageOk) { + public BiFunction replyHandler(MessageContext ctx, String templateOk) { var chatId = ctx.chatId().toString(); - return (unused, e) -> { + return (weekId, e) -> { if (e != null) { handleException((Exception) e, chatId); } else { + var messageOk = String.format(templateOk, weekId.getWeekId()); sendMessage(messageOk, chatId, false); } return null; diff --git a/src/main/java/models/WeekId.java b/src/main/java/models/WeekId.java new file mode 100644 index 0000000..11b6990 --- /dev/null +++ b/src/main/java/models/WeekId.java @@ -0,0 +1,12 @@ +package models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +@Accessors(chain = true) +@Data +public class WeekId { + @JsonProperty("week_id") + private String weekId; +} diff --git a/src/main/java/repositories/ChoreManagementRepository.java b/src/main/java/repositories/ChoreManagementRepository.java index f7a14b6..16d3779 100644 --- a/src/main/java/repositories/ChoreManagementRepository.java +++ b/src/main/java/repositories/ChoreManagementRepository.java @@ -1,9 +1,11 @@ package repositories; +import models.WeekId; + import java.util.concurrent.CompletableFuture; public interface ChoreManagementRepository { - CompletableFuture skipWeek(String userId, String weekId); + CompletableFuture skipWeek(String userId, String weekId); - CompletableFuture unSkipWeek(String userId, String weekId); + CompletableFuture unSkipWeek(String userId, String weekId); } diff --git a/src/main/java/repositories/ChoreManagementRepositoryImp.java b/src/main/java/repositories/ChoreManagementRepositoryImp.java index 49e377e..ad38212 100644 --- a/src/main/java/repositories/ChoreManagementRepositoryImp.java +++ b/src/main/java/repositories/ChoreManagementRepositoryImp.java @@ -2,6 +2,7 @@ import com.google.inject.Inject; import com.typesafe.config.Config; +import models.WeekId; import repositories.base.BaseNonAdminRepository; import security.Security; @@ -14,11 +15,11 @@ public ChoreManagementRepositoryImp(Config config, Security security, Executor e super(config, security, executor); } - public CompletableFuture skipWeek(String userId, String weekId) { - return sendPostRequest("/api/v1/users/me/deactivate/" + weekId, null, userId); + public CompletableFuture skipWeek(String userId, String weekId) { + return sendPostRequest("/api/v1/users/me/deactivate/" + weekId, WeekId.class, userId); } - public CompletableFuture unSkipWeek(String userId, String weekId) { - return sendPostRequest("/api/v1/users/me/reactivate/" + weekId, null, userId); + public CompletableFuture unSkipWeek(String userId, String weekId) { + return sendPostRequest("/api/v1/users/me/reactivate/" + weekId, WeekId.class, userId); } } diff --git a/src/main/java/services/ChoreManagementService.java b/src/main/java/services/ChoreManagementService.java index 1a0f7b1..ec63b7d 100644 --- a/src/main/java/services/ChoreManagementService.java +++ b/src/main/java/services/ChoreManagementService.java @@ -4,6 +4,7 @@ import models.ChoreType; import models.Ticket; import models.User; +import models.WeekId; import models.WeeklyChores; import java.util.List; @@ -19,9 +20,9 @@ public interface ChoreManagementService { CompletableFuture completeChore(String userId, String weekId, String choreType); - CompletableFuture skipWeek(String userId, String weekId); + CompletableFuture skipWeek(String userId, String weekId); - CompletableFuture unSkipWeek(String userId, String weekId); + CompletableFuture unSkipWeek(String userId, String weekId); CompletableFuture> listChoreTypes(); diff --git a/src/main/java/services/ChoreManagementServiceImp.java b/src/main/java/services/ChoreManagementServiceImp.java index 539845a..a0c0472 100644 --- a/src/main/java/services/ChoreManagementServiceImp.java +++ b/src/main/java/services/ChoreManagementServiceImp.java @@ -6,6 +6,7 @@ import models.ChoreType; import models.Ticket; import models.User; +import models.WeekId; import models.WeeklyChores; import repositories.ChoreManagementRepository; import repositories.chores.ChoresRepository; @@ -56,12 +57,12 @@ public CompletableFuture completeChore(String userId, String weekId, Strin } @Override - public CompletableFuture skipWeek(String userId, String weekId) { + public CompletableFuture skipWeek(String userId, String weekId) { return repository.skipWeek(userId, weekId); } @Override - public CompletableFuture unSkipWeek(String userId, String weekId) { + public CompletableFuture unSkipWeek(String userId, String weekId) { return repository.unSkipWeek(userId, weekId); } diff --git a/src/main/java/utils/Internationalization.java b/src/main/java/utils/Internationalization.java new file mode 100644 index 0000000..a08e0e1 --- /dev/null +++ b/src/main/java/utils/Internationalization.java @@ -0,0 +1,17 @@ +package utils; + +import java.util.Map; +import java.util.function.Function; + +public class Internationalization { + public static Map WEEK_ID_KEYWORDS_MAP = Map.of( + "actual", "current", "anterior", "last", "siguiente", "next" + ); + + public static String translateWeekId(String weekId) { + return WEEK_ID_KEYWORDS_MAP.entrySet().stream() + .map(param -> (Function) s -> s.replace(param.getKey(), param.getValue())) + .reduce(Function.identity(), Function::andThen) + .apply(weekId); + } +}