Build a ChatGPT SMS bot with the OpenAI API and ASP.NET Core
Time to read: 7 minutes
ChatGPT is a powerful language model trained by OpenAI. ChatGPT is a state-of-the-art natural language processing tool that can help you create a chatbot that can provide accurate and helpful responses to user queries.
With its extensive knowledge base and advanced language processing capabilities, ChatGPT can assist you in developing a chatbot that delivers a seamless and engaging user experience. It's worth noting that this introduction was generated using ChatGPT itself, with some minor editing, showcasing the power and versatility of this language model.
In this tutorial, you'll learn how to integrate Twilio SMS, ASP.NET Core, and ChatGPT to to create a robust and intelligent chatbot that you can talk to using SMS. Let's get started!
Prerequisites
Here’s what you will need to follow along:
- .NET 7 SDK (earlier and newer versions may work too)
- A code editor or IDE (I recommend JetBrains Rider, Visual Studio, or VS Code with the C# plugin)
- A free OpenAI account
- A free Twilio account (sign up with Twilio for free)
- A Twilio phone number
- The ngrok CLI and, optionally, a free ngrok account
You can find the source code for this tutorial on GitHub. Use it if you run into any issues, or submit an issue if you run into problems.
Create and set up a Twilio SMS project
Open a shell of your choice and use the .NET CLI to create an empty web project named SmsChatGpt and change into the project directory, using these commands:
The Twilio .NET SDK lets you communicate with Twilio's APIs without having to manually write the HTTP code. Add the Twilio .NET SDK using the following command:
The Twilio helper library for ASP.NET Core helps you integrate Twilio into ASP.NET Core. Add the helper library for ASP.NET Core using the following command:
Open the project in your preferred .NET IDE and update the Program.cs file to match the following code:
Here's an overview of the changes:
- The application configures server sessions to store the session data in memory. These sessions will be used to store the chat messages.
- The Twilio API client is registered as a service in the ASP.NET Core Dependency Injection (DI) container. Now the
ITwilioRestClient
andTwilioRestClient
can be injected into constructors and methods supported by DI.
MapMessageEndpoint
is an extension method that doesn't exist yet. Create a new file named MessageEndpoint.cs and add the following code to it:
The MessageEndpoint.MapMessageEndpoint
extension method maps the /message endpoint for HTTP POST requests to the OnMessage
method.
The OnMessage
method reads the form data from the request and extracts data from the form. The From
parameter is the phone number that sent the message. The To
parameter is the phone number that received the message, which will be your Twilio phone number. The Body
parameter is the content of the message itself. The MessageResource.CreateAsync
method sends a message back to the sender, repeating what the sender said.
You'll need to configure the Twilio Account SID and Auth Token before you can communicate with the Twilio API using the Twilio REST client. Since the Auth Token is a secret that you should not share, you should avoid hard-coding it such as putting it in your appsettings.json file — or any other way that it could end up in your source control history. Instead, use the Secrets Manager aka user-secrets, environment variables, or a vault service.
Run the following commands to initialize user-secrets:
Then, grab the Account SID and Auth Token from the Account Info panel of the Twilio Console and configure them using the following command, replacing [YOUR_ACCOUNT_SID]
with your Account SID and [YOUR_AUTH_TOKEN]
with your Auth Token:
Now, run your application using the following command:
In the application's output, you'll see a line similar to Now listening on: http://localhost:5209
. Copy the URL and port, as you'll need it shortly.
Configure the message webhook on your Twilio phone number
Next, you'll need to configure the message webhook on your Twilio phone number. Before you can do that, you'll need to make your locally running application accessible to the internet. You can quickly do this using ngrok which creates a secure tunnel to the internet for you.
Leave your .NET application running, and run the following command in a separate shell, after replacing [YOUR_LOCALHOST_URL]
with the URL and port which you copied previously:
ngrok print the Forwarding URL to the output, which you'll need to publicly access your local application. Copy it, as you'll need it in just a moment.
Now, go back to the Twilio Console in your browser and use the left navigation to navigate to Phone Numbers > Manage > Active Numbers. Then, click the Twilio Phone Number you want to test with. On the phone number configuration page, locate "A MESSAGE COMES IN" in the Messaging section. Underneath that, set the first dropdown to Webhook. Set the value of the text box next to the dropdown to the ngrok Forwarding URL which you just copied, and add /message at the end of the URL. Then click Save.
Now, text your Twilio phone number something. You should receive an SMS back saying something like "You said: [whatever you said]".
Great job! You have an application that can receive SMS and send back SMS.
Integrate OpenAI's ChatGPT
OpenAI has official client libraries for their APIs, but they do not provide one for .NET. Luckily, there are some unofficial libraries developed by the .NET community, such as Betalgo.OpenAI, OpenAI, and OpenAI-DotNet.
You'll be using the Betalgo.OpenAI library in this tutorial. Swap back to the shell that is running your application and press ctrl + c
to stop it. Then, add the package for Betalgo.OpenAI using the following command:
Open Program.cs and add the following using
statement at the top of the file.
Then add the following line after builder.Services.AddTwilioClient()
:
This will add the IOpenAIService
to the DI container of ASP.NET Core.
You'll need an API key from OpenAI to communicate with their APIs. Using the OpenAI API is not free, but when you create an account OpenAPI will give you free credit to use. Open a browser and follow this link to the OpenAI API keys page. If you aren't logged in or signed up, it will prompt you to do so now. Once you're logged in, it'll take you to the API keys page.
Click on the Create new secret key button. As the prompt says, save your API key secret somewhere safe, as you won't have another chance to see it!
Use the following command to store the OpenAI API key as a user-secret, replacing [OPENAI_API_KEY]
with the API key you just created:
Next, update MessageEndpoint.cs with the following code:
The IOpenAIService
is injected into the openAiService
parameter of the OnMessage
method. User
is one of the optional parameters you can pass to the ChatGPT API.
While it is optional, it helps ChatGPT monitor and detect abuse, so I recommend passing it in. The only data you have access to that uniquely identifies the current use is their phone number. Since a phone number is Personally Identifiable Information (PII), I decided not to hand that to OpenAI, but instead to hash it first using the SHA256 hashing algorithm.
Next, the endpoint will pass the SMS body to the ChatGPT API and retrieve the response. The response is then sent back to the sender using Twilio.
Run your application again using the following command:
Then, ask ChatGPT anything by texting a question to your Twilio phone number.
I asked the SMS ChatGPT bot for a joke about dogs, and it delivered a great joke, however, when I asked it for a follow-up joke about cats, without explicitly mentioning a joke, it just gave me information about cats.
This is because ChatGPT does not maintain the context of the previous messages by default. Let's fix that first.
Persist ChatGPT's chat history as context
Since ChatGPT doesn't persist the history of the chat, it is not able to use the history as context to generate new responses. To solve this problem, you have to persist the history in your application, and pass the entire chat history to ChatGPT's API, for every new query.
In this tutorial, you'll store the history of the chat in ASP.NET Core's server session. Update the MessageEndpoint.cs like this:
Now the endpoint loads any previous chat messages from the session, and then adds it to the new SMS body. The whole conversation is passed to the ChatGPT API and the response is also added to the conversation, which is then persisted back into session.
Stop and start your application to try it out. Now, when I asked for a follow-up joke about cats, it knew I wanted a joke and not facts about cats.
Now that the ChatGPT bot has the context of the entire chat history, it is much more useful. However, users may still want to start from a fresh slate. Update the start of the OnMessage
method in the MessageEndpoint.cs file:
Now users can text "reset" and the chat history will be reset.
Maximize message delivery
You can only send messages using Twilio SMS that are shorter or equal to 1600 characters, but sometimes ChatGPT's response will exceed that limit. If so, you'd receive an error that would look something like this:
While Twilio will accept messages shorter than or equal to 1600 characters, Twilio recommend keeping your messages below or equal to 320 characters to maximize deliverability of your messages.
To ensure ChatGPT does this, update the OnMessage
method again:
Then add these two static functions to the MessageEndpoint
class:
The SplitTextIntoMessages
method will split the text into paragraphs and add the paragraphs while not exceeding the recommended 320-character limit. The method returns a list of strings, each containing 1 or more paragraphs. If a paragraph is larger than 320 characters, the individual string will exceed the 320-character limit. So it doesn't guarantee each string will be less than 320 characters, but in most cases it will be.
The SendResponse
method iterates over the list of strings and sends them out one by one with a one-second delay between each. Twilio cannot guarantee that the messages will arrive in the same order as they are created. However, by putting a one-second delay between each message the order is preserved most of the time. Alternatively, you could poll the message status and wait to send the next message until the current message is delivered.
Restart your application and try asking the bot a question that will have a long response. Here's a video that shows how the bot answers the question "How do I become a .NET developer?".
The video shows how the bot responds with multiple messages, with a delay between each message, but the messages are in the correct order.
Next steps
Fantastic job! You integrated OpenAI's APIs with Twilio SMS to create an SMS based ChatGPT bot.
Want to experiment more with OpenAI's APIs? Here's a tutorial on how to generate AI art with DALL·E 2 by texting a Twilio phone number.
We can't wait to see what you build. Let us know!
Niels Swimberghe is a Belgian American software engineer and technical content creator at Twilio. Get in touch with Niels on Twitter @RealSwimburger and follow Niels’ personal blog on .NET, Azure, and web development at swimburger.net.
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.