Skip to content

Instantly share code, notes, and snippets.

@kieranklaassen
Created December 5, 2022 14:07
Show Gist options
  • Save kieranklaassen/40aaa3aecc8ecf37f7a788d0b18a85b1 to your computer and use it in GitHub Desktop.
Save kieranklaassen/40aaa3aecc8ecf37f7a788d0b18a85b1 to your computer and use it in GitHub Desktop.
Unofficial ChatGPT API Wrapper Ruby
# The ChatGptService class provides an easy way to integrate with the OpenAI ChatGPT API.
# It allows you to send and receive messages in a conversation thread, and reset the thread
# if necessary.
#
# Example usage:
# chat_gpt_service = ChatGptService.new(BEARER_TOKEN)
# response = chat_gpt_service.chat("Hello, how are you?")
# puts response
# # => {"message"=>
# # {"id"=>"8e78691a-1fde-4bd5-ad68-46b23ea65d8f",
# # "role"=>"assistant",
# # "user"=>nil,
# # "create_time"=>nil,
# # "update_time"=>nil,
# # "content"=>
# # {"content_type"=>"text",
# # "parts"=>
# # ["Hello! How can I help you today? Is there something on your mind that you would like to talk about or ask about? I'm here to assist you with any questions you may have, so feel free to ask away."]},
# # "end_turn"=>nil,
# # "weight"=>1.0,
# # "metadata"=>{},
# # "recipient"=>"all"},
# # "conversation_id"=>"edbf3a3b-7d3f-4bed-a437-a09d69a93c9c",
# # "error"=>nil}
#
# # reset the conversation thread
# chat_gpt_service.reset_thread
#
require "json"
require "net/https"
require "securerandom"
class ChatGptService
attr_reader :conversation_id
def initialize(bearer_token)
@bearer_token = bearer_token
@conversation_id = nil
end
def chat(message)
payload = {
action: "next",
messages: [
{
id: SecureRandom.uuid,
role: "user",
content: {content_type: "text", parts: [message]}
}
],
parent_message_id: @parent_message_id || SecureRandom.uuid,
model: "text-davinci-002-render"
}
payload[:conversation_id] = conversation_id if conversation_id
response = post(
"https://chat.openai.com/backend-api/conversation",
payload,
@bearer_token
)
response = JSON.parse(response.compact.last(2).first)
@parent_message_id = response.dig("message", "id")
@conversation_id = response.dig("conversation_id")
response
end
def reset_thread
@conversation_id = nil
end
private
def post(url, data, bearer_token)
uri = URI(url)
https = Net::HTTP.new(uri.host, uri.port)
https.use_ssl = true
request = Net::HTTP::Post.new(uri.path, "Content-Type" => "application/json")
request["Authorization"] = "Bearer #{bearer_token}"
request.body = data.to_json
response = https.request(request)
response.body
response.body.lines.map { |line| line[sse_substring..] }.compact
end
def sse_substring
"data: ".length
end
end
@kieranklaassen
Copy link
Author

That looks nice! I guess they are more strict with their required headers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment