For Zoho Services only:


I'm actually part of something bigger at Ascent Business Solutions recognized as the top Zoho Premium Solutions Partner in the United Kingdom.

Ascent Business Solutions offer support for smaller technical fixes and projects for larger developments, such as migrating to a ZohoCRM.  A team rather than a one-man-band is always available to ensure seamless progress and address any concerns. You'll find our competitive support rates with flexible, no-expiration bundles at https://ascentbusiness.co.uk/zoho-services/uk-zoho-support.  For larger projects, talk to our experts and receive dedicated support from our hands-on project consultants at https://ascentbusiness.co.uk/zoho-services/zoho-crm-implementation.

The team I manage specializes in coding API integrations between Zoho and third-party finance/commerce suites such as Xero, Shopify, WooCommerce, and eBay; to name but a few.  Our passion lies in creating innovative solutions where others have fallen short as well as working with new businesses, new sectors, and new ideas.  Our success is measured by the growth and ROI we deliver for clients, such as transforming a garden shed hobby into a 250k monthly turnover operation or generating a +60% return in just three days after launch through online payments and a streamlined e-commerce solution, replacing a paper-based system.

If you're looking for a partner who can help you drive growth and success, we'd love to work with you.  You can reach out to us on 0121 392 8140 (UK) or info@ascentbusiness.co.uk.  You can also visit our website at https://ascentbusiness.co.uk.

Zoho Projects: Get All Events

