diff --git a/getting-started/sms/respond-to-incoming-message/server/pom.xml b/getting-started/sms/respond-to-incoming-message/server/pom.xml index 034dda8..2e6923a 100644 --- a/getting-started/sms/respond-to-incoming-message/server/pom.xml +++ b/getting-started/sms/respond-to-incoming-message/server/pom.xml @@ -16,7 +16,7 @@ Sinch Java SDK Server Application - [1.0.0,) + [1.5.0,] 21 diff --git a/getting-started/sms/respond-to-incoming-message/server/src/main/java/com/mycompany/app/sms/Controller.java b/getting-started/sms/respond-to-incoming-message/server/src/main/java/com/mycompany/app/sms/Controller.java index 0281477..0707396 100644 --- a/getting-started/sms/respond-to-incoming-message/server/src/main/java/com/mycompany/app/sms/Controller.java +++ b/getting-started/sms/respond-to-incoming-message/server/src/main/java/com/mycompany/app/sms/Controller.java @@ -1,15 +1,20 @@ package com.mycompany.app.sms; import com.sinch.sdk.SinchClient; -import com.sinch.sdk.domains.sms.WebHooksService; -import com.sinch.sdk.domains.sms.models.InboundText; -import com.sinch.sdk.domains.sms.models.webhooks.WebhooksEvent; +import com.sinch.sdk.domains.sms.api.v1.WebHooksService; +import com.sinch.sdk.domains.sms.models.v1.inbounds.TextMessage; +import com.sinch.sdk.domains.sms.models.v1.webhooks.SmsEvent; +import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ResponseStatusException; @RestController("SMS") public class Controller { @@ -17,6 +22,9 @@ public class Controller { private final SinchClient sinchClient; private final ServerBusinessLogic webhooksBusinessLogic; + @Value("${sms.webhooks.secret}") + private String webhooksSecret; + @Autowired public Controller(SinchClient sinchClient, ServerBusinessLogic webhooksBusinessLogic) { this.sinchClient = sinchClient; @@ -27,16 +35,29 @@ public Controller(SinchClient sinchClient, ServerBusinessLogic webhooksBusinessL value = "/SmsEvent", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity smsDeliveryEvent(@RequestBody String body) { + public ResponseEntity smsDeliveryEvent( + @RequestHeader Map headers, @RequestBody String body) { + + WebHooksService webhooks = sinchClient.sms().v1().webhooks(); - WebHooksService webhooks = sinchClient.sms().webHooks(); + // ensure valid authentication to handle request + // See + // https://developers.sinch.com/docs/sms/api-reference/sms/tag/Webhooks/#tag/Webhooks/section/Callbacks + // Contact your account manager to configure your callback sending headers validation or comment + // following line + var validAuth = webhooks.validateAuthenticationHeader(webhooksSecret, headers, body); + + // token validation failed + if (!validAuth) { + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED); + } // decode the request payload - WebhooksEvent event = webhooks.parse(body); + SmsEvent event = webhooks.parseEvent(body); // let business layer process the request switch (event) { - case InboundText e -> webhooksBusinessLogic.processInboundEvent(e); + case TextMessage e -> webhooksBusinessLogic.processInboundEvent(e); default -> throw new IllegalStateException("Unexpected value: " + event); } diff --git a/getting-started/sms/respond-to-incoming-message/server/src/main/java/com/mycompany/app/sms/ServerBusinessLogic.java b/getting-started/sms/respond-to-incoming-message/server/src/main/java/com/mycompany/app/sms/ServerBusinessLogic.java index 6ffecca..00820c1 100644 --- a/getting-started/sms/respond-to-incoming-message/server/src/main/java/com/mycompany/app/sms/ServerBusinessLogic.java +++ b/getting-started/sms/respond-to-incoming-message/server/src/main/java/com/mycompany/app/sms/ServerBusinessLogic.java @@ -1,9 +1,10 @@ package com.mycompany.app.sms; import com.sinch.sdk.SinchClient; -import com.sinch.sdk.domains.sms.BatchesService; -import com.sinch.sdk.domains.sms.models.InboundText; -import com.sinch.sdk.domains.sms.models.requests.SendSmsBatchTextRequest; +import com.sinch.sdk.domains.sms.api.v1.BatchesService; +import com.sinch.sdk.domains.sms.models.v1.batches.request.TextRequest; +import com.sinch.sdk.domains.sms.models.v1.batches.response.BatchResponse; +import com.sinch.sdk.domains.sms.models.v1.inbounds.TextMessage; import java.util.Collections; import java.util.logging.Logger; import org.springframework.stereotype.Component; @@ -14,17 +15,17 @@ public class ServerBusinessLogic { private final BatchesService batches; public ServerBusinessLogic(SinchClient sinchClient) { - this.batches = sinchClient.sms().batches(); + this.batches = sinchClient.sms().v1().batches(); } private static final Logger LOGGER = Logger.getLogger(ServerBusinessLogic.class.getName()); - public void processInboundEvent(InboundText event) { + public void processInboundEvent(TextMessage event) { LOGGER.info("Handle event: " + event); - SendSmsBatchTextRequest smsRequest = - SendSmsBatchTextRequest.builder() + TextRequest smsRequest = + TextRequest.builder() .setTo(Collections.singletonList(event.getFrom())) .setBody("You sent: " + event.getBody()) .setFrom(event.getTo()) @@ -32,6 +33,8 @@ public void processInboundEvent(InboundText event) { LOGGER.info("Replying with: " + smsRequest); - batches.send(smsRequest); + BatchResponse response = batches.send(smsRequest); + + LOGGER.info("Response: " + response); } } diff --git a/getting-started/sms/respond-to-incoming-message/server/src/main/resources/application.yaml b/getting-started/sms/respond-to-incoming-message/server/src/main/resources/application.yaml index 6433f49..2a0ef28 100644 --- a/getting-started/sms/respond-to-incoming-message/server/src/main/resources/application.yaml +++ b/getting-started/sms/respond-to-incoming-message/server/src/main/resources/application.yaml @@ -19,3 +19,6 @@ sms: # Sets the region for SMS # valid values are US and EU region: + +sms.webhooks.secret: + \ No newline at end of file diff --git a/getting-started/verification/user-verification-using-sms-pin/client/pom.xml b/getting-started/verification/user-verification-using-sms-pin/client/pom.xml index 6408a28..af779f8 100644 --- a/getting-started/verification/user-verification-using-sms-pin/client/pom.xml +++ b/getting-started/verification/user-verification-using-sms-pin/client/pom.xml @@ -11,7 +11,7 @@ Sinch Java SDK Client Application - [1.0.0,) + [1.5.0,) 8 8 3.13.0 diff --git a/getting-started/voice/respond-to-incoming-call/server/pom.xml b/getting-started/voice/respond-to-incoming-call/server/pom.xml index 034dda8..b7ec97c 100644 --- a/getting-started/voice/respond-to-incoming-call/server/pom.xml +++ b/getting-started/voice/respond-to-incoming-call/server/pom.xml @@ -16,7 +16,7 @@ Sinch Java SDK Server Application - [1.0.0,) + [1.5.0,) 21 diff --git a/pom-ci.xml b/pom-ci.xml index 6748db0..d27f958 100644 --- a/pom-ci.xml +++ b/pom-ci.xml @@ -11,7 +11,7 @@ Sinch Java SDK Client quickstart - [1.0.0,) + [1.5.0,) 21 21 3.8.0 diff --git a/templates/client/pom.xml b/templates/client/pom.xml index 6408a28..af779f8 100644 --- a/templates/client/pom.xml +++ b/templates/client/pom.xml @@ -11,7 +11,7 @@ Sinch Java SDK Client Application - [1.0.0,) + [1.5.0,) 8 8 3.13.0 diff --git a/templates/client/src/main/java/Application.java b/templates/client/src/main/java/Application.java index 208eb43..87df54c 100644 --- a/templates/client/src/main/java/Application.java +++ b/templates/client/src/main/java/Application.java @@ -40,7 +40,7 @@ public static void main(String[] args) { // comment if unused if (client.getConfiguration().getSmsServicePlanCredentials().isPresent() || client.getConfiguration().getUnifiedCredentials().isPresent()) { - SmsQuickStart sms = new SmsQuickStart(client.sms()); + SmsQuickStart sms = new SmsQuickStart(client.sms().v1()); } // Verification service dedicated business logic processing diff --git a/templates/client/src/main/java/sms/SmsQuickStart.java b/templates/client/src/main/java/sms/SmsQuickStart.java index 57dccf5..3228327 100644 --- a/templates/client/src/main/java/sms/SmsQuickStart.java +++ b/templates/client/src/main/java/sms/SmsQuickStart.java @@ -1,6 +1,6 @@ package sms; -import com.sinch.sdk.domains.sms.*; +import com.sinch.sdk.domains.sms.api.v1.SMSService; public class SmsQuickStart { diff --git a/templates/client/src/main/java/sms/Snippet.java b/templates/client/src/main/java/sms/Snippet.java index 9860195..6940508 100644 --- a/templates/client/src/main/java/sms/Snippet.java +++ b/templates/client/src/main/java/sms/Snippet.java @@ -1,6 +1,6 @@ package sms; -import com.sinch.sdk.domains.sms.*; +import com.sinch.sdk.domains.sms.api.v1.SMSService; import java.util.logging.Logger; public class Snippet { diff --git a/templates/server/pom.xml b/templates/server/pom.xml index 034dda8..b7ec97c 100644 --- a/templates/server/pom.xml +++ b/templates/server/pom.xml @@ -16,7 +16,7 @@ Sinch Java SDK Server Application - [1.0.0,) + [1.5.0,) 21 diff --git a/templates/server/src/main/java/com/mycompany/app/sms/Controller.java b/templates/server/src/main/java/com/mycompany/app/sms/Controller.java index 890f1ca..4041044 100644 --- a/templates/server/src/main/java/com/mycompany/app/sms/Controller.java +++ b/templates/server/src/main/java/com/mycompany/app/sms/Controller.java @@ -1,18 +1,21 @@ package com.mycompany.app.sms; import com.sinch.sdk.SinchClient; -import com.sinch.sdk.domains.sms.WebHooksService; -import com.sinch.sdk.domains.sms.models.DeliveryReportBatch; -import com.sinch.sdk.domains.sms.models.DeliveryReportRecipient; -import com.sinch.sdk.domains.sms.models.InboundBinary; -import com.sinch.sdk.domains.sms.models.InboundText; -import com.sinch.sdk.domains.sms.models.webhooks.WebhooksEvent; +import com.sinch.sdk.domains.sms.api.v1.WebHooksService; +import com.sinch.sdk.domains.sms.models.v1.deliveryreports.DeliveryReport; +import com.sinch.sdk.domains.sms.models.v1.inbounds.InboundMessage; +import com.sinch.sdk.domains.sms.models.v1.webhooks.SmsEvent; +import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ResponseStatusException; @RestController("SMS") public class Controller { @@ -20,6 +23,9 @@ public class Controller { private final SinchClient sinchClient; private final ServerBusinessLogic webhooksBusinessLogic; + @Value("${sms.webhooks.secret}") + private String webhooksSecret; + @Autowired public Controller(SinchClient sinchClient, ServerBusinessLogic webhooksBusinessLogic) { this.sinchClient = sinchClient; @@ -30,19 +36,30 @@ public Controller(SinchClient sinchClient, ServerBusinessLogic webhooksBusinessL value = "/SmsEvent", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity smsDeliveryEvent(@RequestBody String body) { + public ResponseEntity smsDeliveryEvent( + @RequestHeader Map headers, @RequestBody String body) { + + WebHooksService webhooks = sinchClient.sms().v1().webhooks(); - WebHooksService webhooks = sinchClient.sms().webHooks(); + // ensure valid authentication to handle request + // See + // https://developers.sinch.com/docs/sms/api-reference/sms/tag/Webhooks/#tag/Webhooks/section/Callbacks + // Contact your account manager to configure your callback sending headers validation or comment + // following line + var validAuth = webhooks.validateAuthenticationHeader(webhooksSecret, headers, body); + + // token validation failed + if (!validAuth) { + throw new ResponseStatusException(HttpStatus.UNAUTHORIZED); + } // decode the request payload - WebhooksEvent event = webhooks.parse(body); + SmsEvent event = webhooks.parseEvent(body); // let business layer process the request switch (event) { - case InboundBinary e -> webhooksBusinessLogic.processInboundEvent(e); - case InboundText e -> webhooksBusinessLogic.processInboundEvent(e); - case DeliveryReportRecipient e -> webhooksBusinessLogic.processDeliveryReportEvent(e); - case DeliveryReportBatch e -> webhooksBusinessLogic.processDeliveryReportEvent(e); + case InboundMessage e -> webhooksBusinessLogic.processInboundEvent(e); + case DeliveryReport e -> webhooksBusinessLogic.processDeliveryReportEvent(e); default -> throw new IllegalStateException("Unexpected value: " + event); } diff --git a/templates/server/src/main/java/com/mycompany/app/sms/ServerBusinessLogic.java b/templates/server/src/main/java/com/mycompany/app/sms/ServerBusinessLogic.java index 561012e..a8dd2c9 100644 --- a/templates/server/src/main/java/com/mycompany/app/sms/ServerBusinessLogic.java +++ b/templates/server/src/main/java/com/mycompany/app/sms/ServerBusinessLogic.java @@ -1,10 +1,8 @@ package com.mycompany.app.sms; -import com.sinch.sdk.domains.sms.models.DeliveryReportBatch; -import com.sinch.sdk.domains.sms.models.DeliveryReportRecipient; -import com.sinch.sdk.domains.sms.models.InboundBinary; -import com.sinch.sdk.domains.sms.models.InboundText; -import com.sinch.sdk.domains.sms.models.webhooks.WebhooksEvent; +import com.sinch.sdk.domains.sms.models.v1.deliveryreports.DeliveryReport; +import com.sinch.sdk.domains.sms.models.v1.inbounds.InboundMessage; +import com.sinch.sdk.domains.sms.models.v1.webhooks.SmsEvent; import java.util.logging.Logger; import org.springframework.stereotype.Component; @@ -13,23 +11,15 @@ public class ServerBusinessLogic { private static final Logger LOGGER = Logger.getLogger(ServerBusinessLogic.class.getName()); - public void processInboundEvent(InboundText event) { + public void processInboundEvent(InboundMessage event) { trace(event); } - public void processInboundEvent(InboundBinary event) { + public void processDeliveryReportEvent(DeliveryReport event) { trace(event); } - public void processDeliveryReportEvent(DeliveryReportRecipient event) { - trace(event); - } - - public void processDeliveryReportEvent(DeliveryReportBatch event) { - trace(event); - } - - private void trace(WebhooksEvent event) { + private void trace(SmsEvent event) { LOGGER.info("Handle event: " + event); } } diff --git a/templates/server/src/main/resources/application.yaml b/templates/server/src/main/resources/application.yaml index 92d72f1..3db4ba9 100644 --- a/templates/server/src/main/resources/application.yaml +++ b/templates/server/src/main/resources/application.yaml @@ -31,3 +31,7 @@ numbers.webhooks.secret: # Secret value set for Conversation webhooks calls validation conversation.webhooks.secret: + +# Secret value set for Conversation webhooks calls validation +sms.webhooks.secret: + \ No newline at end of file diff --git a/tutorials/sms/auto-subscribe-app/pom.xml b/tutorials/sms/auto-subscribe-app/pom.xml index ec93517..2a44686 100644 --- a/tutorials/sms/auto-subscribe-app/pom.xml +++ b/tutorials/sms/auto-subscribe-app/pom.xml @@ -17,7 +17,7 @@ Demo Project for auto-subscribe - [1.0.0,) + [1.5.0,) 21 diff --git a/tutorials/sms/auto-subscribe-app/src/main/java/com/mycompany/app/AutoSubscribeController.java b/tutorials/sms/auto-subscribe-app/src/main/java/com/mycompany/app/AutoSubscribeController.java index 9a6c0b3..aec44e3 100644 --- a/tutorials/sms/auto-subscribe-app/src/main/java/com/mycompany/app/AutoSubscribeController.java +++ b/tutorials/sms/auto-subscribe-app/src/main/java/com/mycompany/app/AutoSubscribeController.java @@ -1,7 +1,7 @@ package com.mycompany.app; -import com.sinch.sdk.domains.sms.SMSService; -import com.sinch.sdk.domains.sms.models.InboundText; +import com.sinch.sdk.domains.sms.api.v1.SMSService; +import com.sinch.sdk.domains.sms.models.v1.inbounds.TextMessage; import java.util.Objects; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; @@ -25,10 +25,10 @@ public AutoSubscribeController(SMSService smsService, AutoSubscribeService servi public void smsDeliveryEvent(@RequestBody String body) { // decode the request payload - var event = smsService.webHooks().parse(body); + var event = smsService.webhooks().parseEvent(body); // let business layer process the request - if (Objects.requireNonNull(event) instanceof InboundText e) { + if (Objects.requireNonNull(event) instanceof TextMessage e) { service.processInboundEvent(e); } else { throw new IllegalStateException("Unexpected value: " + event); diff --git a/tutorials/sms/auto-subscribe-app/src/main/java/com/mycompany/app/AutoSubscribeService.java b/tutorials/sms/auto-subscribe-app/src/main/java/com/mycompany/app/AutoSubscribeService.java index d6d1024..a72fdb0 100644 --- a/tutorials/sms/auto-subscribe-app/src/main/java/com/mycompany/app/AutoSubscribeService.java +++ b/tutorials/sms/auto-subscribe-app/src/main/java/com/mycompany/app/AutoSubscribeService.java @@ -1,10 +1,10 @@ package com.mycompany.app; -import com.sinch.sdk.domains.sms.SMSService; -import com.sinch.sdk.domains.sms.models.Group; -import com.sinch.sdk.domains.sms.models.InboundText; -import com.sinch.sdk.domains.sms.models.requests.GroupUpdateRequestParameters; -import com.sinch.sdk.domains.sms.models.requests.SendSmsBatchTextRequest; +import com.sinch.sdk.domains.sms.api.v1.SMSService; +import com.sinch.sdk.domains.sms.models.v1.batches.request.TextRequest; +import com.sinch.sdk.domains.sms.models.v1.groups.Group; +import com.sinch.sdk.domains.sms.models.v1.groups.request.GroupUpdateRequest; +import com.sinch.sdk.domains.sms.models.v1.inbounds.TextMessage; import java.util.Collection; import java.util.Collections; import java.util.logging.Logger; @@ -28,7 +28,7 @@ public AutoSubscribeService(SMSService smsService, GroupManager groupManager) { this.group = groupManager.getGroup(); } - public void processInboundEvent(InboundText event) { + public void processInboundEvent(TextMessage event) { LOGGER.info("Received event:" + event); @@ -65,7 +65,7 @@ private String processAction( return unsubscribe(group, isMemberInGroup, to, from); } - return unknwownAction(isMemberInGroup, to); + return unknownAction(isMemberInGroup, to); } private String subscribe( @@ -76,8 +76,7 @@ private String subscribe( .formatted(group.getName(), STOP_ACTION, groupPhoneNumber); } - var request = - GroupUpdateRequestParameters.builder().setAdd(Collections.singletonList(member)).build(); + var request = GroupUpdateRequest.builder().setAdd(Collections.singletonList(member)).build(); smsService.groups().update(group.getId(), request); return "Congratulations! You are now subscribed to '%s'. Text \"%s\" to +%s to leave this group." @@ -92,15 +91,14 @@ private String unsubscribe( .formatted(group.getName(), SUBSCRIBE_ACTION, groupPhoneNumber); } - var request = - GroupUpdateRequestParameters.builder().setRemove(Collections.singletonList(member)).build(); + var request = GroupUpdateRequest.builder().setRemove(Collections.singletonList(member)).build(); smsService.groups().update(group.getId(), request); return "We're sorry to see you go. You can always rejoin '%s' by texting \"%s\" to +%s." .formatted(group.getName(), SUBSCRIBE_ACTION, groupPhoneNumber); } - private String unknwownAction(boolean isMemberInGroup, String to) { + private String unknownAction(boolean isMemberInGroup, String to) { String message = isMemberInGroup @@ -116,7 +114,7 @@ private String unknwownAction(boolean isMemberInGroup, String to) { private void sendResponse(String from, String to, String response) { var request = - SendSmsBatchTextRequest.builder() + TextRequest.builder() .setTo(Collections.singletonList(to)) .setBody(response) .setFrom(from) diff --git a/tutorials/sms/auto-subscribe-app/src/main/java/com/mycompany/app/Config.java b/tutorials/sms/auto-subscribe-app/src/main/java/com/mycompany/app/Config.java index 49cce89..2e0df24 100644 --- a/tutorials/sms/auto-subscribe-app/src/main/java/com/mycompany/app/Config.java +++ b/tutorials/sms/auto-subscribe-app/src/main/java/com/mycompany/app/Config.java @@ -1,7 +1,7 @@ package com.mycompany.app; import com.sinch.sdk.SinchClient; -import com.sinch.sdk.domains.sms.SMSService; +import com.sinch.sdk.domains.sms.api.v1.SMSService; import com.sinch.sdk.models.Configuration; import com.sinch.sdk.models.SMSRegion; import org.springframework.beans.factory.annotation.Value; @@ -30,6 +30,6 @@ public SMSService smsService() { .setSmsRegion(SMSRegion.US) .build(); - return new SinchClient(configuration).sms(); + return new SinchClient(configuration).sms().v1(); } } diff --git a/tutorials/sms/auto-subscribe-app/src/main/java/com/mycompany/app/GroupManager.java b/tutorials/sms/auto-subscribe-app/src/main/java/com/mycompany/app/GroupManager.java index bb20311..af3a577 100644 --- a/tutorials/sms/auto-subscribe-app/src/main/java/com/mycompany/app/GroupManager.java +++ b/tutorials/sms/auto-subscribe-app/src/main/java/com/mycompany/app/GroupManager.java @@ -1,9 +1,9 @@ package com.mycompany.app; -import com.sinch.sdk.domains.sms.GroupsService; -import com.sinch.sdk.domains.sms.SMSService; -import com.sinch.sdk.domains.sms.models.Group; -import com.sinch.sdk.domains.sms.models.requests.GroupCreateRequestParameters; +import com.sinch.sdk.domains.sms.api.v1.GroupsService; +import com.sinch.sdk.domains.sms.api.v1.SMSService; +import com.sinch.sdk.domains.sms.models.v1.groups.Group; +import com.sinch.sdk.domains.sms.models.v1.groups.request.GroupRequest; import jakarta.annotation.PreDestroy; import java.util.Optional; import java.util.logging.Logger; @@ -66,7 +66,7 @@ private Optional retrieveGroup(GroupsService groupsService) { */ private Group createGroup(GroupsService groupsService) { - var request = GroupCreateRequestParameters.builder().setName(GROUP_NAME).build(); + var request = GroupRequest.builder().setName(GROUP_NAME).build(); var group = groupsService.create(request);