Search code examples
curlzohobooks

Why isn't my Zoho Books API 'criteria' filter for 'contact_name' working with cURL? (applies to /contacts)


Thanks in advnace, for the record this is not about deluge. The request must be provided via cURL.

The problem:

1- Requests to fetch contacts that match $criteria return all contacts in ZohoBooks instead of the contacts that contain the string.

This means that the $criteria do not bring up 'contact_names' that match. It brings them all.

2- I am 90% sure the problem is the way I am building the $url, but no amount of reading on zoho.com/books/api/v3/contacts/ or playing with POSTman gave me any better ideas about how to pass the filter properly.

... $criteria = "(contact_name:contains:'" . urlencode($contactName) . "')"; //***this is an update from previous post*** $url = "https://www.zohoapis.com/books/v3/contacts?organization_id=$organizationId&criteria=$criteria"; logMessage("Initiating cURL request to URL: $url");

In case it matters here is the rest of my code:

<?php
include_once '../../zoho_refresh.php';

date_default_timezone_set('America/Panama');
error_reporting(E_ALL);
ini_set('display_errors', '1');
ini_set('log_errors', 1);
ini_set('error_log', __DIR__ . '/call_to_name_validator_zoho.log');

$logFile = __DIR__ . '/call_to_name_validator_zoho.log';

function errorHandler($errno, $errstr, $errfile, $errline) {
    global $logFile;
    $date = date('Y-m-d H:i:s');
    $errorMessage = "[{$date}] Error: {$errno}: {$errstr} in {$errfile} on line {$errline}\n";
    error_log($errorMessage, 3, $logFile);
    echo "An error occurred. Please try again later.";
}
set_error_handler("errorHandler");

function logMessage($message) {
    global $logFile;
    $timeStamp = date('Y-m-d H:i:s');
    $logEntry = "[{$timeStamp}] $message\n---------------------------------------------\n";
    error_log($logEntry, 3, $logFile);
}

logMessage("Validator executed");

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['contact_name']) && !empty($_POST['contact_name'])) {
    $contactName = $_POST['contact_name'];
    logMessage("Contact name received: $contactName");

    $accessToken = getAccessToken();
    logMessage("Access token retrieved: $accessToken");

    $organizationId = '##########';
    $criteria = "(contact_name:contains:'" . urlencode($contactName) . "')"; //*** This is an update from original post ***
    $url = "https://www.zohoapis.com/books/v3/contacts?organization_id=$organizationId&criteria=$criteria";
    logMessage("Initiating cURL request to URL: $url");

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Authorization: Zoho-oauthtoken ' . $accessToken,
        'Content-Type: application/json'
    ]);

    $response = curl_exec($ch);
    $err = curl_error($ch);
    curl_close($ch);

    if ($err) {
        logMessage("cURL error: $err");
        echo json_encode(['status' => 'error', 'message' => $err]);
    } else {
        logMessage("Zoho response: $response");
        $result = json_decode($response, true);
        if (isset($result['contacts'])) {
            $contacts = array_map(function ($contact) {
                return [
                    'contact_name' => $contact['contact_name'],
                    'customer_name' => $contact['customer_name'] ?? null,
                    'email' => $contact['email'] ?? null,
                ];
            }, $result['contacts']);
            echo json_encode(['status' => 'success', 'contacts' => $contacts]);
        } else {
            echo json_encode(['status' => 'error', 'message' => 'No contacts found']);
        }
    }
} else {
    logMessage("No or invalid contact name provided");
    echo json_encode(['status' => 'error', 'message' => 'No or invalid contact name provided']);
 }
   ?>

What I have tried

  1. ChatGPT
  2. Getting the right structure via POSTman
  3. Gemini (I'm that desperate).
  4. Tried with equal, contain...
  5. Direct hardcoded the $url: $url = "https://www.zohoapis.com/books/v3/contacts?organization_id=$organizationId&criteria=(contact_name:starts_with:'Fu')";

**Every single time, the response that I get is the first 200 contacts (as per Zoho Books limits), so I am sure it is ignoring the &criteria=$criteria" part. **

What I expected

Yet my expectation was to obtain the contacts that "contain" the "criteria". For example, if I type Fu... in a search box, it should brink all the clients that contain Fu or fu .... like Frankfurt Flughafen Rosa Kuchen Corp., Funny How I Always Screw It on The Simple Part, Fushin Show Mein, Sei Fuori Dal Gioco...

What I think is the Problem

I am willing to bet the problem is that I do not what is the proper way to pass to ZohoBooks the right criteria to fetch the fields that match the string provided.

$url = "https://www.zohoapis.com/books/v3/contacts?organization_id=$organizationId&criteria=$criteria";

Solution

  • This was the solution:

    $url = "https://www.zohoapis.com/books/v3/contacts?organization_id=" . $organizationId . "&contact_name_startswith=" . $contactName;