What?
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());
  1.  // 
  2.  // *********************************** 
  3.  // get Zoho Projects information 
  4.  v_BaseURL = "https://projectsapi.zoho.com"
  5.  v_Heading = ""
  6.  // 
  7.  // get all portals 
  8.  v_EndpointPortals = v_BaseURL + "/restapi/portals/"
  9.  r_Portals = invokeUrl 
  10.  [ 
  11.      url: v_EndpointPortals 
  12.      type: GET 
  13.      connection: "my_projects_connection" 
  14.  ]
  15.  info r_Portals; 
  16.  // 
  17.  // 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 
  18.  v_PortalName = "my_portal"
  19.  v_PortalID = "789456123"
  20.  // 
  21.  // get all projects 
  22.  v_EndpointProjects = v_BaseURL + "/restapi/portal/" + v_PortalID + "/projects/"
  23.  r_Projects = invokeUrl 
  24.  [ 
  25.      url: v_EndpointProjects 
  26.      type: GET 
  27.      connection: "my_projects_connection" 
  28.  ]
  29.  // 
  30.  // already decided as we only want one 
  31.  v_ProjectName = "My Project Board"
  32.  v_ProjectID = "1234567000001234567"
  33.  // 
  34.  // get all users (optional here) 
  35.  v_EndpointUsers = v_BaseURL + "/restapi/portal/" + v_PortalID + "/projects/" + v_ProjectID + "/users/"
  36.  r_Users = invokeUrl 
  37.  [ 
  38.      url :v_EndpointUsers 
  39.      type :GET 
  40.      connection:"my_projects_connection" 
  41.  ]
  42.  // 
  43.  // get all events 
  44.  // NB: status=open are upcoming events; status=closed are events in the past; status is a mandatory field 
  45.  // NB: range is an integer and the number of records to return (default=100; max=200) 
  46.  // NB: index is an integer and is the offset or starting index (not the ID of the record) 
  47.  m_Params = Map()
  48.  m_Params.put("range",50)
  49.  m_Params.put("status","closed")
  50.  v_EndpointEvents = v_BaseURL + "/restapi/portal/" + v_PortalID + "/projects/" + v_ProjectID + "/events/"
  51.  r_PastEvents = invokeUrl 
  52.  [ 
  53.      url :v_EndpointEvents 
  54.      type :GET 
  55.      parameters:m_Params 
  56.      connection:"my_projects_connection" 
  57.  ]
  58.  l_PastEvents = ifnull(r_PastEvents.get("events"),List())
  59.  for each  m_PastEvent in l_PastEvents 
  60.  { 
  61.      // 
  62.      // convert a Zoho Project DateTime to a DateTime datatype (given 12/12/2023 12:00:00 PM... remove ambiguity: mm/dd or dd/mm?) 
  63.      if(!isNull(m_PastEvent.get("scheduled_on"))) 
  64.      { 
  65.          if(m_PastEvent.get("scheduled_on").contains(" ")) 
  66.          { 
  67.              l_ThisDateTimeEventParts = m_PastEvent.get("scheduled_on").toList(" ")
  68.              if(l_ThisDateTimeEventParts.get(0).contains("/")) 
  69.              { 
  70.                  l_ThisDateEventParts = l_ThisDateTimeEventParts.get(0).toList("/")
  71.                  v_ThisDateEvent_Year = l_ThisDateEventParts.get(2)
  72.                  v_ThisDateEvent_Month = l_ThisDateEventParts.get(1)
  73.                  v_ThisDateEvent_Day = l_ThisDateEventParts.get(0)
  74.                  l_ThisTimeEventParts = l_ThisDateTimeEventParts.get(1).toList(":")
  75.                  v_ThisDateEvent_Minute = l_ThisTimeEventParts.get(1)
  76.                  v_ThisDateEvent_Hour = l_ThisTimeEventParts.get(0)
  77.                  // 
  78.                  // convert 12-hour to 24-hour 
  79.                  v_ThisDateEvent_Hour = if(l_ThisDateTimeEventParts.get(2)=="PM", v_ThisDateEvent_Hour.toLong() + 12, v_ThisDateEvent_Hour)
  80.                  v_ThisDateEvent_Hour = if(v_ThisDateEvent_Hour.toLong()==24, "12", v_ThisDateEvent_Hour)
  81.                  // 
  82.                  v_ThisEventDate = v_ThisDateEvent_Year + "-" + v_ThisDateEvent_Month + "-" + v_ThisDateEvent_Day; 
  83.                  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()
  84.                  v_ThisEventStart = v_ThisDateEvent_Year + "-" + v_ThisDateEvent_Month + "-" + v_ThisDateEvent_Day + " " + v_ThisDateEvent_Hour + ":" + v_ThisDateEvent_Minute + ":00"
  85.                  // 
  86.                  // date and time obtained... do your other stuff here 
  87.              } 
  88.          } 
  89.      } 
  90.  } 
  91.  // 
  92.  // get all future events 
  93.  // NB: status=open are upcoming events; status=closed are events in the past; status is a mandatory field 
  94.  // NB: range is an integer and the number of records to return (default=100; max=200) 
  95.  // NB: index is an integer and is the offset or starting index (not the ID of the record) 
  96.  m_Params = Map()
  97.  m_Params.put("range",50)
  98.  m_Params.put("status","open")
  99.  v_EndpointEvents = v_BaseURL + "/restapi/portal/" + v_PortalID + "/projects/" + v_ProjectID + "/events/"
  100.  r_FutureEvents = invokeUrl 
  101.  [ 
  102.      url :v_EndpointEvents 
  103.      type :GET 
  104.      parameters:m_Params 
  105.      connection:"my_projects_connection" 
  106.  ]
  107.  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;
  1.  // 
  2.  // get event record by ID 
  3.  v_EndpointEvent = v_BaseURL + "/restapi/portal/" + v_PortalID + "/projects/" + v_ProjectID + "/events/" + v_EventID + "/"
  4.  r_ThisEvent = invokeUrl 
  5.  [ 
  6.      url :v_EndpointEvent 
  7.      type :GET 
  8.      connection:"my_projects_connection" 
  9.  ]
  10.  info r_ThisEvent; 

Source(s):

Category: Zoho :: Article: 878

Credit where Credit is Due:


Feel free to copy, redistribute and share this information. All that we ask is that you attribute credit and possibly even a link back to this website as it really helps in our search engine rankings.

Disclaimer: Please note that the information provided on this website is intended for informational purposes only and does not represent a warranty. The opinions expressed are those of the author only. We recommend testing any solutions in a development environment before implementing them in production. The articles are based on our good faith efforts and were current at the time of writing, reflecting our practical experience in a commercial setting.

Thank you for visiting and, as always, we hope this website was of some use to you!

Kind Regards,

Joel Lipman
www.joellipman.com

Related Articles

Joes Revolver Map

Accreditation

Badge - Certified Zoho Creator Associate
Badge - Certified Zoho Creator Associate

Donate & Support

If you like my content, and would like to support this sharing site, feel free to donate using a method below:

Paypal:
Donate to Joel Lipman via PayPal

Bitcoin:
Donate to Joel Lipman with Bitcoin bc1qf6elrdxc968h0k673l2djc9wrpazhqtxw8qqp4

Ethereum:
Donate to Joel Lipman with Ethereum 0xb038962F3809b425D661EF5D22294Cf45E02FebF
© 2024 Joel Lipman .com. All Rights Reserved.