From 0eaedff3fedededb837051f2cf0ee28f4202ea35 Mon Sep 17 00:00:00 2001 From: Souvik-D10 Date: Wed, 27 May 2026 10:31:46 +0530 Subject: [PATCH 1/3] feat: integrated whatsapp features --- .../order/controller/OrderController.java | 14 ++- .../qrmenu/order/service/OrderService.java | 2 +- .../order/service/impl/OrderServiceImpl.java | 5 +- .../WhatsappOrderNotificationService.java | 8 ++ .../whatsapp/service/WhatsappService.java | 8 ++ .../WhatsappOrderNotificationServiceImpl.java | 56 ++++++++++++ .../service/impl/WhatsappServiceImpl.java | 87 +++++++++++++++++++ .../src/main/resources/application.properties | 9 ++ 8 files changed, 184 insertions(+), 5 deletions(-) create mode 100644 RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/WhatsappOrderNotificationService.java create mode 100644 RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/WhatsappService.java create mode 100644 RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/impl/WhatsappOrderNotificationServiceImpl.java create mode 100644 RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/impl/WhatsappServiceImpl.java diff --git a/RestroHub/src/main/java/com/restroly/qrmenu/order/controller/OrderController.java b/RestroHub/src/main/java/com/restroly/qrmenu/order/controller/OrderController.java index 0db95a20..b798dde5 100644 --- a/RestroHub/src/main/java/com/restroly/qrmenu/order/controller/OrderController.java +++ b/RestroHub/src/main/java/com/restroly/qrmenu/order/controller/OrderController.java @@ -20,6 +20,7 @@ import com.restroly.qrmenu.order.dto.UpdateOrderStatusRequest; import com.restroly.qrmenu.order.service.OrderService; import com.restroly.qrmenu.payment.service.PaymentService; +import com.restroly.qrmenu.whatsapp.service.WhatsappOrderNotificationService; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -35,6 +36,8 @@ public class OrderController { private final PaymentService paymentService = null; @Autowired private final OrderService orderService = null; + @Autowired + private final WhatsappOrderNotificationService whatsapp = null; //private final OrderService orderService; @@ -46,6 +49,8 @@ public ResponseEntity createOrder(@Valid @RequestBody CreateOrder String paymentUrl = paymentService.generatePaymentLink(response.getTotalAmount(), response.getOrderId(), response.getPaymentLink()); //Genarated payment link is stored in response object to send it to client and use it for payment response.setPaymentLink(paymentUrl); + //Sending whatsapp notification + whatsapp.sendOrderConfirmation(response); return ResponseEntity.status(HttpStatus.CREATED).body(response); } @@ -67,12 +72,17 @@ public ResponseEntity> getActiveOrders(@PathVariable Long br @PatchMapping("/{orderId}/status") public ResponseEntity updateOrderStatus(@PathVariable Long orderId, @Valid @RequestBody UpdateOrderStatusRequest request) { - return ResponseEntity.ok(orderService.updateOrderStatus(orderId, request.getStatus())); + OrderResponse response = orderService.updateOrderStatus(orderId, request.getStatus()); + //Sending whatsapp notification + whatsapp.sendOrderStatusUpdate(response); + return ResponseEntity.ok(response); } @PostMapping("/{orderId}/cancel") public ResponseEntity cancelOrder(@PathVariable Long orderId) { - orderService.cancelOrder(orderId); + OrderResponse response=orderService.cancelOrder(orderId); + //sending cancel message + whatsapp.sendOrderStatusUpdate(response); return ResponseEntity.noContent().build(); } } \ No newline at end of file diff --git a/RestroHub/src/main/java/com/restroly/qrmenu/order/service/OrderService.java b/RestroHub/src/main/java/com/restroly/qrmenu/order/service/OrderService.java index bc3c5353..b5490636 100644 --- a/RestroHub/src/main/java/com/restroly/qrmenu/order/service/OrderService.java +++ b/RestroHub/src/main/java/com/restroly/qrmenu/order/service/OrderService.java @@ -18,5 +18,5 @@ public interface OrderService { OrderResponse updateOrderStatus(Long orderId, OrderStatus status); - void cancelOrder(Long orderId); + OrderResponse cancelOrder(Long orderId); } \ No newline at end of file diff --git a/RestroHub/src/main/java/com/restroly/qrmenu/order/service/impl/OrderServiceImpl.java b/RestroHub/src/main/java/com/restroly/qrmenu/order/service/impl/OrderServiceImpl.java index fd5c0ec1..e1632600 100644 --- a/RestroHub/src/main/java/com/restroly/qrmenu/order/service/impl/OrderServiceImpl.java +++ b/RestroHub/src/main/java/com/restroly/qrmenu/order/service/impl/OrderServiceImpl.java @@ -125,12 +125,13 @@ public OrderResponse updateOrderStatus(Long orderId, OrderStatus status) { } @Override - public void cancelOrder(Long orderId) { + public OrderResponse cancelOrder(Long orderId) { log.debug("Cancelling order with id: {}", orderId); Order order = findOrderById(orderId); order.setStatus(OrderStatus.CANCELLED); - orderRepository.save(order); + Order canceledOrder = orderRepository.save(order); log.info("Order {} cancelled", orderId); + return orderMapper.toResponse(canceledOrder); } private Order findOrderById(Long orderId) { diff --git a/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/WhatsappOrderNotificationService.java b/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/WhatsappOrderNotificationService.java new file mode 100644 index 00000000..515db17a --- /dev/null +++ b/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/WhatsappOrderNotificationService.java @@ -0,0 +1,8 @@ +package com.restroly.qrmenu.whatsapp.service; + +import com.restroly.qrmenu.order.dto.OrderResponse; + +public interface WhatsappOrderNotificationService{ + void sendOrderConfirmation(OrderResponse order); + void sendOrderStatusUpdate(OrderResponse order); +} diff --git a/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/WhatsappService.java b/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/WhatsappService.java new file mode 100644 index 00000000..fa825397 --- /dev/null +++ b/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/WhatsappService.java @@ -0,0 +1,8 @@ +package com.restroly.qrmenu.whatsapp.service; + +import java.util.List; +import java.util.Map; + +public interface WhatsappService { + void sendTemplateMessage(String toPhoneNumber, String templateName, List> bodyParameters); +} diff --git a/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/impl/WhatsappOrderNotificationServiceImpl.java b/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/impl/WhatsappOrderNotificationServiceImpl.java new file mode 100644 index 00000000..0b832adb --- /dev/null +++ b/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/impl/WhatsappOrderNotificationServiceImpl.java @@ -0,0 +1,56 @@ +package com.restroly.qrmenu.whatsapp.service.impl; + +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import com.restroly.qrmenu.order.dto.OrderResponse; +import com.restroly.qrmenu.whatsapp.service.WhatsappOrderNotificationService; + +import lombok.extern.slf4j.Slf4j; +@Service +@Slf4j +public class WhatsappOrderNotificationServiceImpl extends WhatsappServiceImpl implements WhatsappOrderNotificationService{ + @Value("${whatsapp.message.template.order-confirmation}") + public String orderConfirmation; + @Value("${whatsapp.message.template.status-update}") + public String orderUpdateStatus; + + /** + * Sends the initial order confirmation using an approved Meta Template. + */ + @Async + public void sendOrderConfirmation(OrderResponse order) { + String templateName = orderConfirmation; // The exact name of your approved template in Meta + + // The parameters MUST be in the exact order as {{1}}, {{2}}, {{3}}, etc., in your Meta template + List> bodyParameters = List.of( + Map.of("type", "text", "text", order.getCustomerName()), // {{1}} + Map.of("type", "text", "text", String.valueOf(order.getOrderId())), // {{2}} + Map.of("type", "text", "text", order.getBranchName()), // {{3}} + Map.of("type", "text", "text", String.valueOf(order.getTableNumber())), // {{4}} + Map.of("type", "text", "text", order.getTotalAmount().toString()), // {{5}} + Map.of("type", "text", "text", order.getPaymentLink() != null ? order.getPaymentLink() : "Payment Due") // {{6}} + ); + sendTemplateMessage(order.getCustomerPhone(), templateName, bodyParameters); + } + /** + * Sends an update when the order status changes. + */ + @Async + public void sendOrderStatusUpdate(OrderResponse order) { + String templateName = orderUpdateStatus; + + // The parameters MUST match the exact order of {{1}}, {{2}}, {{3}} in your Meta template + List> bodyParameters = List.of( + Map.of("type", "text", "text", String.valueOf(order.getOrderId())), // {{1}} + Map.of("type", "text", "text", order.getCustomerName()), // {{2}} + Map.of("type", "text", "text", order.getStatus().name()) // {{3}} + ); + + sendTemplateMessage(order.getCustomerPhone(), templateName, bodyParameters); + } +} diff --git a/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/impl/WhatsappServiceImpl.java b/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/impl/WhatsappServiceImpl.java new file mode 100644 index 00000000..3c427845 --- /dev/null +++ b/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/impl/WhatsappServiceImpl.java @@ -0,0 +1,87 @@ +package com.restroly.qrmenu.whatsapp.service.impl; + +import com.restroly.qrmenu.whatsapp.service.WhatsappService; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; +import java.util.Map; + +@Service +@RequiredArgsConstructor +@Slf4j +public abstract class WhatsappServiceImpl implements WhatsappService { + private final RestTemplate restTemplate = new RestTemplate(); + + @Value("${whatsapp.api.url:https://graph.facebook.com/v25.0/}") + private String apiUrl; + + @Value("${whatsapp.api.phone-number-id}") + private String phoneNumberId; + + @Value("${whatsapp.api.token}") + private String accessToken; + + /** + * Core method to execute the HTTP POST request to Meta's Cloud API. + */ + public void sendTemplateMessage(String toPhoneNumber, String templateName, List> bodyParameters) { + try { + String url = apiUrl + phoneNumberId + "/messages"; + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.setBearerAuth(accessToken); + + // Constructing the JSON payload for a Template Message + Map payload = Map.of( + "messaging_product", "whatsapp", + "recipient_type", "individual", + "to", formatPhoneNumber(toPhoneNumber), + "type", "template", + "template", Map.of( + "name", templateName, + "language", Map.of("code", "en_US"), + "components", List.of( + Map.of( + "type", "body", + "parameters", bodyParameters + ) + ) + ) + ); + + HttpEntity> requestEntity = new HttpEntity<>(payload, headers); + + ResponseEntity response = restTemplate.postForEntity(url, requestEntity, String.class); + + if (response.getStatusCode().is2xxSuccessful()) { + log.info("WhatsApp template '{}' sent successfully to {}", templateName, toPhoneNumber); + } else { + log.warn("Failed to send WhatsApp template. Status: {}, Response: {}", + response.getStatusCode(), response.getBody()); + } + + } catch (Exception e) { + log.error("Exception occurred while sending WhatsApp template to {}: {}", toPhoneNumber, e.getMessage()); + } + } + + /** + * Utility to ensure the phone number doesn't have '+' or spaces, + * as required by the WhatsApp API. + */ + private String formatPhoneNumber(String phone) { + if (phone == null) return ""; + return phone.replaceAll("[^0-9]", ""); + } +} \ No newline at end of file diff --git a/RestroHub/src/main/resources/application.properties b/RestroHub/src/main/resources/application.properties index f8a1c3a0..3ea67ad4 100644 --- a/RestroHub/src/main/resources/application.properties +++ b/RestroHub/src/main/resources/application.properties @@ -104,6 +104,15 @@ google.oauth.client-id=${GOOGLE_OAUTH_CLIENT_ID:YOUR_GOOGLE_OAUTH_CLIENT_ID_HERE #--- UPI Link generation used as instructed --- payment.payee.name=Restroly +# =============================== +# WhatsApp +# =============================== +whatsapp.api.url=https://graph.facebook.com/v25.0/ +whatsapp.api.phone-number-id= your-phone-number-id +whatsapp.api.token= your-permanent-access-token +whatsapp.message.template.order-confirmation=approved_template +whatsapp.message.template.status-update=approved_template + # =============================== # Security / CORS # =============================== From 404813c4e28213eb8c764af5a277812b26d4a632 Mon Sep 17 00:00:00 2001 From: Souvik-D10 Date: Thu, 28 May 2026 09:52:19 +0530 Subject: [PATCH 2/3] Implemented suggessions --- .../qrmenu/RestaurantApplication.java | 2 ++ .../order/controller/OrderController.java | 9 ++++-- .../WhatsappOrderNotificationServiceImpl.java | 6 ++++ .../service/impl/WhatsappServiceImpl.java | 29 ++++++++++++------- .../src/main/resources/application.properties | 10 +++---- 5 files changed, 38 insertions(+), 18 deletions(-) diff --git a/RestroHub/src/main/java/com/restroly/qrmenu/RestaurantApplication.java b/RestroHub/src/main/java/com/restroly/qrmenu/RestaurantApplication.java index 75faa870..afff6ad4 100644 --- a/RestroHub/src/main/java/com/restroly/qrmenu/RestaurantApplication.java +++ b/RestroHub/src/main/java/com/restroly/qrmenu/RestaurantApplication.java @@ -6,11 +6,13 @@ import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.annotation.ComponentScan; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.scheduling.annotation.EnableAsync; @SpringBootApplication @ComponentScan(basePackages = "com.restroly.qrmenu") @EnableJpaRepositories(basePackages = "com.restroly.qrmenu") @EntityScan(basePackages = "com.restroly.qrmenu") +@EnableAsync public class RestaurantApplication extends SpringBootServletInitializer { public static void main(String[] args) { diff --git a/RestroHub/src/main/java/com/restroly/qrmenu/order/controller/OrderController.java b/RestroHub/src/main/java/com/restroly/qrmenu/order/controller/OrderController.java index b798dde5..bba01207 100644 --- a/RestroHub/src/main/java/com/restroly/qrmenu/order/controller/OrderController.java +++ b/RestroHub/src/main/java/com/restroly/qrmenu/order/controller/OrderController.java @@ -50,7 +50,8 @@ public ResponseEntity createOrder(@Valid @RequestBody CreateOrder //Genarated payment link is stored in response object to send it to client and use it for payment response.setPaymentLink(paymentUrl); //Sending whatsapp notification - whatsapp.sendOrderConfirmation(response); + if(response.getCustomerName() == null) response.setCustomerName("Customer"); + if(response.getCustomerPhone() != null) whatsapp.sendOrderConfirmation(response); return ResponseEntity.status(HttpStatus.CREATED).body(response); } @@ -74,7 +75,8 @@ public ResponseEntity updateOrderStatus(@PathVariable Long orderI @Valid @RequestBody UpdateOrderStatusRequest request) { OrderResponse response = orderService.updateOrderStatus(orderId, request.getStatus()); //Sending whatsapp notification - whatsapp.sendOrderStatusUpdate(response); + if(response.getCustomerName() == null) response.setCustomerName("Customer"); + if(response.getCustomerPhone() != null) whatsapp.sendOrderStatusUpdate(response); return ResponseEntity.ok(response); } @@ -82,7 +84,8 @@ public ResponseEntity updateOrderStatus(@PathVariable Long orderI public ResponseEntity cancelOrder(@PathVariable Long orderId) { OrderResponse response=orderService.cancelOrder(orderId); //sending cancel message - whatsapp.sendOrderStatusUpdate(response); + if(response.getCustomerName() == null) response.setCustomerName("Customer"); + if(response.getCustomerPhone() != null) whatsapp.sendOrderStatusUpdate(response); return ResponseEntity.noContent().build(); } } \ No newline at end of file diff --git a/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/impl/WhatsappOrderNotificationServiceImpl.java b/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/impl/WhatsappOrderNotificationServiceImpl.java index 0b832adb..f90b2de2 100644 --- a/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/impl/WhatsappOrderNotificationServiceImpl.java +++ b/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/impl/WhatsappOrderNotificationServiceImpl.java @@ -3,7 +3,9 @@ import java.util.List; import java.util.Map; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; @@ -14,6 +16,10 @@ @Service @Slf4j public class WhatsappOrderNotificationServiceImpl extends WhatsappServiceImpl implements WhatsappOrderNotificationService{ + @Autowired + public WhatsappOrderNotificationServiceImpl(RestTemplateBuilder builder) { + super(builder); + } @Value("${whatsapp.message.template.order-confirmation}") public String orderConfirmation; @Value("${whatsapp.message.template.status-update}") diff --git a/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/impl/WhatsappServiceImpl.java b/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/impl/WhatsappServiceImpl.java index 3c427845..9c7fbab9 100644 --- a/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/impl/WhatsappServiceImpl.java +++ b/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/impl/WhatsappServiceImpl.java @@ -2,7 +2,9 @@ import com.restroly.qrmenu.whatsapp.service.WhatsappService; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -13,6 +15,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import java.time.Duration; import java.util.List; import java.util.Map; @@ -20,7 +23,7 @@ @RequiredArgsConstructor @Slf4j public abstract class WhatsappServiceImpl implements WhatsappService { - private final RestTemplate restTemplate = new RestTemplate(); + private final RestTemplate restTemplate; @Value("${whatsapp.api.url:https://graph.facebook.com/v25.0/}") private String apiUrl; @@ -31,10 +34,19 @@ public abstract class WhatsappServiceImpl implements WhatsappService { @Value("${whatsapp.api.token}") private String accessToken; + @Autowired + public WhatsappServiceImpl(RestTemplateBuilder builder) { + this.restTemplate = builder + .setConnectTimeout(Duration.ofMillis(5000)) // Time to establish connection + .setReadTimeout(Duration.ofMillis(5000)) // Time to wait for data + .build(); + } + /** * Core method to execute the HTTP POST request to Meta's Cloud API. */ - public void sendTemplateMessage(String toPhoneNumber, String templateName, List> bodyParameters) { + public void sendTemplateMessage(String toPhoneNumber, String templateName, + List> bodyParameters) { try { String url = apiUrl + phoneNumberId + "/messages"; @@ -54,11 +66,7 @@ public void sendTemplateMessage(String toPhoneNumber, String templateName, List< "components", List.of( Map.of( "type", "body", - "parameters", bodyParameters - ) - ) - ) - ); + "parameters", bodyParameters)))); HttpEntity> requestEntity = new HttpEntity<>(payload, headers); @@ -67,7 +75,7 @@ public void sendTemplateMessage(String toPhoneNumber, String templateName, List< if (response.getStatusCode().is2xxSuccessful()) { log.info("WhatsApp template '{}' sent successfully to {}", templateName, toPhoneNumber); } else { - log.warn("Failed to send WhatsApp template. Status: {}, Response: {}", + log.warn("Failed to send WhatsApp template. Status: {}, Response: {}", response.getStatusCode(), response.getBody()); } @@ -77,11 +85,12 @@ public void sendTemplateMessage(String toPhoneNumber, String templateName, List< } /** - * Utility to ensure the phone number doesn't have '+' or spaces, + * Utility to ensure the phone number doesn't have '+' or spaces, * as required by the WhatsApp API. */ private String formatPhoneNumber(String phone) { - if (phone == null) return ""; + if (phone == null) + return ""; return phone.replaceAll("[^0-9]", ""); } } \ No newline at end of file diff --git a/RestroHub/src/main/resources/application.properties b/RestroHub/src/main/resources/application.properties index 3ea67ad4..5179ae20 100644 --- a/RestroHub/src/main/resources/application.properties +++ b/RestroHub/src/main/resources/application.properties @@ -107,11 +107,11 @@ payment.payee.name=Restroly # =============================== # WhatsApp # =============================== -whatsapp.api.url=https://graph.facebook.com/v25.0/ -whatsapp.api.phone-number-id= your-phone-number-id -whatsapp.api.token= your-permanent-access-token -whatsapp.message.template.order-confirmation=approved_template -whatsapp.message.template.status-update=approved_template +whatsapp.api.url=${WHATSAPP_URL:https://graph.facebook.com/v25.0/} +whatsapp.api.phone-number-id= ${PHONE_ID:your-phone-number-id} +whatsapp.api.token= ${WHATSAPP_ACCESS_TOKEN:your-permanent-access-token} +whatsapp.message.template.order-confirmation=${WHATSAPP_ORDER_CONFIRMATION_TEMPLATE_NAME:approved_template} +whatsapp.message.template.status-update=${WHATSAPP_ORDER_CONFIRMATION_TEMPLATE_NAME:approved_template} # =============================== # Security / CORS From d993338b268cc29013732d63b3993ab47970babe Mon Sep 17 00:00:00 2001 From: Souvik-D10 Date: Thu, 28 May 2026 10:35:21 +0530 Subject: [PATCH 3/3] Implemented retries for API Call --- .../service/impl/WhatsappServiceImpl.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/impl/WhatsappServiceImpl.java b/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/impl/WhatsappServiceImpl.java index 9c7fbab9..86c67180 100644 --- a/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/impl/WhatsappServiceImpl.java +++ b/RestroHub/src/main/java/com/restroly/qrmenu/whatsapp/service/impl/WhatsappServiceImpl.java @@ -70,13 +70,15 @@ public void sendTemplateMessage(String toPhoneNumber, String templateName, HttpEntity> requestEntity = new HttpEntity<>(payload, headers); - ResponseEntity response = restTemplate.postForEntity(url, requestEntity, String.class); - - if (response.getStatusCode().is2xxSuccessful()) { - log.info("WhatsApp template '{}' sent successfully to {}", templateName, toPhoneNumber); - } else { - log.warn("Failed to send WhatsApp template. Status: {}, Response: {}", - response.getStatusCode(), response.getBody()); + for (int i = 1; i <= 3; i++) { + ResponseEntity response = restTemplate.postForEntity(url, requestEntity, String.class); + if (response.getStatusCode().is2xxSuccessful()) { + log.info("WhatsApp template '{}' sent successfully to {}", templateName, toPhoneNumber); + break; + } else { + log.warn("Failed to send WhatsApp template. Status: {}, Response: {} for try {}", + response.getStatusCode(), response.getBody(),i); + } } } catch (Exception e) {