Kaizen 243: Export Timeline Data from Zoho CRM Deals

Kaizen 243: Export Timeline Data from Zoho CRM Deals



Hello everyone!
Welcome to another week of Kaizen.
 When you are working with a CRM record, you need to know what changed, who changed it, and when. That is what the Timeline of a Record API in Zoho CRM achieves. With Timeline of a Record API, you get the entire life story of any record: every field change, every stage move, every time ownership changed, and all the related actions. 

Over time, several customers have requested Timeline export capabilities for reporting and offline analysis through community discussions, feature requests, and user comments. Related conversations include Exporting Deal Timeline and Export Timeline. Several users also raised similar requirements in the comments of related community discussions like this announcement.

In this Kaizen post, we will demonstrate how to build a custom function that can be associated with a custom button in the Deals module to export a Deal’s complete Timeline as a PDF and automatically attach it to the same record.

Solution Overview

To address this requirement, we created a custom function that can be invoked from a custom button in the Deals module.
The function:
  1. calls the Zoho CRM v8 Timeline of a Record API,
  2. retrieves timeline entries in chronological order,
  3. processes both field history events and non-field activity events,
  4. generates an HTML representation of the data,
  5. converts the HTML into a PDF using Zoho Writer,
  6. attaches the generated PDF to the corresponding Deal record.
This gives users a simple and reusable way to export complete Deal Timeline data with a single click.

Timeline of a Record API  

Endpoint:

GET /crm/v8/Deals/{id}/__timeline

The API returns timeline activities such as:
  1. field updates,
  2. notes,
  3. attachments,
  4. calls,
  5. emails,
  6. tasks, and
  7. record creation events.

Prerequisites

Before implementing this solution, complete the following setup.

1. Create the Required Connections

Create the following connections in Zoho CRM and store their connection link names for use in the function.

Zoho CRM Connection: "crm_oauth_connection"

This connection is used to:
  1. fetch the Deal record,
  2. retrieve Timeline data,
  3. attach the generated PDF to the Deal.
Scopes to include:
  1. ZohoCRM.modules.deals.READ
  2. ZohoCRM.modules.attachments.CREATE

Zoho Writer Connection: "writer_oauth_connection"

This connection is used to:

  1. upload the generated HTML file,
  2. convert the file into PDF,
  3. download the generated PDF.

Scopes to include:

  1. WorkDrive.workspace.ALL
  2. ZohoWriter.merge.ALL
  3. ZohoWriter.documentEditor.ALL
  4. WorkDrive.files.ALL
  5. WorkDrive.organization.ALL
  6. ZohoPC.files.ALL

2. Create a Custom Button in the Deals Module

Create a custom button in the Deals module with Placement as Record-Details, and Action as Function. Associate it with the custom function discussed in this post. When configuring the button action, pass the Deal ID and Deal Name as the input parameters. This allows users to generate the Timeline export directly from an individual Deal record.

How the Solution Works

At a high level, the function performs the following steps:
  1. constructs the Timeline of a Record API endpoint,
  2. fetches Timeline entries page by page,
  3. processes each event and formats it into HTML,
  4. uploads the HTML file to Zoho Writer,
  5. downloads the converted PDF,
  6. attaches the PDF to the Deal record.
Let us now look at each step.

Step 1:  Construct and Call the Timeline of a Record API

The function begins by converting the incoming Deal ID into numeric format and calling the Timeline of a Record API's endpoint using invokeUrl, sorting the response by audited_time.

dealId = dealId.toLong();
baseUrl = "https://www.zohoapis.com/crm/v8/Deals/" + dealId + "/__timeline";

To support Deals with larger activity histories, the function also handles pagination using next_page_token.

Step 2: Process Timeline Events

The response from the Timeline of a Record API may contain different types of entries. The function handles them in two ways:

(i)  Field History Events
If a timeline entry contains field_history, it indicates one or more field-level changes.
For each field history entry, the function extracts:
  1. the timestamp,
  2. the user who performed the change,
  3. the action,
  4. the field label,
  5. the old value,
  6. the new value.
If multiple fields were changed as part of the same timeline event, the function groups them appropriately in the output table.

(ii) Non-Field Activity Events
Some Timeline entries do not include field_history but still represent important actions, such as related record activity or other contextual events. In such cases, the function extracts the available details and includes them as separate rows in the export. This ensures that the generated PDF captures both field-level changes and broader record activity.

Step 3: Build the HTML Output

Once the data is retrieved, the function constructs an HTML document dynamically.
The generated HTML includes:
  1. a heading with the Deal name, and
  2. a table layout for the Timeline data.

Step 4: Handle Pagination

Timeline data may span multiple pages for records with a long activity history. To ensure that all entries are included, the function checks the info object returned by the API and continues fetching records while more_records is true. It uses next_page_token to request the next set of results until all available Timeline entries have been processed.
This allows the function to export a more complete history instead of limiting the output to a single page of data.

Step 5: Convert the HTML into PDF Using Zoho Writer

After the HTML is fully constructed, the function converts it into a file and uploads it to Zoho Writer.

htmlFile = html.toFile("timeline.html");
uploadResp = invokeurl
[
type :POST
files:htmlFile
connection:"writer_oauth_connection"
];

If the upload succeeds, the function retrieves the document_id from the response and uses it to download the same document in PDF format.

pdfFile = invokeurl
[
url :"https://writer.zoho.com/writer/api/v1/download/" + documentId + "?format=pdf"
type :GET
connection:"writer_oauth_connection"
];

Step 6: Attach the PDF to the Deal Record

Finally, the downloaded PDF file is attached to the same Deal record from which the Timeline data was retrieved.

attachResp = zoho.crm.attachFile("Deals",dealId,pdfFile);

If the file is attached successfully, the function returns: "Timeline PDF attached successfully".Otherwise, it returns: "PDF generation failed".

Use the complete function uploaded in the crm-kaizen GitHub repository. If you are looking to export your data into CSV format, a function for exporting timeline data in CSV format is also included in the same repository.

Associate the Function with a Custom Button

After saving the function, associate it with a custom button in the Deals module. Configure the button to pass the current Deal ID as the function input. Once this is done, users can generate the Timeline export directly from the Deal detail page.

Output

When the button is clicked, the function:
  1. fetches the complete Timeline of the selected Deal,
  2. generates a PDF version of the data,
  3. attaches the PDF to the Deal record.
This creates a snapshot of the Deal’s history that can be stored or shared as needed.

You can extend the same approach to use cases such as:
  1. exporting Timeline data for other modules,
  2. generating history snapshots before approvals,
  3. preserving change history for audits,
  4. creating printable summaries for internal review processes,
  5. archiving record activity at key milestones.
The Timeline of a Record API in Zoho CRM provides detailed visibility into the lifecycle of a record. By combining it with a Deluge function, Zoho Writer, and a custom button, you can convert that activity history into a PDF file that is easy to share and store.
We hope this Kaizen helps you achieve export of Timeline data for your Deals module. If you have questions or suggestions, share them in the comments.