klaviyo-api-php icon indicating copy to clipboard operation
klaviyo-api-php copied to clipboard

page_cursor not working or documented wrong

Open HappydaysAS opened this issue 1 year ago • 9 comments

According to the documentation, the parameter page_cursor in getProfiles() is supposed to be the content of the "next" attribute. Doing so will parse the entire URL into the url parameter, page_cursor.

So either it's not working as intended or the documentation is incorrect

HappydaysAS avatar Jan 17 '24 13:01 HappydaysAS

Hi, can you clarify what you mean here with an example of how you're trying to use getProfiles? Also, will you link to the exact documentation that may be incorrect here?

sanfordj avatar Jan 17 '24 15:01 sanfordj

Sure thing.

So I'm running a call to get suppressed profiles based on a specific date

$this->klaviyoAPI->Profiles->getProfiles(filter: "greater-or-equal(subscriptions.email.marketing.suppression.timestamp,{$date})", apiKey: config('klaviyo.api_token'));

this returns to me a response with some paginated profiles. To get the next page, I'm running the same code but adding the page_cursor parameter to getProfiles() which is the link from "next" in the previous response.

This is done like the documentation states on Github under "How to use pagination and the page[size] param" - "NOTE: This page cursor value is exactly what is returned in the self/next/prev response values"

However this does not work and it seems like I actually have to grab the page_cursor parameter from the URL in "next" from the first response in order for it to work.

jesperbjoernandersen avatar Jan 18 '24 11:01 jesperbjoernandersen

hmmm, i have it working on my end, can you share your code?

for example, here is the call i tested on my end:

<?php
require_once(__DIR__ . '/vendor/autoload.php');

use KlaviyoAPI\KlaviyoAPI;

$klaviyo = new KlaviyoAPI(
    'YOUR_KEY', 
    $num_retries = 3, 
    $wait_seconds = 3,
    $guzzle_options = []);

$response1 = $klaviyo->Events->getEvents();

$cursor = $response1['links']['next'];

$response = $klaviyo->Events->getEvents($fields_event=NULL, $fields_metric=NULL, $fields_profile=NULL, $filter=NULL, $include=NULL, $page_cursor=$cursor);

print_r($response);

jon-batscha avatar Jan 18 '24 16:01 jon-batscha

Sure thing

public function getSuppressedSince($date = null)
    {
        $date = $date ?? now()->subDays(3)->toDateString();
        $collection = collect();

        $response = $this->klaviyoAPI->Profiles->getProfiles(filter: "greater-or-equal(subscriptions.email.marketing.suppression.timestamp,{$date})", apiKey: config('klaviyo.api_token'));

        $collection->push(ProfileData::collection($response['data']));

        if ($response['links']['next'])
        {
            $response = $this->klaviyoAPI->Profiles->getProfiles(filter: "greater-or-equal(subscriptions.email.marketing.suppression.timestamp,{$date})", apiKey: config('klaviyo.api_token'), page_cursor: $response['links']['next']);

            $collection->push(ProfileData::collection($response['data']));
        }

        return $collection->flatten();
    }

HappydaysAS avatar Jan 22 '24 10:01 HappydaysAS

Guys, let me know please where I can find how to use this sdk, looks like official docs has example only for GuzzleHttp.

jack-fdrv avatar Feb 02 '24 13:02 jack-fdrv

Any updates on this? Again, from the first response I get the following: Screenshot from 2024-02-13 11-09-59

It then states in the documentation, I should add the value of ['links']['next'] to page_cursor, like so:

$this->klaviyoAPI->Profiles->getProfiles(filter: "greater-or-equal(subscriptions.email.marketing.suppression.timestamp,{$date})", apiKey: config('klaviyo.api_token'), page_cursor: $response['links']['next']);

But this gives me the 400 error "GET https://a.klaviyo.com/api/profiles/?filter=greater-or-equal%28subscriptions.email.marketing.suppression.timestamp%2C2024-02-10%29&page%5Bcursor%5D=https%3A%2F%2Fa.klaviyo.com%2Fapi%2Fprofiles%2F%3Ffilter%3Dgreater-or-equal%2528subscriptions.email.marketing.suppression.timestamp%252C2024-02-10%2529%26page%255Bsize%255D%3D20%26page%255Bcursor%255D%3DbmV4dDo6dGltZXN0YW1wOjoyMDI0LTAyLTEwIDEwOjM4OjE4LjUyMzU0OCswMDowMDo6aWQ6OjcwNDYxODM5NjE&page%5Bsize%5D=20"

HappydaysAS avatar Feb 13 '24 10:02 HappydaysAS

The issue is using keyword arguments. If you don't use keyword arguments, it works fine. That's because the Subclient uses reflection to determine if the cursor is an argument. It looks for it via argument position (index) instead of by argument name.

Because of this, if you use keyword arguments, the cursor is not parsed to get the query string value from the URL you are passing.

You need to parse the next URL to get the cursor value and pass that to the page_cursor argument.

Get the cursor value from the URL like this:

$query = null;

parse_str(parse_url($cursor, PHP_URL_QUERY), $query);

$cursor = $query['page']['cursor'] ?? null;

@sanfordj it's unclear why reflection is used at all.

joelvh avatar Mar 26 '24 22:03 joelvh

@sanfordj #51 should fix it

joelvh avatar Mar 26 '24 23:03 joelvh

Hi, thanks for your patience with this issue. We've made a patch update v7.1.2 which use's @joelvh's suggested changes.

nat-klaviyo avatar Apr 09 '24 16:04 nat-klaviyo