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 http://ascentbusiness.co.uk/zoho-support-2.  For larger projects, check our bespoke pricing structure and receive dedicated support from our hands-on project consultants and developers at http://ascentbusiness.co.uk/crm-solutions/zoho-crm-packages-prices.

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 http://ascentbusiness.co.uk.

ZohoDeluge: Check Shipment Status via DHL API

What?
A quick note here on how to connect to the DHL API and check on a package given a tracking number.

Why?
In our megafunction to generate a customer, a product/item, a sales order, an invoice, a package slip/delivery note, a shipment order; as well as record any payments, inventory adjustments, status changes; all from an eBay Order coming into the system via a webhook... I would like to mark a shipment as delivered only if the courier, in this case DHL, confirms the tracked order was delivered.

How?
So first I'll give some brief instructions on how to get an API key from DHL as a developer and then I'll include the code to query the shipment status based on a tracking number.

Becoming a DHL Developer
  1. Browse to https://developer.dhl.com/user/register to Signup
  2. Complete the form with your details > Confirm via Email
  3. Create an app as described under Get Access section
  4. Click My Apps on the portal website
  5. Click on the App you created
  6. Note the API Key by clicking on "Show Key"

The deluge function
So this function will return the word "delivered" or whatever other statuses there are for a package:
copyraw
/*
    Function: String fn_DHL_CheckShipmentStatus(string p_TrackingNumber)
	
    Purpose: Queries DHL for tracking information about a shipment and returns the status code (eg. "delivered")
	
    Date Created:   2023-03-21 (Joel Lipman)
                    - Initial release
	Date Modified:  2023-03-21 (Joel Lipman)
					- ???

    More Info:
		- DHL Developer Portal: https://developer.dhl.com/
		- DHL Developer Portal Signup: https://developer.dhl.com/user/register
		- DHL Developer API Documentaiton: https://developer.dhl.com/api-reference/shipment-tracking#reference-docs-section
*/
//
// initialize
v_ShipmentStatus = "error";
v_TrackingNumber = ifnull(p_TrackingNumber,0);
//
// specify your DHL API Key (no need for the secret or base64 encoding)
v_DHL_API_Key = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
//
// build up header
m_Header = Map();
m_Header.put("DHL-API-Key",v_DHL_API_Key);
// 
// build up request
v_Endpoint = "https://api-eu.dhl.com/track/shipments?trackingNumber=" + v_TrackingNumber;
//
// send request
r_ShipmentDetails = invokeurl
[
	url: v_Endpoint
	type: GET
	headers: m_Header
	detailed: true
];
//
// parse response
if(r_ShipmentDetails.get("responseCode")==200)
{
	l_Shipments = r_ShipmentDetails.get("responseText").get("shipments");
	for each r_Shipment in l_Shipments
    {
		if(!isnull(r_Shipment.get("status")))
		{
			v_ShipmentStatus = r_Shipment.get("status").get("statusCode");
			info v_ShipmentStatus;
		}
    }
}
//
// return response
return v_ShipmentStatus;
  1.  /* 
  2.      Function: string fn_DHL_CheckShipmentStatus(string p_TrackingNumber) 
  3.   
  4.      Purpose: Queries DHL for tracking information about a shipment and returns the status code (eg. "delivered") 
  5.   
  6.      Date Created:   2023-03-21 (Joel Lipman) 
  7.                      - Initial release 
  8.      Date Modified:  2023-03-21 (Joel Lipman) 
  9.                      - ??? 
  10.   
  11.      More Info: 
  12.          - DHL Developer Portal: https://developer.dhl.com/ 
  13.          - DHL Developer Portal Signup: https://developer.dhl.com/user/register 
  14.          - DHL Developer API Documentaiton: https://developer.dhl.com/api-reference/shipment-tracking#reference-docs-section 
  15.  */ 
  16.  // 
  17.  // initialize 
  18.  v_ShipmentStatus = "error"
  19.  v_TrackingNumber = ifnull(p_TrackingNumber,0)
  20.  // 
  21.  // specify your DHL API Key (no need for the secret or base64 encoding) 
  22.  v_DHL_API_Key = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  23.  // 
  24.  // build up header 
  25.  m_Header = Map()
  26.  m_Header.put("DHL-API-Key",v_DHL_API_Key)
  27.  // 
  28.  // build up request 
  29.  v_Endpoint = "https://api-eu.dhl.com/track/shipments?trackingNumber=" + v_TrackingNumber; 
  30.  // 
  31.  // send request 
  32.  r_ShipmentDetails = invokeUrl 
  33.  [ 
  34.      url: v_Endpoint 
  35.      type: GET 
  36.      headers: m_Header 
  37.      detailed: true 
  38.  ]
  39.  // 
  40.  // parse response 
  41.  if(r_ShipmentDetails.get("responseCode")==200) 
  42.  { 
  43.      l_Shipments = r_ShipmentDetails.get("responseText").get("shipments")
  44.      for each r_Shipment in l_Shipments 
  45.      { 
  46.          if(!isnull(r_Shipment.get("status"))) 
  47.          { 
  48.              v_ShipmentStatus = r_Shipment.get("status").get("statusCode")
  49.              info v_ShipmentStatus; 
  50.          } 
  51.      } 
  52.  } 
  53.  // 
  54.  // return response 
  55.  return v_ShipmentStatus; 

