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.
Text_Input (single line or multi line), Chat_Output (multi line), and Refine_Input (decision box).YOUR_API_KEY and YOUR_ORG_ID as placeholders.// ============================================
// 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;
}
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.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.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 →