---slug: /guides/messaging/compatibility-api/handling-incoming-messages-from-codex-custom: author: danieleds---# Handling Incoming Messages from Codeimport Tabs from @theme/Tabs;import TabItem from @theme/TabItem;In [Receiving your firstSMS](guides/messaging-api/getting-started/receiving-your-first-sms/index.mdx) welearned how to use Compatibility XML bins to handle incoming messages. Inparticular, we showed how to reply with a static message to any incoming SMS.Handling messages from code gives us more flexibility. Instead of serving astatic XML bin, we can use a custom web server to decide the content of the XMLdepending on the incoming message.In this guide, we will show how to create a simple subscription service: userswill be able to text START or STOP, and we will reply respectively withSubscription started! or Subscription Stopped.## Setting up the environmentWe are going to use a few libraries to make our job easier. In particular, wellneed the SignalWire Compatibility SDK and, depending on the language youreusing, well also need a web server. Lets install them:shellpip install flask signalwireshellcomposer require signalwire-community/signalwireshellnpm install express @signalwire/compatibility-api## Producing XMLWed like to set up an endpoint (our own dynamic XML bin) which emits an XML document, like this one:xmlSubscription started!The XML will be sent back to the client as a response to their request.In principle, we could manually create such XML by means of string concatenationor interpolation. However, if you are using one of our supported languages, youcan use our libraries to more easily produce the same XML:pythonfrom twilio.twiml.messaging_response import MessagingResponseresponse = MessagingResponse()response.message(Subscription started!)# Prints the XML string.print(response.to_xml())phprequire_once vendor/autoload.php;use \SignalWire\LaML\MessageResponse;$response = new MessageResponse;$response->message(Subscription started!);# Prints the XML string.echo $response->asXML();javascriptimport { RestClient } from @signalwire/compatibility-api;const response = new RestClient.LaML.MessagingResponse();response.message(Subscription started!);// Prints the XML string.console.log(response.toString());## Serving the XMLNow that we know how to generate a proper Compatibility XML document, lets seehow to set up a web server to serve those documents.### Setting up a web serverHow you set up the web server is mostly specific to the language and frameworkof your choosing. A basic skeleton might be the following:python title=main.pyfrom flask import Flask, request, Responsefrom twilio.twiml.messaging_response import MessagingResponseapp = Flask(__name__)@app.route(/, methods=[GET, POST])def message_handler(): This endpoint will be queried by SignalWire whenever an incoming SMS is received. We respond with an XML document which specifies the next instructions. print(request.values) # The logic goes here returnphp title=index.phprequire_once vendor/autoload.php;use \SignalWire\LaML\MessageResponse;# This endpoint will be queried by SignalWire whenever an incoming SMS is received.# We respond with an XML document which specifies the next instructions.print_r($_REQUEST);# The logic goes herejavascript title=index.jsimport express from express;import { RestClient } from @signalwire/compatibility-api;const app = express();app.use(express.urlencoded({ extended: true }));/** * @param {express.Request} req * @param {express.Response} res */function messageHandler(req, res) { // This endpoint will be queried by SignalWire whenever an incoming SMS is received. // We respond with an XML document which specifies the next instructions. /** @type string */ const body = req.body?.[Body] ?? req.query?.[Body]; console.log(req.body); // The logic goes here.}app.get(/, messageHandler);app.post(/, messageHandler);app.listen(8080);In the next section we will configure a phone number so that, when it receives amessage, SignalWire makes an HTTP request to our message handler endpoint. TheHTTP request will contain as parameters values such as the source number or thebody of the incoming message.For our simple subscription service demo, our message handler needs to look atthe body of the message to determine whether it contains the word START orSTOP. Depending on the word, we will emit an XML document which will producedifferent messages.python title=main.pyfrom flask import Flask, request, Responsefrom twilio.twiml.messaging_response import MessagingResponseapp = Flask(__name__)@app.route(/, methods=[GET, POST])def message_handler(): This endpoint will be queried by SignalWire whenever an incoming SMS is received. We respond with an XML document which specifies the next instructions. print(request.values) body = request.values.get(Body) if not body: return Invalid parameters. response = MessagingResponse() if START in body.upper(): response.message(Subscription started!) elif STOP in body.upper(): response.message(Subscription stopped.) else: response.message(Message unrecognized. Please text START or STOP.) return Response(response.to_xml(), mimetype=text/xml)php title=index.phprequire_once vendor/autoload.php;use \SignalWire\LaML\MessageResponse;# This endpoint will be queried by SignalWire whenever an incoming SMS is received.# We respond with an XML document which specifies the next instructions.$body = $_REQUEST[Body] ?? ;if (empty($body)) { echo Invalid parameters.; exit();}$response = new MessageResponse;if (str_contains(strtoupper($body), START)) { $response->message(Subscription started!);} else if (str_contains(strtoupper($body), STOP)) { $response->message(Subscription stopped.);} else { $response->message(Message unrecognized. Please text START or STOP.);}header(Content-type: text/xml);echo $response->asXML();javascript title=index.jsimport express from express;import { RestClient } from @signalwire/compatibility-api;const app = express();app.use(express.urlencoded({ extended: true }));/** * @param {express.Request} req * @param {express.Response} res */function messageHandler(req, res) { // This endpoint will be queried by SignalWire whenever an incoming SMS is received. // We respond with an XML document which specifies the next instructions. /** @type string */ const body = req.body?.[Body] ?? req.query?.[Body]; if (!body) { res.send(Invalid parameters.); return; } const response = new RestClient.LaML.MessagingResponse(); if (body.toUpperCase().includes(START)) { response.message(Subscription started!); } else if (body.toUpperCase().includes(STOP)) { response.message(Subscription stopped.); } else { response.message(Message unrecognized. Please text START or STOP.); } res.set(Content-Type, text/xml); res.send(response.toString());}app.get(/, messageHandler);app.post(/, messageHandler);app.listen(8080);This simple message handler works like a dynamic XML bin, whose content dependson the received message.Try running the application, which will listen on port 8080:bashpython3 -m flask --app main.py run --host=0.0.0.0 --port 8080bashdocker run --rm -it -p 8080:80 -v $PWD:/var/www/html php:8.1-apachebashnode index.jsSince you are likely behind a NAT, to test this application on your localmachine you need a public IP address that SignalWire can reach. We suggest using[ngrok](https://ngrok.com/): refer to our [guide onngrok](guides/administration/guides/technical-troubleshooting/how-to-test-webhooks-with-ngrok/index.mdx)for more information.In short, while the application is up and listening on port 8080, run ngrok from a new terminal like this:bashngrok http 8080Youll get a public random URL (such as https://983f-93-41-16-193.ngrok.io/)that you can use to access your local application.### Configuring the numberNow that the code is ready and the HTTP endpoint is reachable from the web, weneed to configure our SignalWire number to access it.If you dont have a phonenumber yet, make sure to [buyone](guides/numbers-api/getting-started/buying-a-phone-number/index.mdx). Youwill need at least one number to receive messages.Then, open the settings for the number. Under Messaging Settings, choose tohandle messages using LaML Webhooks, then paste the public ngrok URL whichconnects to your application. Connecting a number to your XML endpoint. First select LaML Webhooks, then paste the URL of the bin. Try sending a message to the configured phone number: after a few seconds youllreceive an automated reply, whose content will be different depending on whatyou wrote.:::info Ensuring message deliveryIf you are sending messages to the US from a 10DLC number, you _must_ registeryour traffic with the Campaign Registry. Otherwise, the carriers will notdeliver your messages. Please see [**Campaign Registry - Everything You Need ToKnow**](pathname:///guides/campaign-registry-all-you-need-to-know) for more information.:::## ConclusionWe have shown how to handle incoming messages from code, by emitting XMLdocuments whose content depends on the incoming message. We did all this in thecontext of the [Compatibility API](pathname:///compatibility-api).For more advanced, real-time applications, youll want to check outour [Realtime SDK](sdks/reference/realtime-sdk/00-realtime-sdk-reference.mdx). Find more detailsin the guide about [Sending and Receiving SMS with the Realtime SDK](guides/messaging-api/guides/realtime-api/first-steps-with-messaging.mdx).