---title: Using Chat to Send SMS and Make Callsslug: /guides/using-chat-to-send-message-and-initiate-callssidebar_position: 1---In this guide, we will explore a simple IVR chat application that offers theuser an option to send an SMS message or make a voice call directly from thebrowser by making use of our Browser SDK and our RELAY Realtime Server SDK.The final application.## Required Resources- [Full source code repository](https://github.com/signalwire/guides/tree/main/Chat/Using%20chat%20to%20send%20messages%20and%20make%20voice%20calls)- [SignalWire Chat API](pathname:///rest/generate-a-new-chat-token)- [SignalWire Javascript Browser SDK](sdks/reference/browser-sdk/00-browser-sdk-reference.mdx)- [SignalWire RELAY Realtime SDK](sdks/reference/realtime-sdk/00-realtime-sdk-reference.mdx)The API also requires that you authenticate yourself using your Project ID, APIToken, and Space URL. If you do not know where to find these values, check outour guide to [Navigating your SignalWireSpace](guides/administration/guides/signalwire-space/navigating-your-space/index.mdx#api).## How to Run the ApplicationThe web chat application is built using [Express](https://expressjs.com).Express is a minimal and flexible Node.js web application framework thatprovides a robust set of features for web applications and mobile applications.To run this application, you must run the Express server locally with thefollowing steps:- Clone the project from the [repo](https://github.com/signalwire/guides/tree/main/Chat/Using%20chat%20to%20send%20messages%20and%20make%20voice%20calls).- Run npm install.- In the project folder there is a .env.example file which you can use to create your .env file and replace the content with necessary credentials like we mentioned in the prerequisite section.- Start the server from your terminal with node index.js (or nodemon index.js if you have [nodemon](https://www.npmjs.com/package/nodemon) installed).## Code WalkthroughThis Guide is divided into two sections: the **Frontend** and the **Backend**.The Frontend includes all of the UI-related sections and the Javascript block ofcode needed for the chat application to work. The Backend section includes thecode to generate the chat token and endpoints that the frontend will call toinitiate phone calls and send messages.### The FrontendUsing the SignalWire Javascript SDK, you can easily integrate chat features intoany web application. it only takes a few minutes to set up a basic example.:::info Please NoteThis project is built on the code from the _**[Simple Chat Demo](/guides/get-started-with-a-simple-chat-demo)**_.You should be familiar with the Chat features discussed in that guide before going through this guide.:::#### Import the SDKTo build your own chat application, you first need to include the SDK in your HTML.htmlThen you can interact with the SDK using the global variable SignalWire. Wellmainly be interested in the SignalWire.Chat.Client class for this guide, butif youd like to explore this API, feel free to browse the [SDKdocumentation](sdks/reference/browser-sdk/00-browser-sdk-reference.mdx).#### Getting a Chat TokenTokens are provided to the client by your own custom server. Your serverdetermines whether the user is actually authorized to access the chat and, ifthey are, asks SignalWire to emit a token. In the **Backend** section, we willsee how to write such a server. For now, we will get a token from our localbackend server with a POST request to the /get_chat_token endpoint which wewill create later.javascriptconst reply = await axios.post(/get_chat_token, { member_id: member, channel: channel,});const token = reply.data.token;The above endpoint takes member_id which is the name of the user joining thechat. The member_id is used to identify the user while using the chatapplication and is displayed on all Chat messages from the user. The channelparameter is to identify the Chat channel the user is joining so they can sendnew messages and see previous messages in the channel.#### Initialize the Chat IVROnce in the chat channel, the user can type start to initialize the IVR anddisplay a menu to send an SMS message or make a voice call.javascriptif (message.toLowerCase() === start) { await chatClient.publish({ channel: channel, content: message, }); const introMessage = Enter 1 to send an SMS message Enter 2 to make a Voice call ; await chatClient.publish({ channel: channel, content: introMessage, });}If the user types **1**, the following snippet prompts for the user input neededto send the message.javascriptif (message === 1) { await chatClient.publish({ channel: channel, content: message, }); selectionType = message; const messageSelection = \tYou selected Message\n Enter the from, to and content parameter using the below format\n (ex. +1aaabbbcccc,+1xxxyyyzzzz,Hello world) ; await chatClient.publish({ channel: channel, content: messageSelection, });}If the user types **2**, the following snippet prompts for the user input needed to initiate a phone call.javascriptif (message === 2) { selectionType = message; await chatClient.publish({ channel: channel, content: message, }); const voiceSelection = \tYou selected a voice call\n Enter the from, to, content parameter using the below format\n (ex. +1aaabbbcccc,+1xxxyyyzzzz, Welcome!) ; await chatClient.publish({ channel: channel, content: voiceSelection, });}:::caution Parameter InputThe data input value for each selection must be comma separated. For example,Messaging uses from,to,message while Voice uses from,to. In this demo, usingthe improper format will throw an error.:::To process the data being sent, this snippet of code checks the selection typeand then breaks the values into parameters to be passed to our server-side code.javascriptif (selectionType === 1) { let data = message.trim().split(,); let from = data[0].trim(); let to = data[1].trim(); let content = data[2].trim(); await chatClient.publish({ channel: channel, content: message, }); sendSWMessage(from, to, content, channel, chatClient);}A Voice selection works the same way in the snippet below. Note that we are alsopassing the chat channel and client to these functions so that we can send aconfirmation message to the user via the chat IVR.javascriptif (selectionType === 2) { let data = message.trim().split(,); let from = data[0].trim(); let to = data[1].trim(); let content = data[2].trim(); await chatClient.publish({ channel: channel, content: message, }); makeCall(from, to, content, channel, chatClient);}In the [full code](https://github.com/signalwire/guides/blob/main/Chat/Using%20chat%20to%20send%20messages%20and%20make%20voice%20calls/frontend/app.js), you will find the functions sendSWMessage and makeCall which take the necessary parameters to send a message and make a voice call and call the backend.### The BackendThe backend section consists of the endpoint needed to generate a chat token andthe two endpoints to make calls and send SMS messages using the [SignalWireRELAY Realtime SDK](sdks/reference/realtime-sdk/00-realtime-sdk-reference.mdx).#### Import the SDKFirst, we must import the necessary libraries and frameworks:- [Axios](https://www.npmjs.com/package/axios)- [Express](https://expressjs.com/)- [SignalWire RELAY Realtime SDK](sdks/reference/realtime-sdk/00-realtime-sdk-reference.mdx).javascriptrequire(dotenv).config();const auth = { username: process.env.PROJECT_ID, password: process.env.API_TOKEN,};const apiUrl = https://${process.env.SPACE_URL};const axios = require(axios);const express = require(express);const bodyParser = require(body-parser);const cors = require(cors);const { Voice, Messaging } = require(@signalwire/realtime-api);#### Chat Token EndpointBelow is a snippet used by our backend code to generate the Chat Token. For moreinformation on this endpoint, see our [technicalreference](pathname:///rest/generate-a-new-chat-token).javascriptapp.post(/get_chat_token, async function (req, res) { const { member_id, channel } = req.body; const channelsPerms = {}; channelsPerms[c] = { read: true, write: true }; const reply = await axios.post( apiUrl + /api/chat/tokens, { ttl: 50, channels: channelsPerms, member_id, state: {}, }, { auth } ); res.json({ token: reply.data.token, });});#### Voice Call EndpointThis second endpoint initiates a phone call using the dialPhone method fromthe Realtime API Voice Client. The users input is read over the voice callusing text-to-speech technology and then the call is ended using the hangupmethod. for more information on the Call object, see the [Voice technicalreference](sdks/reference/realtime-sdk/voice/voice-call.mdx).javascript// Endpoint to make the phone callapp.post(/make_call, async function (req, res) { try { const { from, to, content } = req.body; const call = await client.dialPhone({ from: from, to: to, content: content, }); let playback = await call.playTTS({ text: content }); await playback.ended(); await call.hangup(); return res.json({ data: Call initiated successfully }); } catch (exception) { console.log(exception); console.log(Call not answered); }});#### Messaging EndpointThe last endpoint sends a message using the send method from the Realtime APIMessaging Client. For more information on the Messaging client, you can visitthe [Messaging technicalreference](sdks/reference/realtime-sdk/messaging/messaging-client.mdx).javascript// Endpoint to send the messageapp.post(/send_message, async function (req, res) { try { const { from, to, content } = req.body; const message = await messageClient.send({ from: from, to: to, body: content, context: user, }); return res.json({ data: message }); } catch (e) { return res.json({ data: e.message }); }});## Wrap upWith this simple chat UI and three endpoints, we have built a simple IVR chatapplication that takes selections from users to either place a call or send anSMS message. The application of this demo is very flexible according to yourneeds. It could be incorporated into a portal to direct simple inquiries to themessage system and more complex inquiries to the voice system. You mighthard-code a recipient phone number so customers can send an SMS or voice call touse your service. The implementation is up to you, but the tools you need arelaid out for you here.