0
votes

In my Laravel application I am sending DocuSign envelopes with this package: https://github.com/Tucker-Eric/Laravel-Docusign which works nicely.

This application also using the "Polling" method to check for changes to envelopes.

To accomplish this I grab the envelope IDs from various different models and then pass these IDs to DocuSign's listStatusChanges() method which takes an amount to check and an array of envelope IDs.

If the status comes back as completed I use another method getDocument() to download the signed document.

Here is the job that runs every 15 minutes.


<?php

namespace App\Jobs;

use App\CompanyActionPlan;
use App\CompanyOutcome;
use App\GrowthHubOutcome;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use App\CompanyRegistration;
use App\GrowthHubCompanyRegistration;
use App\Notifications\ActionPlanFormStatusUpdated;
use App\Notifications\GrowthHubOutcomesFormStatusUpdated;
use App\Notifications\GrowthHubRegistrationFormStatusUpdated;
use App\Notifications\OutcomesFormStatusUpdated;
use App\Notifications\RegistrationFormStatusUpdated;
use DocuSign;
use Carbon\Carbon;
use Storage;
use Log;

class PollDocuSignEnvelopes implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * The number of times the job may be attempted.
     *
     * @var int
     */
    public $tries = 3;

    /**
     * Create a new job instance.
     */
    public function __construct()
    {
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        // Create a new DocuSign client
        $client = DocuSign::create();

        // Create an empty array
        $envelopeIds = [];

        // Retrieve the unsigned envelopes from the company registrations
        $actionPlanEnvelopes = CompanyActionPlan::select('envelope_id')
            ->unsignedEnvelope()
            ->unvoidedEnvelope()
            ->pluck('envelope_id')
            ->toArray();

        // Retrieve the unsigned envelopes from the action plans
        $registrationEnvelopes = CompanyRegistration::select('envelope_id')
            ->unsignedEnvelope()
            ->unvoidedEnvelope()
            ->pluck('envelope_id')
            ->toArray();

        // Retrieve the unsigned envelopes from the outcomes
        $outcomeEnvelopes = CompanyOutcome::select('envelope_id')
            ->unsignedEnvelope()
            ->unvoidedEnvelope()
            ->pluck('envelope_id')
            ->toArray();

        // Retrieve the unsigned envelopes from the lgh outcomes
        $growthHubOutcomeEnvelopes = GrowthHubOutcome::select('envelope_id')
            ->unsignedEnvelope()
            ->unvoidedEnvelope()
            ->pluck('envelope_id')
            ->toArray();

        // Retrieve the unsigned envelopes from the lgh outcomes
        $growthHubRegistrationEnvelopes = GrowthHubCompanyRegistration::select('envelope_id')
            ->unsignedEnvelope()
            ->unvoidedEnvelope()
            ->pluck('envelope_id')
            ->toArray();

        // Merge the collection and send all envelope IDs to DocuSign for checking
        $envelopeIds = array_merge(
            $actionPlanEnvelopes,
            $registrationEnvelopes,
            $outcomeEnvelopes,
            $growthHubOutcomeEnvelopes,
            $growthHubRegistrationEnvelopes
        );

        // Only do anything if there are envelopes
        if ($envelopeIds) {
            $options = $client->envelopes->listStatusChangesOptions([
                'count' => 25,
                'envelope_ids' => $envelopeIds,
            ]);

            $changes = $client->envelopes->listStatusChanges($options);

            foreach ($changes['envelopes'] as $envelope) {
                $this->checkActionPlans($envelope, $client);
                $this->checkRegistrations($envelope, $client);
                $this->checkOutcomes($envelope, $client);
                $this->checkGrowthHubOutcomes($envelope, $client);
                $this->checkGrowthHubRegistrations($envelope, $client);
            }
        }
    }

    /**
     * Check the registration forms against the returned changes from DocuSign
     *
     * @param string $envelope
     * @param mixed  $client
     *
     */
    private function checkRegistrations($envelope, $client)
    {
        $registration = CompanyRegistration::where('envelope_id', $envelope['envelope_id'])->first();

        if ($registration) {
            // Only attempt anything if that status is actually different to the previous attempt
            if ($envelope['status'] != $registration->envelope_status) {
                Log::info("SME Registration for company {$registration->company_name} was {$envelope['status']}.");

                if ($envelope['status'] == 'voided') {
                    $voidedAt = Carbon::parse($envelope['voided_date_time']);
                    $registration->markAsVoided($voidedAt);
                    $registration->user->notify(new RegistrationFormStatusUpdated($registration));
                }

                // If the document has been declined
                if ($envelope['status'] == 'declined') {
                    $registration->markAsDeclined();
                    $registration->user->notify(new RegistrationFormStatusUpdated($registration));
                }

                // If the document has been delivered
                if ($envelope['status'] == 'delivered') {
                    $registration->markAsDelivered();
                    $registration->user->notify(new RegistrationFormStatusUpdated($registration));
                }

                // If the envelope is complete, timestamp it, notify the creator and grab the signed document
                if ($envelope['status'] == 'completed') {
                    $filePath = "/registrations/{$registration->id}/signed.pdf";

                    $this->retrieveSignedDocument($client, $registration->envelope_id, $filePath);

                    $registration->markAsCompleted(Carbon::parse($envelope['status_changed_date_time']), $filePath);

                    $registration->user->notify(new RegistrationFormStatusUpdated($registration));
                }
            }
        }
    }

    /**
     * Check the action plan forms against the returned changes from DocuSign
     *
     * @param string $envelope
     * @param mixed  $client
     *
     */
    private function checkActionPlans($envelope, $client)
    {
        $actionPlan = CompanyActionPlan::where('envelope_id', $envelope['envelope_id'])->first();

        if ($actionPlan) {
            if ($envelope['status'] != $actionPlan->envelope_status) {
                Log::info("SME Action Plan for company {$actionPlan->company_name} was {$envelope['status']}.");
                if ($envelope['status'] == 'voided') {
                    $voidedAt = Carbon::parse($envelope['voided_date_time']);
                    $actionPlan->markAsVoided($voidedAt);
                    $actionPlan->user->notify(new ActionPlanFormStatusUpdated($actionPlan));
                }

                // If the document has been declined
                if ($envelope['status'] == 'declined') {
                    $actionPlan->markAsDeclined();
                    $actionPlan->user->notify(new ActionPlanFormStatusUpdated($actionPlan));
                }

                // If the document has been delivered
                if ($envelope['status'] == 'delivered') {
                    $actionPlan->markAsDelivered();
                }

                // If the envelope is complete, timestamp it, notify the creator and grab the signed document
                if ($envelope['status'] == 'completed') {
                    $completedAt = Carbon::parse($envelope['status_changed_date_time']);

                    $filePath = "/action-plans/{$actionPlan->id}/signed.pdf";

                    $signedDocument = $client->envelopes->getDocument(1, $actionPlan->envelope_id);

                    $documentContents = file_get_contents($signedDocument->getPathname());

                    Storage::disk('local')->put($filePath, $documentContents);

                    $actionPlan->markAsCompleted($completedAt, $filePath);

                    $actionPlan->user->notify(new ActionPlanFormStatusUpdated($actionPlan));
                }
            }
        }
    }

    /**
     * Check the registration forms against the returned changes from DocuSign
     *
     * @param string $envelope
     * @param mixed  $client
     *
     */
    private function checkOutcomes($envelope, $client)
    {
        $outcome = CompanyOutcome::where('envelope_id', $envelope['envelope_id'])->first();

        if ($outcome) {
            if ($envelope['status'] != $outcome->envelope_status) {
                Log::info("SME Outcomes for company {$outcome->company_name} was {$envelope['status']}.");

                if ($envelope['status'] == 'voided') {
                    $voidedAt = Carbon::parse($envelope['voided_date_time']);
                    $outcome->markAsVoided($voidedAt);
                    $outcome->user->notify(new OutcomesFormStatusUpdated($outcome));
                }

                // If the document has been declined
                if ($envelope['status'] == 'declined') {
                    $outcome->markAsDeclined();
                    $outcome->user->notify(new OutcomesFormStatusUpdated($outcome));
                }

                // If the document has been delivered
                if ($envelope['status'] == 'delivered') {
                    $outcome->markAsDelivered();
                    $outcome->user->notify(new OutcomesFormStatusUpdated($outcome));
                }

                // If the envelope is complete, timestamp it, notify the creator and grab the signed document
                if ($envelope['status'] == 'completed') {
                    $filePath = "/outcomes/{$outcome->id}/signed.pdf";

                    $this->retrieveSignedDocument($client, $outcome->envelope_id, $filePath);

                    $outcome->markAsCompleted(Carbon::parse($envelope['status_changed_date_time']), $filePath);

                    $outcome->user->notify(new OutcomesFormStatusUpdated($outcome));
                }
            }
        }
    }

    /**
     * Check the lgh outcomes forms against the returned changes from DocuSign
     *
     * @param string $envelope
     * @param mixed  $client
     *
     */
    private function checkGrowthHubOutcomes($envelope, $client)
    {
        $outcome = GrowthHubOutcome::where('envelope_id', $envelope['envelope_id'])->first();

        if ($outcome) {
            if ($envelope['status'] != $outcome->envelope_status) {
                Log::info("LGH SME Outcomes for company {$outcome->company_name} was {$envelope['status']}.");

                if ($envelope['status'] == 'voided') {
                    $voidedAt = Carbon::parse($envelope['voided_date_time']);
                    $outcome->markAsVoided($voidedAt);
                    $outcome->user->notify(new GrowthHubOutcomesFormStatusUpdated($outcome));
                }

                // If the document has been declined
                if ($envelope['status'] == 'declined') {
                    $outcome->markAsDeclined();
                    $outcome->user->notify(new GrowthHubOutcomesFormStatusUpdated($outcome));
                }

                // If the document has been delivered
                if ($envelope['status'] == 'delivered') {
                    $outcome->markAsDelivered();
                    $outcome->user->notify(new GrowthHubOutcomesFormStatusUpdated($outcome));
                }

                // If the envelope is complete, timestamp it, notify the creator and grab the signed document
                if ($envelope['status'] == 'completed') {
                    $filePath = "/outcomes/growth-hub/{$outcome->id}/signed.pdf";

                    $this->retrieveSignedDocument($client, $outcome->envelope_id, $filePath);

                    $outcome->markAsCompleted(Carbon::parse($envelope['status_changed_date_time']), $filePath);

                    $outcome->user->notify(new GrowthHubOutcomesFormStatusUpdated($outcome));
                }
            }
        }
    }

    /**
     * Check the lgh outcomes forms against the returned changes from DocuSign
     *
     * @param string $envelope
     * @param mixed  $client
     *
     */
    private function checkGrowthHubRegistrations($envelope, $client)
    {
        $registration = GrowthHubCompanyRegistration::where('envelope_id', $envelope['envelope_id'])->first();

        if ($registration) {
            if ($envelope['status'] != $registration->envelope_status) {
                Log::info("LGH SME Registration for company {$registration->company_name} was {$envelope['status']}.");

                if ($envelope['status'] == 'voided') {
                    $voidedAt = Carbon::parse($envelope['voided_date_time']);
                    $registration->markAsVoided($voidedAt);
                    $registration->user->notify(new GrowthHubRegistrationFormStatusUpdated($registration));
                }

                // If the document has been declined
                if ($envelope['status'] == 'declined') {
                    $registration->markAsDeclined();
                    $registration->user->notify(new GrowthHubRegistrationFormStatusUpdated($registration));
                }

                // If the document has been delivered
                if ($envelope['status'] == 'delivered') {
                    $registration->markAsDelivered();
                    $registration->user->notify(new GrowthHubRegistrationFormStatusUpdated($registration));
                }

                // If the envelope is complete, timestamp it, notify the creator and grab the signed document
                if ($envelope['status'] == 'completed') {
                    $filePath = "/registrations/growth-hub/{$registration->id}/signed.pdf";

                    $this->retrieveSignedDocument($client, $registration->envelope_id, $filePath);

                    $registration->markAsCompleted(Carbon::parse($envelope['status_changed_date_time']), $filePath);

                    $registration->user->notify(new GrowthHubRegistrationFormStatusUpdated($registration));
                }
            }
        }
    }

    /**
     * Retrieve the signed document from DocuSign and save it to storage at the given file path.
     *
     * @param [type] $client
     * @param string $envelopeId
     * @param string $filePath
     */
    private function retrieveSignedDocument($client, $envelopeId, $filePath)
    {
        $signedDocument = $client->envelopes->getDocument(1, $envelopeId);

        $documentContents = file_get_contents($signedDocument->getPathname());

        Storage::disk('local')->put($filePath, $documentContents);
    }
}

