diff --git a/.env b/.env new file mode 100644 index 0000000..d312488 --- /dev/null +++ b/.env @@ -0,0 +1,3 @@ +DB_URL=jdbc:postgresql://localhost:5432/whatsapp_bot +DB_USERNAME=whatsapp_user +DB_PASSWORD=RITHosting123 diff --git a/db/whatsappbot.mv.db b/db/whatsappbot.mv.db index d10c6e6..770bc98 100644 Binary files a/db/whatsappbot.mv.db and b/db/whatsappbot.mv.db differ diff --git a/pom.xml b/pom.xml index 11e2628..5376ff9 100644 --- a/pom.xml +++ b/pom.xml @@ -43,6 +43,11 @@ h2 runtime + + org.postgresql + postgresql + runtime + com.fasterxml.jackson.core jackson-databind diff --git a/src/main/java/com/rit/whatsapp/controller/WebhookController.java b/src/main/java/com/rit/whatsapp/controller/WebhookController.java index 6e09149..488b28c 100644 --- a/src/main/java/com/rit/whatsapp/controller/WebhookController.java +++ b/src/main/java/com/rit/whatsapp/controller/WebhookController.java @@ -198,11 +198,36 @@ public class WebhookController { return; } + if ("student_show_menu".equals(selectedButtonId)) { + studentMenuHandler.sendStudentMenuDirectly(phoneNumber); + return; + } + if ("student_exam_fees".equals(selectedButtonId)) { studentMenuHandler.handleExamFees(phoneNumber); return; } + if ("student_cat1_marks".equals(selectedButtonId)) { + studentMenuHandler.handleCat1Marks(phoneNumber); + return; + } + + if ("student_cat2_marks".equals(selectedButtonId)) { + studentMenuHandler.handleCat2Marks(phoneNumber); + return; + } + + if ("student_cat3_marks".equals(selectedButtonId)) { + studentMenuHandler.handleCat3Marks(phoneNumber); + return; + } + + if ("student_assignment_marks".equals(selectedButtonId)) { + studentMenuHandler.handleAssignmentMarks(phoneNumber); + return; + } + if ("student_payment_history".equals(selectedButtonId)) { studentMenuHandler.handlePaymentHistory(phoneNumber); return; diff --git a/src/main/java/com/rit/whatsapp/handler/GrievanceHandler.java b/src/main/java/com/rit/whatsapp/handler/GrievanceHandler.java index 5137562..638c5cc 100644 --- a/src/main/java/com/rit/whatsapp/handler/GrievanceHandler.java +++ b/src/main/java/com/rit/whatsapp/handler/GrievanceHandler.java @@ -7,6 +7,8 @@ import com.rit.whatsapp.service.WhatsAppMessageService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import org.springframework.context.annotation.Lazy; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -18,11 +20,13 @@ public class GrievanceHandler { private final WhatsAppMessageService messageService; private final SessionService sessionService; + private final StudentMenuHandler studentMenuHandler; @Autowired - public GrievanceHandler(WhatsAppMessageService messageService, SessionService sessionService) { + public GrievanceHandler(WhatsAppMessageService messageService, SessionService sessionService, @Lazy StudentMenuHandler studentMenuHandler) { this.messageService = messageService; this.sessionService = sessionService; + this.studentMenuHandler = studentMenuHandler; } public void startGrievanceFlow(String phoneNumber) { @@ -39,6 +43,7 @@ public class GrievanceHandler { ); messageService.sendInteractiveMessage(phoneNumber, buttonMessage); + studentMenuHandler.sendStudentMenuDirectly(phoneNumber); } public void handleCategorySelection(String phoneNumber, String selectedCategory) { @@ -60,6 +65,9 @@ public class GrievanceHandler { // Reset state back to main menu sessionService.resetState(phoneNumber); + + // Display student menu + studentMenuHandler.sendStudentMenuDirectly(phoneNumber); } private Map createButton(String id, String title) { diff --git a/src/main/java/com/rit/whatsapp/handler/StudentMenuHandler.java b/src/main/java/com/rit/whatsapp/handler/StudentMenuHandler.java index d1f1b04..253cb25 100644 --- a/src/main/java/com/rit/whatsapp/handler/StudentMenuHandler.java +++ b/src/main/java/com/rit/whatsapp/handler/StudentMenuHandler.java @@ -81,22 +81,43 @@ public class StudentMenuHandler { weeklyBtn.put("id", "student_weekly_timetable"); weeklyBtn.put("title", "Weekly Timetable"); buttons.add(weeklyBtn); + + Map menuBtn = new HashMap<>(); + menuBtn.put("id", "student_show_menu"); + menuBtn.put("title", "Student Menu"); + buttons.add(menuBtn); + System.out.println("FINAL TODAY TIMETABLE MESSAGE:\n" + todaySchedule); Map buttonMessage = WhatsAppMessageBuilder.buildButtonMessage(todaySchedule, buttons); messageService.sendInteractiveMessage(phoneNumber, buttonMessage); + sendStudentMenuDirectly(phoneNumber); + break; + + case "student_internal_marks": + sendInternalMarksMenu(phoneNumber); break; - case "student_internal_marks": - String rawCatMarks = imsApiService.getCatMarks(token); - String rawAssignmentMarks = imsApiService.getAssignmentMarks(token); - sendResponseWithMenu(phoneNumber, MessageFormatter.formatInternalMarks(rawCatMarks, rawAssignmentMarks)); + case "student_cat1_marks": + handleCat1Marks(phoneNumber); break; - + + case "student_cat2_marks": + handleCat2Marks(phoneNumber); + break; + + case "student_cat3_marks": + handleCat3Marks(phoneNumber); + break; + + case "student_assignment_marks": + handleAssignmentMarks(phoneNumber); + break; + case "student_semester_results": sendSemesterSelection(phoneNumber, token); break; - + case "student_fee_details": { String rawFees = imsApiService.getFees(token); String bodyText = MessageFormatter.formatAcademicFeesOnly(rawFees); @@ -118,6 +139,7 @@ public class StudentMenuHandler { Map feeButtonMessage = WhatsAppMessageBuilder.buildButtonMessage(bodyText, feeButtons); messageService.sendInteractiveMessage(phoneNumber, feeButtonMessage); + sendStudentMenuDirectly(phoneNumber); break; } @@ -166,6 +188,7 @@ public class StudentMenuHandler { ); messageService.sendInteractiveMessage(phoneNumber, interactiveList); + sendStudentMenuDirectly(phoneNumber); } public void handleSemesterSelection(String phoneNumber, String selectedOptionId) { @@ -312,6 +335,7 @@ public class StudentMenuHandler { "Receipts", formattedHistory, "Download Receipt", receiptRows ); messageService.sendInteractiveMessage(phoneNumber, listMessage); + sendStudentMenuDirectly(phoneNumber); } else { sendResponseWithMenu(phoneNumber, formattedHistory); } @@ -344,6 +368,80 @@ public class StudentMenuHandler { rows ); messageService.sendInteractiveMessage(phoneNumber, interactiveList); + sendStudentMenuDirectly(phoneNumber); + } + + public void sendStudentMenuDirectly(String phoneNumber) { + sessionService.setUserState(phoneNumber, UserState.MAIN_MENU); + + Map interactiveList = WhatsAppMessageBuilder.buildListMessage( + null, + "Select an option from the menu below", + "Student Menu", + getStudentMenuRows() + ); + messageService.sendInteractiveMessage(phoneNumber, interactiveList); + } + + public void sendInternalMarksMenu(String phoneNumber) { + List> rows = new ArrayList<>(); + rows.add(createRow("student_cat1_marks", "CAT 1 Marks", "View CAT 1 (CO1) marks")); + rows.add(createRow("student_cat2_marks", "CAT 2 Marks", "View CAT 2 (CO2) marks")); + rows.add(createRow("student_cat3_marks", "CAT 3 Marks", "View CAT 3 (CO3) marks")); + rows.add(createRow("student_assignment_marks", "Assignment Marks", "View assignments 1-5 marks")); + + Map interactiveList = WhatsAppMessageBuilder.buildListMessage( + "Internal Marks", + "Select which internal marks you want to view:", + "Select Option", + rows + ); + messageService.sendInteractiveMessage(phoneNumber, interactiveList); + sendStudentMenuDirectly(phoneNumber); + } + + public void handleCat1Marks(String phoneNumber) { + String token = sessionService.getImsToken(phoneNumber); + if (token == null) { + messageService.sendMessage(phoneNumber, "Your session has expired. Please type 'Reset' to login again."); + return; + } + String rawCatMarks = imsApiService.getCatMarks(token); + String formatted = com.rit.whatsapp.util.MessageFormatter.formatCat1Marks(rawCatMarks); + sendResponseWithMenu(phoneNumber, formatted); + } + + public void handleCat2Marks(String phoneNumber) { + String token = sessionService.getImsToken(phoneNumber); + if (token == null) { + messageService.sendMessage(phoneNumber, "Your session has expired. Please type 'Reset' to login again."); + return; + } + String rawCatMarks = imsApiService.getCatMarks(token); + String formatted = com.rit.whatsapp.util.MessageFormatter.formatCat2Marks(rawCatMarks); + sendResponseWithMenu(phoneNumber, formatted); + } + + public void handleCat3Marks(String phoneNumber) { + String token = sessionService.getImsToken(phoneNumber); + if (token == null) { + messageService.sendMessage(phoneNumber, "Your session has expired. Please type 'Reset' to login again."); + return; + } + String rawCatMarks = imsApiService.getCatMarks(token); + String formatted = com.rit.whatsapp.util.MessageFormatter.formatCat3Marks(rawCatMarks); + sendResponseWithMenu(phoneNumber, formatted); + } + + public void handleAssignmentMarks(String phoneNumber) { + String token = sessionService.getImsToken(phoneNumber); + if (token == null) { + messageService.sendMessage(phoneNumber, "Your session has expired. Please type 'Reset' to login again."); + return; + } + String rawAssignmentMarks = imsApiService.getAssignmentMarks(token); + String formatted = com.rit.whatsapp.util.MessageFormatter.formatAssignmentMarks(rawAssignmentMarks); + sendResponseWithMenu(phoneNumber, formatted); } private List> getStudentMenuRows() { diff --git a/src/main/java/com/rit/whatsapp/util/MessageFormatter.java b/src/main/java/com/rit/whatsapp/util/MessageFormatter.java index 8a05ffa..d97070e 100644 --- a/src/main/java/com/rit/whatsapp/util/MessageFormatter.java +++ b/src/main/java/com/rit/whatsapp/util/MessageFormatter.java @@ -287,10 +287,10 @@ public class MessageFormatter { public static String formatInternalMarks(String rawCatJson, String rawAssignmentJson) { StringBuilder sb = new StringBuilder(); - sb.append("\ud83d\udcc8 *Internal Marks*\n\n"); + sb.append("📈 *INTERNAL MARKS REPORT*\n\n"); // --- Parse CAT Marks --- - sb.append("*CAT MARKS:*\n"); + sb.append("✴️ *CAT MARKS:*\n"); if (rawCatJson == null) { sb.append("❌ Failed to retrieve CAT marks.\n\n"); } else { @@ -309,39 +309,52 @@ public class MessageFormatter { if (targetArray != null && targetArray.size() > 0) { for (JsonNode subject : targetArray) { + String code = subject.has("code") ? subject.get("code").asText() : ""; String name = subject.has("name") ? subject.get("name").asText() : - (subject.has("course_name") ? subject.get("course_name").asText() : "Unknown"); + (subject.has("course_name") ? subject.get("course_name").asText() : "Subject"); + String co1 = subject.has("co1") ? subject.get("co1").asText().trim() : ""; + String co2 = subject.has("co2") ? subject.get("co2").asText().trim() : ""; + String total = subject.has("total") ? subject.get("total").asText().trim() : ""; + String weightage = subject.has("weightage") ? subject.get("weightage").asText().trim() : ""; - String marks = ""; - if (subject.has("total") && !subject.get("total").asText().isEmpty()) { - marks = subject.get("total").asText(); - if (subject.has("weightage") && !subject.get("weightage").asText().isEmpty()) { - marks += " (" + subject.get("weightage").asText() + " wt)"; - } - } else if (subject.has("marks")) { - marks = subject.get("marks").asText(); + sb.append("📚 *").append(name).append("*"); + if (!code.isEmpty()) { + sb.append(" (").append(code).append(")"); + } + sb.append("\n"); + + if (!co1.isEmpty() || !co2.isEmpty()) { + sb.append(" ├─ "); + if (!co1.isEmpty()) sb.append("CO1: ").append(co1); + if (!co1.isEmpty() && !co2.isEmpty()) sb.append(" | "); + if (!co2.isEmpty()) sb.append("CO2: ").append(co2); + sb.append("\n"); + sb.append(" └─ "); } else { - marks = "N/A"; + sb.append(" └─ "); } - sb.append("- *").append(name).append("*: ").append(marks).append("\n"); + sb.append("*Total*: *").append(total.isEmpty() ? "N/A" : total).append("*"); + if (!weightage.isEmpty()) { + sb.append(" (").append(weightage).append(" wt)"); + } + sb.append("\n\n"); foundData = true; } } if (!foundData) { - sb.append("Details not available in this format.\n"); - sb.append("\n*DEBUG RAW CAT JSON:*\n").append(rawCatJson).append("\n"); + sb.append("Details not available in this format.\n\n"); } } catch (Exception e) { - sb.append("⚠️ Error formatting CAT marks.\nRAW JSON: ").append(rawCatJson).append("\n"); + sb.append("⚠️ Error formatting CAT marks.\n\n"); } } - sb.append("\n"); + sb.append("───────────────\n\n"); // --- Parse Assignment Marks --- - sb.append("*ASSIGNMENT MARKS:*\n"); + sb.append("📋 *ASSIGNMENT MARKS:*\n"); if (rawAssignmentJson == null) { sb.append("❌ Failed to retrieve Assignment marks.\n"); } else { @@ -360,38 +373,256 @@ public class MessageFormatter { if (targetArray != null && targetArray.size() > 0) { for (JsonNode subject : targetArray) { + String code = subject.has("code") ? subject.get("code").asText() : ""; String name = subject.has("name") ? subject.get("name").asText() : - (subject.has("course_name") ? subject.get("course_name").asText() : "Unknown"); + (subject.has("course_name") ? subject.get("course_name").asText() : "Subject"); + String a1 = subject.has("a1") ? subject.get("a1").asText().trim() : ""; + String a2 = subject.has("a2") ? subject.get("a2").asText().trim() : ""; + String a3 = subject.has("a3") ? subject.get("a3").asText().trim() : ""; + String a4 = subject.has("a4") ? subject.get("a4").asText().trim() : ""; + String a5 = subject.has("a5") ? subject.get("a5").asText().trim() : ""; + String total = subject.has("total") ? subject.get("total").asText().trim() : ""; - String marks = ""; - if (subject.has("total") && !subject.get("total").asText().isEmpty()) { - marks = subject.get("total").asText(); - if (subject.has("weightage") && !subject.get("weightage").asText().isEmpty()) { - marks += " (" + subject.get("weightage").asText() + " wt)"; - } - } else if (subject.has("marks")) { - marks = subject.get("marks").asText(); + sb.append("📝 *").append(name).append("*"); + if (!code.isEmpty()) { + sb.append(" (").append(code).append(")"); + } + sb.append("\n"); + + java.util.List assignList = new java.util.ArrayList<>(); + if (!a1.isEmpty()) assignList.add("A1: " + a1); + if (!a2.isEmpty()) assignList.add("A2: " + a2); + if (!a3.isEmpty()) assignList.add("A3: " + a3); + if (!a4.isEmpty()) assignList.add("A4: " + a4); + if (!a5.isEmpty()) assignList.add("A5: " + a5); + + if (!assignList.isEmpty()) { + sb.append(" ├─ ").append(String.join(" | ", assignList)).append("\n"); + sb.append(" └─ "); } else { - marks = "N/A"; + sb.append(" └─ "); } - sb.append("- *").append(name).append("*: ").append(marks).append("\n"); + sb.append("*Total*: *").append(total.isEmpty() ? "N/A" : total).append("*\n\n"); foundData = true; } } if (!foundData) { sb.append("Details not available in this format.\n"); - sb.append("\n*DEBUG RAW ASSIGNMENT JSON:*\n").append(rawAssignmentJson).append("\n"); } } catch (Exception e) { - sb.append("⚠️ Error formatting Assignment marks.\nRAW JSON: ").append(rawAssignmentJson).append("\n"); + sb.append("⚠️ Error formatting Assignment marks.\n"); } } return sb.toString(); } + public static String formatCat1Marks(String rawCatJson) { + StringBuilder sb = new StringBuilder(); + sb.append("📈 *CAT 1 MARKS REPORT*\n\n"); + if (rawCatJson == null) { + sb.append("❌ Failed to retrieve CAT 1 marks.\n\n"); + } else { + try { + JsonNode root = mapper.readTree(rawCatJson); + boolean foundData = false; + + JsonNode targetArray = null; + if (root.has("data")) { + if (root.get("data").isArray()) { + targetArray = root.get("data"); + } else if (root.get("data").isObject() && root.get("data").has("subjects") && root.get("data").get("subjects").isArray()) { + targetArray = root.get("data").get("subjects"); + } + } + + if (targetArray != null && targetArray.size() > 0) { + for (JsonNode subject : targetArray) { + String code = subject.has("code") ? subject.get("code").asText() : ""; + String name = subject.has("name") ? subject.get("name").asText() : + (subject.has("course_name") ? subject.get("course_name").asText() : "Subject"); + String co1 = subject.has("co1") ? subject.get("co1").asText().trim() : ""; + + sb.append("📚 *").append(name).append("*"); + if (!code.isEmpty()) { + sb.append(" (").append(code).append(")"); + } + sb.append("\n"); + sb.append(" └─ *CAT 1 (CO1)*: *").append(co1.isEmpty() ? "N/A" : co1).append("*\n\n"); + foundData = true; + } + } + + if (!foundData) { + sb.append("Details not available in this format.\n\n"); + } + } catch (Exception e) { + sb.append("⚠️ Error formatting CAT 1 marks.\n\n"); + } + } + return sb.toString(); + } + + public static String formatCat2Marks(String rawCatJson) { + StringBuilder sb = new StringBuilder(); + sb.append("📈 *CAT 2 MARKS REPORT*\n\n"); + if (rawCatJson == null) { + sb.append("❌ Failed to retrieve CAT 2 marks.\n\n"); + } else { + try { + JsonNode root = mapper.readTree(rawCatJson); + boolean foundData = false; + + JsonNode targetArray = null; + if (root.has("data")) { + if (root.get("data").isArray()) { + targetArray = root.get("data"); + } else if (root.get("data").isObject() && root.get("data").has("subjects") && root.get("data").get("subjects").isArray()) { + targetArray = root.get("data").get("subjects"); + } + } + + if (targetArray != null && targetArray.size() > 0) { + for (JsonNode subject : targetArray) { + String code = subject.has("code") ? subject.get("code").asText() : ""; + String name = subject.has("name") ? subject.get("name").asText() : + (subject.has("course_name") ? subject.get("course_name").asText() : "Subject"); + String co2 = subject.has("co2") ? subject.get("co2").asText().trim() : ""; + + sb.append("📚 *").append(name).append("*"); + if (!code.isEmpty()) { + sb.append(" (").append(code).append(")"); + } + sb.append("\n"); + sb.append(" └─ *CAT 2 (CO2)*: *").append(co2.isEmpty() ? "N/A" : co2).append("*\n\n"); + foundData = true; + } + } + + if (!foundData) { + sb.append("Details not available in this format.\n\n"); + } + } catch (Exception e) { + sb.append("⚠️ Error formatting CAT 2 marks.\n\n"); + } + } + return sb.toString(); + } + + public static String formatCat3Marks(String rawCatJson) { + StringBuilder sb = new StringBuilder(); + sb.append("📈 *CAT 3 MARKS REPORT*\n\n"); + if (rawCatJson == null) { + sb.append("❌ Failed to retrieve CAT 3 marks.\n\n"); + } else { + try { + JsonNode root = mapper.readTree(rawCatJson); + boolean foundData = false; + + JsonNode targetArray = null; + if (root.has("data")) { + if (root.get("data").isArray()) { + targetArray = root.get("data"); + } else if (root.get("data").isObject() && root.get("data").has("subjects") && root.get("data").get("subjects").isArray()) { + targetArray = root.get("data").get("subjects"); + } + } + + if (targetArray != null && targetArray.size() > 0) { + for (JsonNode subject : targetArray) { + String code = subject.has("code") ? subject.get("code").asText() : ""; + String name = subject.has("name") ? subject.get("name").asText() : + (subject.has("course_name") ? subject.get("course_name").asText() : "Subject"); + String co3 = subject.has("co3") ? subject.get("co3").asText().trim() : ""; + + sb.append("📚 *").append(name).append("*"); + if (!code.isEmpty()) { + sb.append(" (").append(code).append(")"); + } + sb.append("\n"); + sb.append(" └─ *CAT 3 (CO3)*: *").append(co3.isEmpty() ? "N/A" : co3).append("*\n\n"); + foundData = true; + } + } + + if (!foundData) { + sb.append("Details not available in this format.\n\n"); + } + } catch (Exception e) { + sb.append("⚠️ Error formatting CAT 3 marks.\n\n"); + } + } + return sb.toString(); + } + + public static String formatAssignmentMarks(String rawAssignmentJson) { + StringBuilder sb = new StringBuilder(); + sb.append("📋 *ASSIGNMENT MARKS:*\n\n"); + if (rawAssignmentJson == null) { + sb.append("❌ Failed to retrieve Assignment marks.\n"); + } else { + try { + JsonNode root = mapper.readTree(rawAssignmentJson); + boolean foundData = false; + + JsonNode targetArray = null; + if (root.has("data")) { + if (root.get("data").isArray()) { + targetArray = root.get("data"); + } else if (root.get("data").isObject() && root.get("data").has("subjects") && root.get("data").get("subjects").isArray()) { + targetArray = root.get("data").get("subjects"); + } + } + + if (targetArray != null && targetArray.size() > 0) { + for (JsonNode subject : targetArray) { + String code = subject.has("code") ? subject.get("code").asText() : ""; + String name = subject.has("name") ? subject.get("name").asText() : + (subject.has("course_name") ? subject.get("course_name").asText() : "Subject"); + String a1 = subject.has("a1") ? subject.get("a1").asText().trim() : ""; + String a2 = subject.has("a2") ? subject.get("a2").asText().trim() : ""; + String a3 = subject.has("a3") ? subject.get("a3").asText().trim() : ""; + String a4 = subject.has("a4") ? subject.get("a4").asText().trim() : ""; + String a5 = subject.has("a5") ? subject.get("a5").asText().trim() : ""; + String total = subject.has("total") ? subject.get("total").asText().trim() : ""; + + sb.append("📝 *").append(name).append("*"); + if (!code.isEmpty()) { + sb.append(" (").append(code).append(")"); + } + sb.append("\n"); + + java.util.List assignList = new java.util.ArrayList<>(); + if (!a1.isEmpty()) assignList.add("A1: " + a1); + if (!a2.isEmpty()) assignList.add("A2: " + a2); + if (!a3.isEmpty()) assignList.add("A3: " + a3); + if (!a4.isEmpty()) assignList.add("A4: " + a4); + if (!a5.isEmpty()) assignList.add("A5: " + a5); + + if (!assignList.isEmpty()) { + sb.append(" ├─ ").append(String.join(" | ", assignList)).append("\n"); + sb.append(" └─ "); + } else { + sb.append(" └─ "); + } + + sb.append("*Total*: *").append(total.isEmpty() ? "N/A" : total).append("*\n\n"); + foundData = true; + } + } + + if (!foundData) { + sb.append("Details not available in this format.\n"); + } + } catch (Exception e) { + sb.append("⚠️ Error formatting Assignment marks.\n"); + } + } + return sb.toString(); + } + public static String formatFeesAndExamFees(String rawFees, String rawExamFees) { StringBuilder sb = new StringBuilder(); @@ -898,7 +1129,9 @@ public class MessageFormatter { if (schedule.has(day)) { JsonNode daySchedule = schedule.get(day); - sb.append(label).append("\n"); + StringBuilder daySb = new StringBuilder(); + daySb.append("📅 *").append(label).append("*\n"); + boolean dayHasClasses = false; int maxPeriod = 7; java.util.Iterator fieldNames = daySchedule.fieldNames(); @@ -913,7 +1146,6 @@ public class MessageFormatter { for (int period = 1; period <= maxPeriod; period++) { String periodKey = String.valueOf(period); - sb.append(getNumberEmoji(period)).append(" "); if (daySchedule.has(periodKey)) { JsonNode details = daySchedule.get(periodKey); @@ -940,16 +1172,15 @@ public class MessageFormatter { } if (!subjects.isEmpty()) { - sb.append(String.join(" / ", subjects)).append("\n"); + daySb.append(" ").append(getNumberEmoji(period)).append(" ").append(String.join(" / ", subjects)).append("\n"); + dayHasClasses = true; hasAnyClasses = true; - } else { - sb.append("—\n"); } - } else { - sb.append("—\n"); } } - sb.append("\n"); + if (dayHasClasses) { + sb.append(daySb).append("\n"); + } } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index fef27b8..69fd92f 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -8,15 +8,14 @@ whatsapp.verify-token=rit_bot_secret_token_123 # WhatsApp Phone Number ID (You get this from the Meta developer console) whatsapp.phone-number-id=1236658909534007 -# H2 Database Configuration -spring.datasource.url=jdbc:h2:file:./db/whatsappbot -spring.datasource.driverClassName=org.h2.Driver -spring.datasource.username=sa -spring.datasource.password=password -spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +# PostgreSQL Database Configuration +spring.datasource.url=${DB_URL} +spring.datasource.driver-class-name=org.postgresql.Driver +spring.datasource.username=${DB_USERNAME} +spring.datasource.password=${DB_PASSWORD} +spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect spring.jpa.hibernate.ddl-auto=update -spring.h2.console.enabled=true # Encryption Secret for Passcodes (Must be 16, 24, or 32 bytes) bot.encryption.secret=12345678901234567890123456789012 -whatsapp.api-token=EAAc3Wjql00oBSfSg58drijkqefLn47aI2vYcl8r6GxuwC5vJRt2G8Std3ynf3KnKp9SyuwKXAQfr2Q7hYrNOE66t3dRcS3GAWFbDbikrmvXkbjpIh5V9QNVGI2T4V1VeJAj9d6HMsiHZCAJujaIVLdLleIPti4ok9brnNf1BPwBZA8SZAQ06OUcbSba3SZAQhcoFsh1Utz1g9PLCqsl8Fh9H8ynVJagAxMYqF86sV7fEHKpG6eCp2EkRtfOoE7XbL5AurGkiZA5ZBHiSZCOOujplm3cmgZDZD +whatsapp.api-token=EAAc3Wjql00oBSWGWTlmDkMegzpdfKYWqNp0jci6efxyhHArM0371vc3t8XEZA74jgy6reRpS0XTwH1qUSoiJ5t1KjlX3PpY2fUVa1zAaWBDq0FB5YG6ll20pSfZBHHcvAABIweGSkWDY4Oe2znY76JWSlPpD0LXORdiRTZChu1uTMOMSgUxGdaQTiJJzxkVovCrK6jzocjGzwZCCLKAKyxKqLMECDfwgnrxaTqwloQ7oZA1X1ZCstFvPfGQ32LJ59SBeGzTuC3PM8GewZB6uvYiKSuGEAZDZD