This content originally appeared on Twilio Blog and was authored by Matthew Gilliard
If you're wondering how to send SMS from Java code, we've got you covered already. However, people are increasingly expecting to be able to converse with companies and services rather than just get a never-ending stream of notifications. To build really engaging and interactive apps you're going to want to respond to incoming messages too.
To do that, you will need to configure a URL in your Twilio console. Incoming messages will trigger HTTP requests to that URL, and the response to those webhook requests will determine what happens next, including sending responses. Responses should be written in an XML dialect called Twilio Markup Language, or TwiML.
In this post I'll walk you through setting up a web server using Spring Boot to do just that.
Getting set up
Before we get started, you'll need:
- An installation of Java 8 or newer - I recommend SDKMAN! for installing and managing Java versions.
- A Java IDE - I'm a fan of IntelliJ IDEA, but if you have a favourite that's cool too.
- A Twilio account (if you don't have one yet, sign up for a free account here and receive $10 credit when you upgrade)
- A Twilio phone number that can send and receive SMS
- Either ngrok or the Twilio CLI, so that you canrespond to webhooks in your local development environment
The best way to spin up a brand new Spring Boot project is using the Spring Initializr. This link will take you to a preconfigured setup with the web dependency selected and some names preconfigured. Load that page up, click "Generate" and unzip the downloaded project into an empty directory. Then, open the project in your IDE of choice and let's get cracking.
Building the application
When you open up the codebase you will see the top level of the project. Open the nested folders src/main/java
and find the package called com.example.twilio.sms
, with a single class, called RespondToSmsWithTwilioAndJavaApplication
. You won't need to edit that class, but it has a main
method that will be helpful later.
Creating an HTTP endpoint
For now, create another class in the same package with the following definition, and call it SmsWebhookHandler
:
@RestController
public class SmsWebhookHandler {
@PostMapping("/")
@ResponseBody
public String handleSmsWebhook(){
return "Hello from Twilio";
}
}
[full code including imports on GitHub]
You can run the application now, either by running the main
method from RespondToSmsWithTwilioAndJavaApplication
in your IDE, or ./mvnw spring-boot:run
in a terminal window at the root of your project.
After it's running, test it by using the command below.
curl -XPOST http://localhost:8080
You should see "Hello from Twilio" as the response.
Returning TwiML over HTTP
We've made a good start so far. Next we need to return TwiML so that Twilio can understand the response.
It's possible to write TwiML by hand, but easier to do using the Twilio Java Helper Library. Add the code below to the <dependencies>
section of pom.xml
in the root of your project.
<dependency>
<groupId>com.twilio.sdk</groupId>
<artifactId>twilio</artifactId>
<version>8.8.0</version>
</dependency>
We always recommend using the latest version of the Twilio Helper Library. At the time of writing this is version `8.8.0`. You can always check the latest version at mvnreporistory.com.
Now, let's make a few changes to the code in SmsWebhookHandler
. Change the class to have this definition:
@RestController
public class SmsWebhookHandler {
private final Map<String, Integer> messageCounts = new ConcurrentHashMap<>();
@PostMapping(value = "/", produces = "application/xml")
@ResponseBody
public String handleSmsWebhook(
@RequestParam("From") String from,
@RequestParam("Body") String body){
int thisMessageCount = messageCounts.compute(from, (k,v) -> (v == null) ? 1 : v+1);
String plural = (thisMessageCount > 1) ? "messages" : "message";
String message = String.format(
"☎️ Hello from Twilio. You've sent %d %s, and this one said '%s'",
thisMessageCount, plural, body);
return new MessagingResponse.Builder()
.message(new Message.Builder(message).build())
.build().toXml();
}
}
[full code including imports on GitHub]
There are a few things going on here, so let's step through them:
- Line 4: creates a new map from String to Integer to count how many messages we've had from each unique phone number. Because Spring will only create one instance of this class, the
Map
is shared between all calls. - Line 6: notice that the endpoint now has a content-type of
application/xml
. - Lines 9-10: we can pull out data from the incoming request using
@RequestParam
. Here I'm only using theFrom
number and the messageBody
but there is a lot more you could access. - Line 12: update the
messageCounts
map to account for this new message. - Lines 14-17: build the String to be used as the message response.
- Lines 19-21: finally, build the TwiML response and return it as an XML String.
To test the code, run the project as before. Then, when it's running, run the command below.
curl http://localhost:8080/ -F From=+1234567890 -F Body=Hello
You should receive the following response:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Message>☎️ Hello from Twilio. You've sent 1 message, and this one said 'Hello'</Message>
</Response>
(note that I've added line-breaks to this output)
Connecting to a Twilio phone number
The last piece of the puzzle is how to configure Twilio to use this app when a message comes in. As I said in the introduction, you need to configure your phone number with a URL for the application. Because you're running the application locally, you only have a localhost
URL, which Twilio won't be able to access. There are several options for public hosting with Java, but one tool which I like to use for development is ngrok
, which can create public URLs that forward to your localhost
web apps.
Once you have installed ngrok
and restarted your app using your IDE or the command from above, the following command will create a public URL for your local server:
ngrok http 8080
Once the tunnel has connected, ngrok displays the randomly generated URL that now points at your application. It should look like https://RANDOM_STRING.ngrok.io
. Open up your Twilio console to your incoming numbers and choose the number you want to use for this app, or buy a new one. Edit the number and add your ngrok URL as the webhook for when a message comes in (leaving the method as POST
).
If you have the Twilio CLI installed you can do this on the command line too, with the command below.
twilio phone-numbers:update PHONE_NUMBER
--sms-url http://localhost:3000/messages
The CLI will detect that this is a localhost URL and set up ngrok for you.
Text your number a few times and see the replies roll in.
??? Nice Work ???
Wrapping up
You've learned how to respond to SMS using Twilio and Java, and you can learn how to initiate outbound SMS. Also, you've seen that you can customize responses based on who is messaging you and what they say. Now the limit is your imagination. Will you build a book(store) recommender, a community healthcare system, a chatbot, or something brand new?
Whatever you're building, I'd love to hear about it - get in touch
I can't wait to see what you build!
This content originally appeared on Twilio Blog and was authored by Matthew Gilliard
Matthew Gilliard | Sciencx (2021-03-23T21:34:23+00:00) Receiving and Responding to SMS with Java and Twilio. Retrieved from https://www.scien.cx/2021/03/23/receiving-and-responding-to-sms-with-java-and-twilio/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.