What?
A quick follow-on article to my previous article on Zoho Cliq: Integrate OpenAI and ChatGPT 3.5 Turbo.

Why?
Connecting to OpenAI ChatGPT is all very well and good, but this forgets what you were talking about after each chat. So it's good for 1 question and 1 answer. What we need is to train it a little a bit like the standard OpenAI Chat website does in terms of context.

How?
Just a few changes to the previous code of connecting to OpenAI ChatGPT but the exception here is that there needs to be code to loop through all the messages of the chat/conversation thread so that we send the OpenAI ChatGPT bot the full conversation thread.


First getting the messages relating to this chat:
You will need a connection that has the necessary scope(s). Note that you have to do this as the super admin to get organization level messages. But in ths example below, we're going to query a message to the ChatGPT bot:

// 
// initialize
m_Response = Map();
v_Message = message.trim();
v_ChatID = ifnull(chat.getJSON("id"),0);
//
// get conversations from last 10 minutes
v_MinutesAgo = 10;
v_FromTime = zoho.currenttime.subMinutes(v_MinutesAgo).toLong();
v_TillTime = zoho.currenttime.toLong() / 1000;
//
// by default gets last 100 messages (doesn't return anything if no parameters specified)
v_Endpoint = "https://cliq.zoho.eu/api/v2/chats/"+v_ChatID + "/messages?fromtime=" + v_FromTime + "&limit=50";
r_ChatDetails = invokeurl
[
	url: v_Endpoint
	type: GET
	connection: "ab_cliq"
];
//
// let's build up the conversation thread
l_Messages = List();
if(!isnull(r_ChatDetails.get("data")))
{
	for each r_MessageData in r_ChatDetails.get("data")
    {
		v_Role = "user";
		if(!isnull(r_MessageData.get("message_source")))
		{
			v_UserType = r_MessageData.get("message_source").get("type");
			v_Role = if(v_UserType=="bot", "assistant", "user");
		}
		if(!isnull(r_MessageData.get("content")))
		{
			v_Content = r_MessageData.get("content").get("text");
		}
		//
		m_Message = Map();
		m_Message.put("role",v_Role);
		m_Message.put("content",v_Content);
		l_Messages.add(m_Message);
    }
}
//
// if the message contains a question mark, send it to OpenAI
if(!isBlank(v_Message))
{
	v_Question = v_Message;
	//
	// Need to add openAI token
	v_Token = "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";
	//
	// build header of request
	m_Header = Map();
	m_Header.put("Authorization","Bearer " + v_Token);
	m_Header.put("Content-Type","application/json");
	//
	// build params of request
	m_Params = Map();
	m_Params.put("model","gpt-3.5-turbo");
	//
	// add latest message to conversation thread
	m_Message = Map();
	m_Message.put("role","user");
	m_Message.put("content",v_Question);
	l_Messages.add(m_Message);
	m_Params.put("messages",l_Messages);
	//
	// https://platform.openai.com/docs/api-reference/chat/create
	m_Params.put("temperature",0.8);
	m_Params.put("n",1);
	m_Params.put("max_tokens",256);
	m_Params.put("presence_penalty",0);
	m_Params.put("frequency_penalty",0);
	// 
	// send request to chatgpt openai
	r_ChatGPTResponse = invokeurl
	[
		url :"https://api.openai.com/v1/chat/completions"
		type :POST
		parameters:m_Params.toString()
		headers:m_Header
		detailed:true
	];
	if(r_ChatGPTResponse.get("responseCode") == 200)
	{
		//
		// retrieve the answer in text
		l_Choices = r_ChatGPTResponse.get("responseText").get("choices");
		for each  m_Choice in l_Choices
		{
			if(!isnull(m_Choice.get("message")))
			{
				if(m_Choice.get("message").get("role") == "assistant")
				{
					//
					// add the answer text to the response map
					m_Response.put("text",m_Choice.get("message").get("content"));
					//break;
				}
			}
		}
	}
	else if(r_ChatGPTResponse.get("responseCode") == 429)
	{
		// store in response text
		m_Response = {"text":"I dont have any knowledge on this. Consider doing a Google search."};
	}
}
return m_Response;