Schedules in Zoho CRM: quando usare una funzione Deluge a orario
Gli Schedules in Zoho CRM servono quando una funzione Deluge deve girare a un orario fisso o in modo ricorrente, senza che alcun record venga modificato. Sono i casi "ogni notte", "ogni ora" oppure "ogni lunedì". Se invece l'azione deve partire quando un record cambia, lo strumento giusto è una regola workflow.
Uno Schedule è un'azione automatica definita dall'utente, eseguita tramite una funzione a un momento preciso oppure su base ricorrente. La definizione è quella della documentazione di Zoho. Una funzione, in Zoho CRM, è logica scritta dall'utente in Deluge o in Java per eseguire azioni personalizzate. Deluge è il linguaggio che si scrive nel Deluge Script Editor di Zoho.
Una funzione non parte mai da sola. La documentazione sviluppatori precisa che va associata a un trigger, cioè all'evento che dice a Zoho CRM quando eseguirla. Nel caso di uno Schedule il trigger è l'orologio: data, ora e frequenza.
Questo post fa parte di una serie di tre sull'automazione di Zoho CRM con il codice:
- il client script, che lavora nella pagina mentre l'utente compila un record;
- la funzione Deluge collegata a una regola workflow, che parte quando un record cambia;
- lo Schedule, trattato qui, che parte a un orario senza evento sul record.
Prima di tutte e tre viene sempre l'opzione senza codice. Una regola di convalida, un aggiornamento di campo o un'attività creata da un workflow risolvono molti casi senza alcuna manutenzione del codice.
Senza codice, client script, workflow o Schedule: la tabella di scelta
La scelta tra le opzioni di automazione di Zoho CRM dipende da quando deve scattare l'azione. La tabella confronta le cinque strade più comuni per momento di esecuzione, necessità di codice e tempo massimo concesso alla funzione. I tempi massimi vengono dalla pagina Platform Limits and Quotas delle funzioni di Zoho CRM.
| Opzione | Quando scatta | Codice | Tempo massimo della funzione |
|---|---|---|---|
| Regola di convalida, aggiornamento di campo o attività da workflow | Al salvataggio o alla modifica del record | No | Non applicabile |
| Regola workflow basata su una data | A una data calcolata da un campo del record | No | Non applicabile |
| Client script | Nella pagina, mentre l'utente lavora | Sì | Non applicabile |
| Funzione su regola workflow | Quando un record cambia, in modo asincrono | Sì | 30 secondi |
| Funzione su Schedule | A un orario o con ricorrenza, senza evento sul record | Sì | 15 minuti |
La differenza di tempo pesa nella scelta. Una funzione di workflow deve chiudersi in 30 secondi ed elabora di solito un solo record. Una funzione su Schedule ha fino a 15 minuti e può leggere e aggiornare molti record in un'unica esecuzione.
Per le funzioni di workflow vale un altro dettaglio della documentazione. Il record viene salvato subito, senza attendere la fine della funzione. Nessuna delle due funzioni blocca quindi l'utente che lavora.
Quando basta una regola workflow senza codice e quando serve uno Schedule
Un'attività singola per ogni trattativa, 14 giorni dopo l'ultima attività, si costruisce senza codice. Basta una regola workflow basata su una data, impostata sul campo Last Activity Time, con un'azione di tipo attività. Le regole workflow sono insiemi di azioni, come notifiche email, attività e aggiornamenti di campo, eseguite quando si verificano condizioni specificate.
Questa soluzione va preferita quando è sufficiente. Non richiede crediti di esecuzione per le funzioni, non ha codice da mantenere e qualunque amministratore la legge in pochi secondi.
Uno Schedule si guadagna il suo posto quando la logica supera ciò che un workflow sul singolo record sa fare. I casi tipici sono questi:
- un'unica esecuzione che scorre molti record insieme, invece di un evento per ogni record;
- una logica legata al calendario, per esempio agire solo nei giorni feriali;
- un controllo per evitare attività doppie quando la prima è ancora aperta;
- calcoli che confrontano o sommano più record tra loro;
- una sincronizzazione periodica con altri sistemi.
L'help centre di Zoho cita proprio l'integrazione come uso previsto degli Schedules. Si possono collegare i dati del CRM al sito o all'intranet aziendale, ad applicazioni di terze parti o ad altre app Zoho. L'esempio di questo post combina tre dei casi elencati: giorni feriali, molti record in una sola esecuzione e nessun doppione.
Edizioni, permessi e limiti degli Schedules in Zoho CRM
Gli Schedules richiedono un'edizione di Zoho CRM con accesso completo alle funzioni. Secondo la documentazione sviluppatori, le funzioni sono disponibili con pieno accesso su Enterprise, CRM Plus, Ultimate e Zoho One. Su Standard e Professional sono accessibili solo tramite Extensions.
Servono inoltre due permessi di profilo. Il permesso Manage Workflow consente di configurare gli Schedules. Il permesso Manage Extensibility, tra i Developer Permissions, consente di creare e gestire le funzioni.
I limiti principali degli Schedules in Zoho CRM sono questi:
- al massimo 10 Schedules per organizzazione;
- nomi univoci, perché un nome non può essere duplicato;
- data di inizio entro un anno dalla data corrente;
- al massimo 200.000 righe eseguite per esecuzione;
- esecuzione manuale con Run Now consentita solo due volte al giorno.
Su due punti le pagine di Zoho non coincidono. Per il numero di Schedules, la pagina sviluppatori parla di 10 Schedules attivi. L'help centre di Zoho CRM sugli Schedules conta invece 10 Schedules "attivi o inattivi". Conviene quindi trattare anche quelli disattivati come posti occupati.
Sul tempo di esecuzione, la pagina sviluppatori Custom Schedules indica 5 minuti. L'help centre, la pagina Triggers and Associations e la pagina Limits and Quotas indicano 15 minuti. La documentazione sviluppatori sui limiti afferma: "Functions that exceed their category's timeout are forcefully terminated". Progettare la funzione perché finisca ben sotto i 5 minuti evita il problema.
Le righe eseguite non sono le righe del sorgente. Zoho conta le righe che il runtime esegue davvero, compresi cicli, rami condizionali e funzioni figlie chiamate.
Crediti, chiamate API e paginazione: perché un ciclo moltiplica i costi
Ogni esecuzione di una funzione Deluge consuma un credito dal saldo giornaliero dell'edizione. Per Enterprise e Zoho One il saldo è di 20.000 crediti gratuiti più 500 per ogni licenza utente, più eventuali crediti aggiuntivi. Il massimo è 400.000. I crediti si ricaricano su una finestra mobile di 24 ore.
Le chiamate interne alla funzione hanno un costo separato. Ogni esecuzione di invokeurl che riceve risposta viene scalata dal limite di chiamate esterne del servizio. La documentazione Deluge fa l'esempio diretto: un invokeurl dentro un ciclo che gira cinque volte consuma cinque chiamate. A livello di organizzazione il tetto è di 5.000.000 di richieste al giorno.
COQL, cioè CRM Object Query Language, permette di scrivere query simili a SQL per leggere record di Zoho CRM con i nomi API di moduli e campi. La sintassi della paginazione è LIMIT offset, limit: prima il numero di record da saltare, poi quanti leggerne. Il valore predefinito è 200 e il massimo è 2.000.
Il costo in crediti API di una query COQL dipende dal LIMIT:
- da 1 a 200 record: 1 credito API;
- da 201 a 1.000 record: 2 crediti API;
- da 1.001 a 2.000 record: 3 crediti API.
Anche qui le pagine divergono. La pagina Get Records through COQL Query indica al massimo 200 record e 50 campi per chiamata. La panoramica COQL parla di 2.000 record con LIMIT 0, 2000. Pagine da 200 record rispettano entrambe le indicazioni e costano un credito ciascuna.
La risposta riporta more_records quando esistono altre pagine. Una chiamata che attende più di 40 secondi fallisce con un "socket timeout error".
Esempio pratico: un'attività per ogni trattativa ferma da 14 giorni nei giorni feriali
L'esempio di questo post crea, ogni mattina feriale, un'attività per il proprietario di ogni trattativa aperta non modificata da 14 giorni. Non crea mai una seconda attività finché la prima è ancora aperta. Una trattativa è "ferma" quando il suo campo Modified_Time è più vecchio di 14 giorni e la fase non è chiusa.
La funzione segue il principio "prima leggere tutto, poi agire". Le letture avvengono tutte prima di qualunque scrittura. Così una query non vede mai i record appena creati dalla stessa esecuzione e il conteggio finale resta coerente.
La funzione lavora in tre passaggi:
- legge con una query COQL le attività aperte create da questo job, riconoscibili dal prefisso nell'oggetto, e annota le trattative collegate;
- legge le trattative aperte più vecchie della soglia, a pagine da 200 record, fermandosi quando
more_recordsvale false; - crea un'attività, con scadenza oggi, solo per le trattative che non ne hanno già una aperta.
Il controllo del giorno della settimana avviene nel codice. Lo Schedule gira quindi tutti i giorni alle 08:00, e il sabato e la domenica la funzione esce senza fare nulla. Questa scelta evita di dipendere dalle opzioni di frequenza del menu, che le pagine di Zoho descrivono in modo diverso.
Il collegamento tra attività e trattativa usa il campo What_Id. La documentazione COQL precisa che il supporto di What_Id vale solo per Tasks, Calls ed Events. Per questo il controllo dei doppioni parte proprio dal modulo Tasks.
Le query passano da una connessione. Una connessione è l'autorizzazione OAuth salvata in Zoho che la funzione richiama per nome nel parametro connection di invokeurl.
Il codice completo della funzione Deluge per le trattative ferme
La funzione seguente implementa i tre passaggi dell'esempio. Va incollata nell'editor delle funzioni di Zoho CRM, creando una funzione della categoria Schedule. Le query lunghe sono spezzate su più righe con variabili intermedie, senza cambiare il testo inviato a COQL.
void schedule.stale_deals_nudge()
{
apiDomain = "https://www.zohoapis.eu"; // dominio API del Suo data centre
crmConn = "crm_coql"; // nome del link della connessione
staleDays = 14;
orgTimeZone = "Europe/Berlin"; // il Suo fuso orario, nome del TZ database
closedStages = "'Closed Won','Closed Lost'";
taskPrefix = "Trattativa ferma: ";
// weekday(): 1 = domenica ... 7 = sabato
dayNo = today.weekday();
if(dayNo != 1 && dayNo != 7)
{
cutoff = now.subDay(staleDays).toString("yyyy-MM-dd'T'HH:mm:ssXXX",orgTimeZone);
headers = Map();
headers.put("Content-Type","application/json");
// 1) trattative che hanno gia un'attivita aperta creata da questo job
openTaskDeals = Map();
tBody = Map();
tq = "select What_Id from Tasks where (Subject like '" + taskPrefix + "%'";
tq = tq + " and Status != 'Completed') limit 0, 2000";
tBody.put("select_query",tq);
tResp = invokeurl
[
url :apiDomain + "/crm/v8/coql"
type :POST
body :tBody.toString()
headers :headers
connection :crmConn
];
tRows = tResp.get("data");
if(tRows != null)
{
for each t in tRows
{
if(t.get("What_Id") != null)
{
openTaskDeals.put(t.get("What_Id").get("id").toString(),true);
}
}
}
// 2) leggere prima tutte le trattative ferme e aperte, poi agire
stale = List();
offsets = {0,200,400,600,800};
for each off in offsets
{
q = "select id, Deal_Name, Stage, Owner, Modified_Time from Deals";
q = q + " where ((Stage not in (" + closedStages + "))";
q = q + " and (Modified_Time < '" + cutoff + "'))";
q = q + " order by Modified_Time asc limit " + off + ", 200";
qBody = Map();
qBody.put("select_query",q);
resp = invokeurl
[
url :apiDomain + "/crm/v8/coql"
type :POST
body :qBody.toString()
headers :headers
connection :crmConn
];
rows = resp.get("data");
if(rows == null || rows.size() == 0)
{
break;
}
stale.addAll(rows);
if(resp.get("info").get("more_records") == false)
{
break;
}
}
// 3) un'attivita al proprietario di ogni trattativa ferma che non ne ha ancora una
created = 0;
for each d in stale
{
dealId = d.get("id").toString();
if(!openTaskDeals.containKey(dealId))
{
task = Map();
task.put("Subject",taskPrefix + d.get("Deal_Name"));
task.put("Owner",d.get("Owner").get("id"));
task.put("Due_Date",today.toString("yyyy-MM-dd"));
task.put("What_Id",dealId);
task.put("$se_module","Deals");
info zoho.crm.createRecord("Tasks",task);
created = created + 1;
}
}
info "ferme: " + stale.size() + ", attivita create: " + created;
}
}
Le prime righe contengono tutte le impostazioni da adattare. apiDomain è il dominio del data centre europeo: un'organizzazione su un altro data centre usa il proprio dominio. crmConn deve coincidere con il nome del link della Sua connessione. staleDays fissa la soglia in giorni e orgTimeZone il fuso orario del calcolo.
I nomi API dei campi e i valori delle fasi sono esempi. Deal_Name, Stage, Owner, Modified_Time, lo stato Completed e le fasi Closed Won e Closed Lost vanno verificati nella Sua organizzazione, sotto Setup. La clausola not in accetta al massimo 100 valori.
La lista offsets limita la lettura a cinque pagine, cioè 1.000 trattative per esecuzione. Ogni esecuzione usa al massimo sei chiamate invokeurl. In crediti API sono 3 per la query sulle attività e 1 per ogni pagina di trattative.
Configurare lo Schedule passo per passo in Setup, Automation, Schedules
La configurazione di uno Schedule in Zoho CRM richiede cinque passaggi, da eseguire in quest'ordine. I menu sono indicati con le etichette inglesi, come appaiono in Setup.
- Connessione. Crei una connessione OAuth di Zoho con lo scope di lettura COQL e ne annoti il nome del link. La documentazione COQL avverte che senza lo scope ZohoCRM.settings.fields.READ la lettura dei metadati dei campi restituisce OAUTH_SCOPE_MISMATCH.
- Funzione. Crei la funzione nella categoria Schedule. La categoria conta: una funzione di tipo Automation si associa a workflow, Blueprint e approvazioni, ma non agli Schedules.
- Primo test. Commenti la riga
info zoho.crm.createRecord("Tasks",task);e lanci la funzione. Il messaggio finale mostra quante trattative ferme sono state trovate, senza creare nulla. - Schedule. In Setup, Automation, Schedules scelga Create your First Schedule, associ la funzione e imposti data di inizio, ora 08:00, frequenza giornaliera e fine.
- Sorveglianza. Nei primi giorni controlli la scheda Failure dello Schedule e il consumo di crediti.
Sulla frequenza le pagine di Zoho differiscono. La pagina sviluppatori Custom Schedules elenca Once, Daily, Weekly, Monthly e Yearly. La pagina Triggers and Associations cita invece hourly, daily, weekly, monthly e intervalli personalizzati. Verifichi quindi le voci presenti nel menu della Sua organizzazione.
Il pulsante Run Now è disponibile solo due volte al giorno per Schedule. Conviene perciò eseguire i test dall'editor della funzione e riservare Run Now alla verifica finale.
Gestire gli errori: scheda Failure, rerun e attività duplicate
Le esecuzioni fallite di uno Schedule compaiono nella scheda Failure della pagina di configurazione degli Schedules. Compaiono anche nella scheda Failures della pagina Functions. Secondo la documentazione Zoho su Function Failure e Rerun, le funzioni fallite restano elencate al massimo 30 giorni.
Le cause indicate da Zoho sono cinque:
- errori nel codice della funzione;
- parametri errati passati alla funzione;
- problemi del server, come "Internal Server Error";
- tempo di esecuzione eccessivo;
- errori di un'API di terze parti.
Il rerun, cioè la riesecuzione di una funzione fallita, va usato con cautela. Riesegue la funzione con i valori vecchi, quelli presenti nei record al momento della prima esecuzione. Se nel frattempo un'altra automazione ha modificato i record, Zoho avverte che possono nascere azioni duplicate.
La documentazione dà un'indicazione precisa per le funzioni fallite più volte. Prima si corregge il codice, poi si riesegue solo l'ultimo errore. Rieseguire tutti gli altri può generare dati duplicati.
In Svennis lanciamo sempre il primo test con la riga createRecord commentata e, dopo un errore, correggiamo il codice e rieseguiamo solo l'ultima esecuzione fallita. Il rerun di massa è la causa di attività doppie che vediamo più spesso presso i clienti.
Ogni rerun consuma una chiamata dell'edizione, e se ne possono selezionare al massimo 100 alla volta. Un errore nel codice o nell'API esterna continua a fallire finché non viene risolto.
Cosa significa per un'azienda italiana: fuso orario, data centre, festività ed edizione
Per un'azienda italiana, uno Schedule a orario richiede quattro verifiche prima della messa in produzione.
Fuso orario. La variabile orgTimeZone accetta un nome del TZ database. Per l'Italia il valore è Europe/Rome. Il calcolo della soglia di 14 giorni usa questo fuso, quindi un valore errato sposta il confine di qualche ora.
Data centre. Il dominio https://www.zohoapis.eu vale per le organizzazioni ospitate sul data centre europeo. Verifichi in quale data centre si trova la Sua organizzazione e usi il dominio corrispondente.
Festività. Il codice salta solo sabato e domenica. Le festività nazionali e le chiusure aziendali non sono gestite: in quei giorni i commerciali troveranno comunque nuove attività. Se serve, aggiunga una lista di date da escludere.
Edizione. Su Standard e Professional le funzioni sono accessibili solo tramite Extensions. Chi valuta un passaggio di edizione può confrontare le opzioni nella pagina su Zoho CRM Plus in Italia, una delle edizioni con accesso completo alle funzioni.
Lo stesso schema, prima leggere e poi agire, si applica alle sincronizzazioni notturne con il gestionale. È il caso tipico di un'integrazione tra SAP Business One e Zoho CRM, dove un'esecuzione pianificata allinea molti record in una volta.
Prossimi passi per mettere in produzione il primo Schedule in Zoho CRM
Il primo Schedule in Zoho CRM va in produzione in sicurezza seguendo una breve lista di controllo. Ogni punto riprende un limite o un rischio descritto in questa guida.
- Verifichi che un workflow senza codice non basti già al Suo caso.
- Controlli edizione e permessi: Manage Workflow e Manage Extensibility.
- Conti gli Schedules esistenti, attivi e inattivi, rispetto al limite di 10.
- Adatti dominio, connessione, fuso orario, nomi dei campi e fasi chiuse.
- Esegua il test con la riga createRecord commentata e legga il messaggio finale.
- Attivi lo Schedule alle 08:00 con frequenza giornaliera.
- Per una settimana controlli ogni mattina la scheda Failure e il consumo di crediti.
Se la funzione deve reagire alla modifica di un record anziché a un orario, il riferimento è la guida sulla funzione Deluge in una regola workflow. Se invece l'automazione rientra in un progetto più ampio, la pagina sull'implementazione di Zoho CRM descrive come impostare configurazione, automazioni e integrazioni fin dall'inizio.
Fonti
- Zoho CRM Developer: Custom Schedules
- Zoho CRM Help: Schedules
- Zoho CRM Developer: Functions, Triggers and Associations
- Zoho CRM Developer: Functions, Platform Limits and Quotas
- Zoho CRM Developer: Function Failure and Rerun
- Zoho Deluge: invokeURL task for API calls
- Zoho CRM API V8: Query (COQL) Overview
- Zoho CRM API V8: Get Records through COQL Query