Very recently, as in today, I've started receiving a 404 from the API.

This is the stack trace.


<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>404 - File or directory not found.</title>
<style type="text/css">
<!--
body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}
fieldset{padding:0 15px 10px 15px;}
h1{font-size:2.4em;margin:0;color:#FFF;}
h2{font-size:1.7em;margin:0;color:#CC0000;}
h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;}
#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF;
background-color:#555555;}
#content{margin:0 0 0 2%;position:relative;}
.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}
-->
</style>
</head>
<body>
<div id="header"><h1>Server Error</h1></div>
<div id="content">
<div class="content-container"><fieldset>
<h2>404 - File or directory not found.</h2>
<h3>The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.</h3>
</fieldset></div>
</div>
</body>
</html>
{"url":"https://advice.newable.io","input":[],"userId":null,"email":null,"exception":"[object] (DocuSign\\eSign\\Client\\ApiException(code: 404): Error while requesting server, received a non successful HTTP code [404] with response Body: <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\">
<head>
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\"/>
<title>404 - File or directory not found.</title>
<style type=\"text/css\">
<!--
body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}
fieldset{padding:0 15px 10px 15px;}
h1{font-size:2.4em;margin:0;color:#FFF;}
h2{font-size:1.7em;margin:0;color:#CC0000;}
h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;}
#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:\"trebuchet MS\", Verdana, sans-serif;color:#FFF;
background-color:#555555;}
#content{margin:0 0 0 2%;position:relative;}
.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}
-->
</style>
</head>
<body>
<div id=\"header\"><h1>Server Error</h1></div>
<div id=\"content\">
<div class=\"content-container\"><fieldset>
<h2>404 - File or directory not found.</h2>
<h3>The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.</h3>
</fieldset></div>
</div>
</body>
</html>
at /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/docusign/esign-client/src/Client/ApiClient.php:330)
[stacktrace]
#0 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/docusign/esign-client/src/Api/EnvelopesApi.php(9328): DocuSign\\eSign\\Client\\ApiClient->callApi('/v2/accounts/50...', 'GET', Array, '', Array, '\\\\DocuSign\\\\eSign...', '/v2/accounts/{a...')
#1 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/docusign/esign-client/src/Api/EnvelopesApi.php(9208): DocuSign\\eSign\\Api\\EnvelopesApi->listStatusChangesWithHttpInfo('509375162', Object(DocuSign\\eSign\\Api\\EnvelopesApi\\ListStatusChangesOptions))
#2 [internal function]: DocuSign\\eSign\\Api\\EnvelopesApi->listStatusChanges('509375162', Object(DocuSign\\eSign\\Api\\EnvelopesApi\\ListStatusChangesOptions))
#3 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/tucker-eric/docusign-rest-client/src/Api/BaseApi.php(76): call_user_func_array(Array, Array)
#4 /homepages/45/d641872465/htdocs/sites/ita-portal/app/Jobs/PollDocuSignEnvelopes.php(107): DocuSign\\Rest\\Api\\BaseApi->__call('listStatusChang...', Array)
#5 [internal function]: App\\Jobs\\PollDocuSignEnvelopes->handle()
#6 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(32): call_user_func_array(Array, Array)
#7 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/Util.php(37): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#8 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(90): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#9 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(34): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#10 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/Container.php(590): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#11 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(94): Illuminate\\Container\\Container->call(Array)
#12 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(130): Illuminate\\Bus\\Dispatcher->Illuminate\\Bus\\{closure}(Object(App\\Jobs\\PollDocuSignEnvelopes))
#13 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(105): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(App\\Jobs\\PollDocuSignEnvelopes))
#14 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(98): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#15 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(83): Illuminate\\Bus\\Dispatcher->dispatchNow(Object(App\\Jobs\\PollDocuSignEnvelopes), false)
#16 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(130): Illuminate\\Queue\\CallQueuedHandler->Illuminate\\Queue\\{closure}(Object(App\\Jobs\\PollDocuSignEnvelopes))
#17 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(105): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(App\\Jobs\\PollDocuSignEnvelopes))
#18 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(85): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#19 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(59): Illuminate\\Queue\\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\\Queue\\Jobs\\DatabaseJob), Object(App\\Jobs\\PollDocuSignEnvelopes))
#20 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(88): Illuminate\\Queue\\CallQueuedHandler->call(Object(Illuminate\\Queue\\Jobs\\DatabaseJob), Array)
#21 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(368): Illuminate\\Queue\\Jobs\\Job->fire()
#22 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(314): Illuminate\\Queue\\Worker->process('database', Object(Illuminate\\Queue\\Jobs\\DatabaseJob), Object(Illuminate\\Queue\\WorkerOptions))
#23 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(134): Illuminate\\Queue\\Worker->runJob(Object(Illuminate\\Queue\\Jobs\\DatabaseJob), 'database', Object(Illuminate\\Queue\\WorkerOptions))
#24 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(112): Illuminate\\Queue\\Worker->daemon('database', 'default', Object(Illuminate\\Queue\\WorkerOptions))
#25 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(96): Illuminate\\Queue\\Console\\WorkCommand->runWorker('database', 'default')
#26 [internal function]: Illuminate\\Queue\\Console\\WorkCommand->handle()
#27 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(32): call_user_func_array(Array, Array)
#28 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/Util.php(37): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#29 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(90): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#30 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(34): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#31 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Container/Container.php(590): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#32 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Console/Command.php(134): Illuminate\\Container\\Container->call(Array)
#33 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/symfony/console/Command/Command.php(255): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#34 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Console/Command.php(121): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#35 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/symfony/console/Application.php(1005): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#36 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/symfony/console/Application.php(271): Symfony\\Component\\Console\\Application->doRunCommand(Object(Illuminate\\Queue\\Console\\WorkCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#37 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/symfony/console/Application.php(147): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#38 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Console/Application.php(93): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#39 /homepages/45/d641872465/htdocs/sites/ita-portal/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(131): Illuminate\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#40 /homepages/45/d641872465/htdocs/sites/ita-portal/artisan(37): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#41 {main}
"}

How can I debug this?

(I have an identical setup in a DocuSign Sandox and it works as expected).

enter image description here

1
If I had to guess, I'll say you may have reached your hourly API limit. Polling is not a recommended approach. If this still happens at the top of the hour, you may want to provide API logsInbar Gazit

1 Answers

2
votes

The only reason I'm aware of that this call in particular returns a 404 response is if the request includes a specific list of envelopeIds over a certain number. The older versions of our SDKs and a lot of customer solutions add these envelopeIds to the request in the form of URL Parameters. I found when testing this that when I approached or went over ~49 envelopes the response changed from a 200 to a 404.

Looking at the provided code I see this:

// Only do anything if there are envelopes
if ($envelopeIds) {
    $options = $client->envelopes->listStatusChangesOptions([
        'count' => 25,
        'envelope_ids' => $envelopeIds,
    ]);

$changes = $client->envelopes->listStatusChanges($options);

Can you confirm the total number of envelopes being included here? If the number is ~49 that is likely the culprit, meaning you'll need to add in an extra check to limit the total number of envelopeIds being passed into the listStatusChangesOptions object.