Php 使用docusignrestapi时获得404

Php 使用docusignrestapi时获得404,php,laravel,docusignapi,Php,Laravel,Docusignapi,在我的Laravel应用程序中,我将随此软件包一起发送DocuSign信封:效果很好 此应用程序还使用“轮询”方法检查信封的更改 为了实现这一点,我从各种不同的模型中获取信封ID,然后将这些ID传递给DocuSign的listStatusChanges()方法,该方法需要检查数量和信封ID数组 如果状态返回为已完成,我将使用另一种方法getDocument()下载已签名的文档 这是每15分钟运行一次的作业 <?php namespace App\Jobs; use App\Compa

在我的Laravel应用程序中,我将随此软件包一起发送DocuSign信封:效果很好

此应用程序还使用“轮询”方法检查信封的更改

为了实现这一点,我从各种不同的模型中获取信封ID,然后将这些ID传递给DocuSign的
listStatusChanges()
方法,该方法需要检查数量和信封ID数组

如果状态返回为已完成,我将使用另一种方法
getDocument()
下载已签名的文档

这是每15分钟运行一次的作业


<?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);
    }
}



我知道这个调用返回404响应的唯一原因是,如果请求包含特定数量的信封ID的特定列表。我们的SDK的旧版本和许多客户解决方案以URL参数的形式将这些信封ID添加到请求中。我在测试时发现,当我接近或超过49个信封时,响应从200变为404

查看提供的代码,我看到以下内容:

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

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

你能确认这里包含的信封总数吗?如果号码是49,那很可能就是凶手,这意味着您需要添加一个额外的检查,以限制传递到listStatusChangesOptions对象的信封ID的总数。

我知道此调用返回404响应的唯一原因是,如果请求包含超过特定数量的信封ID的特定列表。我们的SDK的旧版本和许多客户解决方案以URL参数的形式将这些信封ID添加到请求中。我在测试时发现,当我接近或超过49个信封时,响应从200变为404

查看提供的代码,我看到以下内容:

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

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

你能确认这里包含的信封总数吗?如果数字为~49,则可能是罪魁祸首,这意味着您需要添加一个额外的检查,以限制传递到listStatusChangesOptions对象的信封ID总数。

如果必须猜测,我会说您可能已达到每小时API限制。轮询不是推荐的方法。如果这仍然发生在一个小时的顶端,你可能想提供API日志如果我不得不猜测,我会说你可能已经达到了你的每小时API限制。轮询不是推荐的方法。如果这仍然发生在一个小时的顶端,你可能想提供API日志你认为API中没有提到这一点,因为它应该是一个给定的吗?这是一个公平的问题。我的理解是,URL长度通常应限制为~2000(2048)个字符,因为这是某些web浏览器的默认值。例如,IE的默认限制为2048。看看这里,我发现了一个关于URL限制标准的非常可靠的解释:你认为API中没有提到这一点,因为它应该是给定的吗?这是一个公平的问题。我的理解是,URL长度通常应限制为~2000(2048)个字符,因为这是某些web浏览器的默认值。例如,IE的默认限制为2048。看看这里,我发现了关于URL限制标准的一个非常可靠的解释: