Sample ChatGPT plugin in Ruby
April 7, 2023 ยท View on GitHub
This Ruby/Sinatra app is a ChatGPT plugin that provides a random number.
Example usage





Run locally and test on ChatGPT
To start up the application and bind to port 9292:
bundle
rerun rackup
You will need to expose the application to the internet. I use https://ngrok.com/.
ngrok http --region=au 9292
The output shows you your domain
Session Status online
Region Australia (au)
Forwarding https://e92baeb18b8a.ngrok.app -> http://localhost:9292
The domain e92baeb18b8a.ngrok.app will be passed to ChatGPT when we register the plugin.
Register plugin with ChatGPT
Open https://chat.openai.com/chat, and switch to the ChatGPT "Plugins" model.

Next, under the Plugins dropdown, select "Plugin Store".

At the bottom of the modal, click on "Develop your own plugin".
Click the green "My manifest is ready" button.
Copy your ngrok domain e92baeb18b8a.ngrok.app into the form, and click the green "Find manifest file" button.
ChatGPT will validate the two manifest files. Click the green Next button.

Next, click Install for me, then Continue, then Install plugin.
Testing the plugin
Try the prompts:
- Generate two random numbers
- Add three random numbers together and say the answer in English
- Create a rectangular prism with random sides, each between 10 and 30 cm in length
- Or the other examples above

Implementation
The Sinatra app provides a POST /random endpoint that returns {random_number: 35} or similar.
export DOMAIN=e92baeb18b8a.ngrok.app
curl "https://$DOMAIN/random" -d '{}'
You can also pass min or max to override the defaults of 0 and 100 respectively.
$ curl "https://$DOMAIN/random" -d '{"min":10,"max":20}'
{"random_number":15}
But ChatGPT Plugins doesn't know the details of this API until we tell it. When you register ChatGPT it fetches two files from our plugin.
The high-level plugin definition:
curl "https://$DOMAIN/.well-known/ai-plugin.json"
And the description of our POST /random endpoint:
curl "https://$DOMAIN/.well-known/openapi.yaml"
The source files are within this repo's .well-known folder, but our app.rb sinatra script loads them, replaces DOMAIN with our $DOMAIN ngrok domain, and returns the modified file.
Writing your own openapi.yaml file
I actually asked GPT-4 to write my file:
Create an openapi.yaml for a service that has a POST /random endpoint that returns single integer which is a random number
Through debugging, I needed to manually change the result a little bit to add operationId: query_query_post to my /random paths entry.
And then I asked GPT-4 to write the initial Sinatra app:
Create a ruby sinatra app.rb that implements this endpoint
And I was half way there. Good times.