Skip to content

Commit

Permalink
responding to sms message gs
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-sberna committed Jul 23, 2024
1 parent 8d1995f commit a03c7d6
Show file tree
Hide file tree
Showing 8 changed files with 268 additions and 3 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.idea
**/.vscode
**/target
78 changes: 78 additions & 0 deletions getting-started/sms/respond-to-incoming-message/server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Backend application built using Sinch Java SDK to handle incoming webhooks

This directory contains a server application based onto [Sinch SDK java](https://github.com/sinch/sinch-sdk-java)

## Requirements

- JDK 8 or later (Sinch SDK Java is requiring java 8 only but client application can use latest available version)
- [Maven](https://maven.apache.org/)
- [SpringBoot](https://spring.io/projects/spring-boot)
- [Sinch account](https://dashboard.sinch.com)
- [ngrok](https://ngrok.com/docs)

## Configuration

### Configure application settings

com.mycompany.app.Application settings are using the `SpringBoot` configuration file: [`application.yaml`](src/main/resources/application.yaml) file and enable to configure:

#### Sinch credentials
Located in `credentials` section (*you can find all of the credentials you need on your [Sinch dashboard](https://dashboard.sinch.com)*):
- `project-id`: YOUR_project_id
- `key-id`: YOUR_access_key_id
- `key-secret`: YOUR_access_key_secret

#### Server port
<em>Default: 8090</em>

Located in `server` section:
- port: The port to be used to listen to incoming requests. <em>Default: 8090</em>

## Usage

### Start server
1. Edit configuration file

See above for Configuration paragraph

2. Start server locally.

Compile and run the application as server locally.
```bash
mvn spring-boot:run
```
### EndPoints
When server is online, declared controllers will respond to following endpoints

| Service | Endpoint |
|--------------|--------------------|
| Numbers | /NumbersEvent |
| SMS | /SmsEvent |
| Verification | /VerificationEvent |
| Voice | /VoiceEvent |

## Use ngrok to forward request to local server

Forwarding request to same `8090` port used above:

*Note: The `8090` value is coming from default config and can be changed (see [Server port](#Server port) configuration section)*

```bash
ngrok http 8090
```

ngrok output will contains output like:
```
ngrok (Ctrl+C to quit)
...
Forwarding https://0e64-78-117-86-140.ngrok-free.app -> http://localhost:8090
```
The line
```
Forwarding https://0e64-78-117-86-140.ngrok-free.app -> http://localhost:8090
```
Contains `https://0e64-78-117-86-140.ngrok-free.app` value.

This value must be used to configure callback's URL from your [Sinch dashboard](https://dashboard.sinch.com/sms/api/services)
51 changes: 51 additions & 0 deletions getting-started/sms/respond-to-incoming-message/server/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<groupId>my.company.com</groupId>
<artifactId>sinch-java-sdk-server-application</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Sinch Java SDK Server Application</name>

<properties>
<sinch.sdk.java.version>[1.0.0,)</sinch.sdk.java.version>
<java.version>21</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>com.sinch.sdk</groupId>
<artifactId>sinch-sdk-java</artifactId>
<version>${sinch.sdk.java.version}</version>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.mycompany.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.mycompany.app;

import com.sinch.sdk.SinchClient;
import com.sinch.sdk.core.utils.StringUtil;
import com.sinch.sdk.models.Configuration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;

@org.springframework.context.annotation.Configuration
public class Config {

@Value("${credentials.project-id}")
String projectId;

@Value("${credentials.key-id}")
String keyId;

@Value("${credentials.key-secret}")
String keySecret;

@Bean
public SinchClient sinchClient() {

Configuration.Builder builder = Configuration.builder();

if (!StringUtil.isEmpty(projectId)) {
builder.setProjectId(projectId);
}

if (!StringUtil.isEmpty(keyId)) {
builder.setKeyId(keyId);
}
if (!StringUtil.isEmpty(keySecret)) {
builder.setKeySecret(keySecret);
}

return new SinchClient(builder.build());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.mycompany.app.sms;

import com.sinch.sdk.SinchClient;
import com.sinch.sdk.domains.sms.BatchesService;
import com.sinch.sdk.domains.sms.WebHooksService;
import com.sinch.sdk.domains.sms.adapters.SMSService;
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 org.springframework.beans.factory.annotation.Autowired;
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.RestController;

@RestController("SMS")
public class Controller {

private final SinchClient sinchClient;
private final ServerBusinessLogic webhooksBusinessLogic;

@Autowired
public Controller(SinchClient sinchClient, ServerBusinessLogic webhooksBusinessLogic) {
this.sinchClient = sinchClient;
this.webhooksBusinessLogic = webhooksBusinessLogic;
}

@PostMapping(
value = "/SmsEvent",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Void> smsDeliveryEvent(@RequestBody String body) {

WebHooksService webhooks = sinchClient.sms().webHooks();

// decode the request payload
WebhooksEvent event = webhooks.parse(body);

// let business layer process the request
switch (event) {
case InboundText e -> webhooksBusinessLogic.processInboundEvent(e);
default -> throw new IllegalStateException("Unexpected value: " + event);
}

return ResponseEntity.ok().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
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.models.webhooks.WebhooksEvent;

import java.util.Collections;
import java.util.logging.Logger;
import org.springframework.stereotype.Component;

@Component("SMSServerBusinessLogic")
public class ServerBusinessLogic {

private final BatchesService batches;

public ServerBusinessLogic(SinchClient sinchClient, BatchesService batchesService){
this.batches = sinchClient.sms().batches();
}

private static final Logger LOGGER = Logger.getLogger(ServerBusinessLogic.class.getName());

public void processInboundEvent(InboundText event) {
trace(event);

batches.send(SendSmsBatchTextRequest.builder()
.setTo(Collections.singletonList(event.getFrom()))
.setBody("You sent: " + event.getBody())
.setFrom(event.getTo())
.build());
}

private void trace(WebhooksEvent event) {
LOGGER.info("Handle event: " + event);
}
}

This file was deleted.

0 comments on commit a03c7d6

Please sign in to comment.