A quick article because I couldn't find anything that documented this with a working example.
Why?
The use-case here is that we want to make a ZohoCreator page display events for this month from ZohoProjects.
How?
The bit that stumped me was making a call to the Events endpoint as it would just come back with a blank response...
The reason it was blank was due to my parameters; the key item to remember is that status is a mandatory field and it can either be "closed" or "open". If you have used ZohoCRM then this is obvious; if you haven't then it may be difficult to work this out. Put simply, "Closed" are events in the past and "Open" are events in the future. The "is_open" in tasks is misleading and cannot be used in the request for events. There are hardly any parameters you can send to. Here's some code to get the last 50 events:
copyraw
//
// ***********************************
// get Zoho Projects information
v_BaseURL = "https://projectsapi.zoho.com";
v_Heading = "";
//
// get all portals
v_EndpointPortals = v_BaseURL + "/restapi/portals/";
r_Portals = invokeUrl
[
url: v_EndpointPortals
type: GET
connection: "my_projects_connection"
];
info r_Portals;
//
// once we check the JSON, we can select a portal name and ID, this avoids the need of using up an API request to get the portal
v_PortalName = "my_portal";
v_PortalID = "789456123";
//
// get all projects
v_EndpointProjects = v_BaseURL + "/restapi/portal/" + v_PortalID + "/projects/";
r_Projects = invokeUrl
[
url: v_EndpointProjects
type: GET
connection: "my_projects_connection"
];
//
// already decided as we only want one
v_ProjectName = "My Project Board";
v_ProjectID = "1234567000001234567";
//
// get all users (optional here)
v_EndpointUsers = v_BaseURL + "/restapi/portal/" + v_PortalID + "/projects/" + v_ProjectID + "/users/";
r_Users = invokeurl
[
url :v_EndpointUsers
type :GET
connection:"my_projects_connection"
];
//
// get all events
// NB: status=open are upcoming events; status=closed are events in the past; status is a mandatory field
// NB: range is an integer and the number of records to return (default=100; max=200)
// NB: index is an integer and is the offset or starting index (not the ID of the record)
m_Params = Map();
m_Params.put("range",50);
m_Params.put("status","closed");
v_EndpointEvents = v_BaseURL + "/restapi/portal/" + v_PortalID + "/projects/" + v_ProjectID + "/events/";
r_PastEvents = invokeurl
[
url :v_EndpointEvents
type :GET
parameters:m_Params
connection:"my_projects_connection"
];
l_PastEvents = ifnull(r_PastEvents.get("events"),List());
for each m_PastEvent in l_PastEvents
{
//
// convert a Zoho Project DateTime to a DateTime datatype (given 12/12/2023 12:00:00 PM... remove ambiguity: mm/dd or dd/mm?)
if(!isNull(m_PastEvent.get("scheduled_on")))
{
if(m_PastEvent.get("scheduled_on").contains(" "))
{
l_ThisDateTimeEventParts = m_PastEvent.get("scheduled_on").toList(" ");
if(l_ThisDateTimeEventParts.get(0).contains("/"))
{
l_ThisDateEventParts = l_ThisDateTimeEventParts.get(0).toList("/");
v_ThisDateEvent_Year = l_ThisDateEventParts.get(2);
v_ThisDateEvent_Month = l_ThisDateEventParts.get(1);
v_ThisDateEvent_Day = l_ThisDateEventParts.get(0);
l_ThisTimeEventParts = l_ThisDateTimeEventParts.get(1).toList(":");
v_ThisDateEvent_Minute = l_ThisTimeEventParts.get(1);
v_ThisDateEvent_Hour = l_ThisTimeEventParts.get(0);
//
// convert 12-hour to 24-hour
v_ThisDateEvent_Hour = if(l_ThisDateTimeEventParts.get(2)=="PM", v_ThisDateEvent_Hour.toLong() + 12, v_ThisDateEvent_Hour);
v_ThisDateEvent_Hour = if(v_ThisDateEvent_Hour.toLong()==24, "12", v_ThisDateEvent_Hour);
//
v_ThisEventDate = v_ThisDateEvent_Year + "-" + v_ThisDateEvent_Month + "-" + v_ThisDateEvent_Day;
v_ThisEventDateSort = v_ThisDateEvent_Year.toString() + v_ThisDateEvent_Month.toString() + v_ThisDateEvent_Day.toString() + v_ThisDateEvent_Hour.toString() + v_ThisDateEvent_Minute.toString() + ifnull(m_PastEvent.get("title"),"?").trim().toLowerCase();
v_ThisEventStart = v_ThisDateEvent_Year + "-" + v_ThisDateEvent_Month + "-" + v_ThisDateEvent_Day + " " + v_ThisDateEvent_Hour + ":" + v_ThisDateEvent_Minute + ":00";
//
// date and time obtained... do your other stuff here
}
}
}
}
//
// get all future events
// NB: status=open are upcoming events; status=closed are events in the past; status is a mandatory field
// NB: range is an integer and the number of records to return (default=100; max=200)
// NB: index is an integer and is the offset or starting index (not the ID of the record)
m_Params = Map();
m_Params.put("range",50);
m_Params.put("status","open");
v_EndpointEvents = v_BaseURL + "/restapi/portal/" + v_PortalID + "/projects/" + v_ProjectID + "/events/";
r_FutureEvents = invokeurl
[
url :v_EndpointEvents
type :GET
parameters:m_Params
connection:"my_projects_connection"
];
l_FutureEvents = ifnull(r_FutureEvents.get("events"),List());
- //
- // ***********************************
- // get Zoho Projects information
- v_BaseURL = "https://projectsapi.zoho.com";
- v_Heading = "";
- //
- // get all portals
- v_EndpointPortals = v_BaseURL + "/restapi/portals/";
- r_Portals = invokeUrl
- [
- url: v_EndpointPortals
- type: GET
- connection: "my_projects_connection"
- ];
- info r_Portals;
- //
- // once we check the JSON, we can select a portal name and ID, this avoids the need of using up an API request to get the portal
- v_PortalName = "my_portal";
- v_PortalID = "789456123";
- //
- // get all projects
- v_EndpointProjects = v_BaseURL + "/restapi/portal/" + v_PortalID + "/projects/";
- r_Projects = invokeUrl
- [
- url: v_EndpointProjects
- type: GET
- connection: "my_projects_connection"
- ];
- //
- // already decided as we only want one
- v_ProjectName = "My Project Board";
- v_ProjectID = "1234567000001234567";
- //
- // get all users (optional here)
- v_EndpointUsers = v_BaseURL + "/restapi/portal/" + v_PortalID + "/projects/" + v_ProjectID + "/users/";
- r_Users = invokeUrl
- [
- url :v_EndpointUsers
- type :GET
- connection:"my_projects_connection"
- ];
- //
- // get all events
- // NB: status=open are upcoming events; status=closed are events in the past; status is a mandatory field
- // NB: range is an integer and the number of records to return (default=100; max=200)
- // NB: index is an integer and is the offset or starting index (not the ID of the record)
- m_Params = Map();
- m_Params.put("range",50);
- m_Params.put("status","closed");
- v_EndpointEvents = v_BaseURL + "/restapi/portal/" + v_PortalID + "/projects/" + v_ProjectID + "/events/";
- r_PastEvents = invokeUrl
- [
- url :v_EndpointEvents
- type :GET
- parameters:m_Params
- connection:"my_projects_connection"
- ];
- l_PastEvents = ifnull(r_PastEvents.get("events"),List());
- for each m_PastEvent in l_PastEvents
- {
- //
- // convert a Zoho Project DateTime to a DateTime datatype (given 12/12/2023 12:00:00 PM... remove ambiguity: mm/dd or dd/mm?)
- if(!isNull(m_PastEvent.get("scheduled_on")))
- {
- if(m_PastEvent.get("scheduled_on").contains(" "))
- {
- l_ThisDateTimeEventParts = m_PastEvent.get("scheduled_on").toList(" ");
- if(l_ThisDateTimeEventParts.get(0).contains("/"))
- {
- l_ThisDateEventParts = l_ThisDateTimeEventParts.get(0).toList("/");
- v_ThisDateEvent_Year = l_ThisDateEventParts.get(2);
- v_ThisDateEvent_Month = l_ThisDateEventParts.get(1);
- v_ThisDateEvent_Day = l_ThisDateEventParts.get(0);
- l_ThisTimeEventParts = l_ThisDateTimeEventParts.get(1).toList(":");
- v_ThisDateEvent_Minute = l_ThisTimeEventParts.get(1);
- v_ThisDateEvent_Hour = l_ThisTimeEventParts.get(0);
- //
- // convert 12-hour to 24-hour
- v_ThisDateEvent_Hour = if(l_ThisDateTimeEventParts.get(2)=="PM", v_ThisDateEvent_Hour.toLong() + 12, v_ThisDateEvent_Hour);
- v_ThisDateEvent_Hour = if(v_ThisDateEvent_Hour.toLong()==24, "12", v_ThisDateEvent_Hour);
- //
- v_ThisEventDate = v_ThisDateEvent_Year + "-" + v_ThisDateEvent_Month + "-" + v_ThisDateEvent_Day;
- v_ThisEventDateSort = v_ThisDateEvent_Year.toString() + v_ThisDateEvent_Month.toString() + v_ThisDateEvent_Day.toString() + v_ThisDateEvent_Hour.toString() + v_ThisDateEvent_Minute.toString() + ifnull(m_PastEvent.get("title"),"?").trim().toLowerCase();
- v_ThisEventStart = v_ThisDateEvent_Year + "-" + v_ThisDateEvent_Month + "-" + v_ThisDateEvent_Day + " " + v_ThisDateEvent_Hour + ":" + v_ThisDateEvent_Minute + ":00";
- //
- // date and time obtained... do your other stuff here
- }
- }
- }
- }
- //
- // get all future events
- // NB: status=open are upcoming events; status=closed are events in the past; status is a mandatory field
- // NB: range is an integer and the number of records to return (default=100; max=200)
- // NB: index is an integer and is the offset or starting index (not the ID of the record)
- m_Params = Map();
- m_Params.put("range",50);
- m_Params.put("status","open");
- v_EndpointEvents = v_BaseURL + "/restapi/portal/" + v_PortalID + "/projects/" + v_ProjectID + "/events/";
- r_FutureEvents = invokeUrl
- [
- url :v_EndpointEvents
- type :GET
- parameters:m_Params
- connection:"my_projects_connection"
- ];
- l_FutureEvents = ifnull(r_FutureEvents.get("events"),List());
Additional: Code to get a single event:
The above is great on a test system where you don't have many events, but what if this the system has far more than 50 events, past or upcoming? Here's the code to get a single event record by its record ID. Note that this isn't in the official documentation but at time of print, this works:
copyraw
// // get event record by ID v_EndpointEvent = v_BaseURL + "/restapi/portal/" + v_PortalID + "/projects/" + v_ProjectID + "/events/" + v_EventID + "/"; r_ThisEvent = invokeurl [ url :v_EndpointEvent type :GET connection:"my_projects_connection" ]; info r_ThisEvent;
- //
- // get event record by ID
- v_EndpointEvent = v_BaseURL + "/restapi/portal/" + v_PortalID + "/projects/" + v_ProjectID + "/events/" + v_EventID + "/";
- r_ThisEvent = invokeUrl
- [
- url :v_EndpointEvent
- type :GET
- connection:"my_projects_connection"
- ];
- info r_ThisEvent;
Source(s):
- Zoho Projects - REST API - Documentation
- Zoho Projects - REST API - Documentation - Search for Events by Name
Category: Zoho :: Article: 878



Add comment