Integrate Zoho Creator with ChatGPT Using Deluge Script

Integrating Zoho Creator with ChatGPT Using Deluge Script

This script wires an OpenAI chat model directly into a Zoho Creator form. The user types a prompt into a text field, Deluge calls the OpenAI API with invokeurl, and the generated text lands in an output field on the same record — no middleware, no external automation tool.

It handles three triggers: generate from a fresh prompt, refine an existing output with a follow-up instruction, and reset the form state.

Updated for the current OpenAI API. The original 2023 version of this script used the /v1/edits endpoint with the text-davinci-edit-001 model for the refine step. OpenAI retired both, so that branch has been rewritten to use /v1/chat/completions with a system instruction, which produces the same behaviour on a supported endpoint. The original also compared with a single = in two conditions, which assigns rather than compares in Deluge; that is corrected below.

Before you start

  • An OpenAI API key and, if your account uses one, an organization ID.
  • Three fields on the form: Text_Input (single line or multi line), Chat_Output (multi line), and Refine_Input (decision box).
  • Store the key in a Creator variable or a connection rather than pasting it inline — the sample below references YOUR_API_KEY and YOUR_ORG_ID as placeholders.

Deluge script

// ============================================
// ZOHO CREATOR -> OPENAI CHAT COMPLETIONS
// Trigger: On user input of the Text_Input field
// ============================================

// --- Trigger 1: new prompt, no existing output -> generate ---
if(input.Text_Input != "" && input.Refine_Input == false && input.Chat_Output == "")
{
headers = Map();
headers.put("Content-Type","application/json");
headers.put("Authorization","Bearer " + YOUR_API_KEY);
headers.put("OpenAI-Organization", YOUR_ORG_ID);

messages = List();
userMsg = Map();
userMsg.put("role","user");
userMsg.put("content",input.Text_Input);
messages.add(userMsg);

data = Map();
data.put("model","gpt-4o-mini");
data.put("messages",messages);

response = invokeurl
[
url : "https://api.openai.com/v1/chat/completions"
type : POST
parameters : data.toString()
headers: headers
];

choices = response.getJSON("choices");
if(choices != null && choices.size() > 0)
{
message = choices.get(0).getJSON("message");
input.Chat_Output = message.getJSON("content");
}
else
{
info "OpenAI error: " + response.toString();
}
}
// --- Trigger 2: existing output + new instruction -> refine ---
else if(input.Text_Input != "" && input.Chat_Output != null && input.Chat_Output != "")
{
headers2 = Map();
headers2.put("Content-Type","application/json");
headers2.put("Authorization","Bearer " + YOUR_API_KEY);
headers2.put("OpenAI-Organization", YOUR_ORG_ID);

sysMsg = Map();
sysMsg.put("role","system");
sysMsg.put("content","Rewrite the user's text according to their instruction. Return only the rewritten text.");

priorMsg = Map();
priorMsg.put("role","user");
priorMsg.put("content","TEXT:\n" + input.Chat_Output + "\n\nINSTRUCTION:\n" + input.Text_Input);

messages2 = List();
messages2.add(sysMsg);
messages2.add(priorMsg);

data2 = Map();
data2.put("model","gpt-4o-mini");
data2.put("messages",messages2);

response2 = invokeurl
[
url : "https://api.openai.com/v1/chat/completions"
type : POST
parameters : data2.toString()
headers: headers2
];

choices2 = response2.getJSON("choices");
if(choices2 != null && choices2.size() > 0)
{
message2 = choices2.get(0).getJSON("message");
input.Chat_Output = message2.getJSON("content");
}
}

// --- Trigger 3: On user input of the Refine_Input decision field ---
if(input.Refine_Input == true)
{
input.Text_Input = "";
input.Refine_Input = false;
}

Notes

  • Model name is a moving target. gpt-4o-mini is used here as a cost-effective default. Swap it for whichever model your account has access to; the request shape does not change.
  • Guard the response. The original script indexed straight into choices. If the API returns an error object instead, that throws. The version above checks the array first and logs the raw response with info so you can see what came back.
  • Rate limits and timeouts. Long prompts on a form-level trigger can exceed Creator’s script timeout. For heavy generation, move the call to a scheduled function or a standalone function invoked from a button.

Related: the same invokeurl pattern — build a Map, stringify it, pass an Authorization header — is how nearly every REST integration in this library works. Once this one runs, the rest are variations on it.

This script is part of the free Creator Scripts Deluge Library.

All 39 Deluge scripts, the full Zoho Creator course, and every downloadable asset are now free. Get free access →