Alternative get request:
copyraw
r_ShipmentDetails = getUrl(v_Endpoint, m_Header, false);
  1.  r_ShipmentDetails = getUrl(v_Endpoint, m_Header, false)

Not done yet!
Of course, it would help if when something was delivered, that was conveyed back to the system that asked, in this case Zoho Inventory. So for this, I've set up a nightly schedule which checks on all the shipments from a certain date and updates the shipment status for items that have been delivered:
Login to ZohoInventory > Setup (Cog Icon) > Automation > Schedules > New Schedule > I'm calling mine Nightly Schedule To Update Shipment Status
copyraw
//
// init
v_DaysAgo = 2;
v_BooksOrgID = organization.get("organization_id");
//
// specify DHL API Key (no need for the secret)
v_DHL_API_Key = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
//
// build up header
m_Header = Map();
m_Header.put("DHL-API-Key",v_DHL_API_Key);
//
// generate a list based on the number of days ago (list of dates to check)
l_GeneratedList = leftpad(" ",v_DaysAgo).replaceAll(" ",",").toList();
//
// loop through
for each index v_Index in l_GeneratedList
{
	// output to developer for debug purposes
	v_Date = zoho.currentdate.subDay(v_Index).toString("yyyy-MM-dd");
	info v_Date;
	//
	// set criteria of what shipment orders to retrieve
	m_Criteria = Map();
	m_Criteria.put("date",v_Date);
	//
	// retrieve all shipment orders for that day from ZohoInventory
	r_YesterdaysShipments = zoho.inventory.getRecords("shipmentorders",v_BooksOrgID,m_Criteria,"ab_inventory");
	if(!isnull(r_YesterdaysShipments.get("shipmentorders")))
	{
		l_YesterdaysShipments = r_YesterdaysShipments.get("shipmentorders");
		for each  r_ZohoShipment in l_YesterdaysShipments
		{
			if(!isnull(r_ZohoShipment.get("tracking_number")))
			{
				// 
				// build up request
				v_Endpoint = "https://api-eu.dhl.com/track/shipments?trackingNumber=" + r_ZohoShipment.get("tracking_number");
				info "SO-Ref: " + r_ZohoShipment.get("salesorder_number");
				info "Tracking #: " + r_ZohoShipment.get("tracking_number");
				//
				// send request
				r_DhlShipmentDetails = invokeurl
				[
					url :v_Endpoint
					type :GET
					headers:m_Header
					detailed:true
				];
				//
				// parse response
				if(r_DhlShipmentDetails.get("responseCode") == 200)
				{
					l_DhlShipments = r_DhlShipmentDetails.get("responseText").get("shipments");
					for each  r_DhlShipment in l_DhlShipments
					{
						if(!isnull(r_DhlShipment.get("status")))
						{
							v_ShipmentStatus = r_DhlShipment.get("status").get("statusCode");
							if(v_ShipmentStatus == "delivered")
							{
								v_EndpointUpdate = "https://inventory.zoho.eu/api/v1/shipmentorders/" + r_ZohoShipment.get("shipment_id") + "/status/delivered?organization_id=" + v_BooksOrgID;
								r_ZohoShipmentUpdate = invokeurl
								[
									url :v_EndpointUpdate
									type :POST
									connection:"ab_inventory"
								];
								info "Message: " + r_ZohoShipmentUpdate.get("message");
							}
						}
					}
				}
			}
		}
	}
}
  1.  // 
  2.  // init 
  3.  v_DaysAgo = 2
  4.  v_BooksOrgID = organization.get("organization_id")
  5.  // 
  6.  // specify DHL API Key (no need for the secret) 
  7.  v_DHL_API_Key = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  8.  // 
  9.  // build up header 
  10.  m_Header = Map()
  11.  m_Header.put("DHL-API-Key",v_DHL_API_Key)
  12.  // 
  13.  // generate a list based on the number of days ago (list of dates to check) 
  14.  l_GeneratedList = leftpad(" ",v_DaysAgo).replaceAll(" ",",").toList()
  15.  // 
  16.  // loop through 
  17.  for each index v_Index in l_GeneratedList 
  18.  { 
  19.      // output to developer for debug purposes 
  20.      v_Date = zoho.currentdate.subDay(v_Index).toString("yyyy-MM-dd")
  21.      info v_Date; 
  22.      // 
  23.      // set criteria of what shipment orders to retrieve 
  24.      m_Criteria = Map()
  25.      m_Criteria.put("date",v_Date)
  26.      // 
  27.      // retrieve all shipment orders for that day from ZohoInventory 
  28.      r_YesterdaysShipments = zoho.inventory.getRecords("shipmentorders",v_BooksOrgID,m_Criteria,"ab_inventory")
  29.      if(!isnull(r_YesterdaysShipments.get("shipmentorders"))) 
  30.      { 
  31.          l_YesterdaysShipments = r_YesterdaysShipments.get("shipmentorders")
  32.          for each  r_ZohoShipment in l_YesterdaysShipments 
  33.          { 
  34.              if(!isnull(r_ZohoShipment.get("tracking_number"))) 
  35.              { 
  36.                  // 
  37.                  // build up request 
  38.                  v_Endpoint = "https://api-eu.dhl.com/track/shipments?trackingNumber=" + r_ZohoShipment.get("tracking_number")
  39.                  info "SO-Ref: " + r_ZohoShipment.get("salesorder_number")
  40.                  info "Tracking #: " + r_ZohoShipment.get("tracking_number")
  41.                  // 
  42.                  // send request 
  43.                  r_DhlShipmentDetails = invokeUrl 
  44.                  [ 
  45.                      url :v_Endpoint 
  46.                      type :GET 
  47.                      headers:m_Header 
  48.                      detailed:true 
  49.                  ]
  50.                  // 
  51.                  // parse response 
  52.                  if(r_DhlShipmentDetails.get("responseCode") == 200) 
  53.                  { 
  54.                      l_DhlShipments = r_DhlShipmentDetails.get("responseText").get("shipments")
  55.                      for each  r_DhlShipment in l_DhlShipments 
  56.                      { 
  57.                          if(!isnull(r_DhlShipment.get("status"))) 
  58.                          { 
  59.                              v_ShipmentStatus = r_DhlShipment.get("status").get("statusCode")
  60.                              if(v_ShipmentStatus == "delivered") 
  61.                              { 
  62.                                  v_EndpointUpdate = "https://inventory.zoho.eu/api/v1/shipmentorders/" + r_ZohoShipment.get("shipment_id") + "/status/delivered?organization_id=" + v_BooksOrgID; 
  63.                                  r_ZohoShipmentUpdate = invokeUrl 
  64.                                  [ 
  65.                                      url :v_EndpointUpdate 
  66.                                      type :POST 
  67.                                      connection:"ab_inventory" 
  68.                                  ]
  69.                                  info "message: " + r_ZohoShipmentUpdate.get("message")
  70.                              } 
  71.                          } 
  72.                      } 
  73.                  } 
  74.              } 
  75.          } 
  76.      } 
  77.  } 

Caveat(s):
  • Limited to 250 requests per day (can be upgraded at a cost)

Source(s):
Category: Zoho :: Article: 843

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.