Docusign single signer but multiple signatures on document - php

I am using Docusign php api. I am signing the document by this api . everything is fine . But now i need signatures of recipients at multiple places. I don't know how many times i need the signature , Even i don't know the position where i need the signature tab , I just have a placeholder in the html doc and that is #\b . I have to put signature tab where is #\b
// create a new DocuSign configuration and assign host and header(s)
$config = new DocuSign\eSign\Configuration();
$config->setHost($host);
$config->addDefaultHeader("X-DocuSign-Authentication", "{\"Username\":\"" . $username . "\",\"Password\":\"" . $password . "\",\"IntegratorKey\":\"" . $integrator_key . "\"}");
/////////////////////////////////////////////////////////////////////////
// STEP 1: Login() API
/////////////////////////////////////////////////////////////////////////
// instantiate a new docusign api client
$apiClient = new DocuSign\eSign\ApiClient($config);
// we will first make the Login() call which exists in the AuthenticationApi...
$authenticationApi = new DocuSign\eSign\Api\AuthenticationApi($apiClient);
// optional login parameters
$options = new \DocuSign\eSign\Api\AuthenticationApi\LoginOptions();
// call the login() API
$loginInformation = $authenticationApi->login($options);
// parse the login results
if(isset($loginInformation) && count($loginInformation) > 0)
{
// note: defaulting to first account found, user might be a
// member of multiple accounts
$loginAccount = $loginInformation->getLoginAccounts()[0];
if(isset($loginInformation))
{
$accountId = $loginAccount->getAccountId();
}
}
if(empty($accountId))
{
return false;
}
/////////////////////////////////////////////////////////////////////////
// STEP 2: Create & Send Envelope (aka Signature Request)
/////////////////////////////////////////////////////////////////////////
// set recipient information
// instantiate a new envelopeApi object
$envelopeApi = new DocuSign\eSign\Api\EnvelopesApi($apiClient);
// Add a document to the envelope
$document = new DocuSign\eSign\Model\Document();
$document->setDocumentBase64(base64_encode(file_get_contents($documentFileName)));
$document->setName($documentName);
$document->setDocumentId("1");
// Create a |SignHere| tab somewhere on the document for the recipient to sign
$signHere = new \DocuSign\eSign\Model\SignHere();
$signHere->setXPosition("20");
$signHere->setYPosition("20");
$signHere->setDocumentId("1");
$signHere->setPageNumber("1");
$signHere->setRecipientId("1");
// add the signature tab to the envelope's list of tabs
$tabs = new DocuSign\eSign\Model\Tabs();
$tabs->setSignHereTabs(array($signHere));
// add a signer to the envelope
$signer = new \DocuSign\eSign\Model\Signer();
$signer->setEmail($recipientEmail);
$signer->setName($recipientName);
$signer->setRecipientId("1");
$signer->setClientUserId('12345');
$signer->setTabs($tabs);
// Add a recipient to sign the document
$recipients = new DocuSign\eSign\Model\Recipients();
$recipients->setSigners(array($signer));
$envelop_definition = new DocuSign\eSign\Model\EnvelopeDefinition();
$envelop_definition->setEmailSubject("Please sign this doc");
// set envelope status to "sent" to immediately send the signature request
$envelop_definition->setStatus("sent");
$envelop_definition->setRecipients($recipients);
$envelop_definition->setDocuments(array($document));
// create and send the envelope! (aka signature request)
$envelop_summary = $envelopeApi->createEnvelope($accountId, $envelop_definition, null);
if($envelop_summary)
{
$document=json_decode($envelop_summary);
$envloped=$document->envelopeId;
// get the document url
$ReturnUrl=add_query_arg(array('action'=>'docusign_request','_uid'=>$formprocess,'_envelopid'=>$envloped),get_permalink());
$viewrequest = new DocuSign\eSign\Model\RecipientViewRequest();
$viewrequest->setUserName($recipientName);
$viewrequest->setEmail($recipientEmail);
$viewrequest->setRecipientId(1);
$viewrequest->setClientUserId('12345');
$viewrequest->setAuthenticationMethod('email');
$viewrequest->setReturnUrl($ReturnUrl);
$envelopview=$envelopeApi->createRecipientView($accountId,$document->envelopeId,$viewrequest);
$redirecturl=$envelopview->getUrl();
wp_redirect($redirecturl);
// get the doc url
}

You should be using Docusign Anchor tabs for this purpose
https://github.com/docusign/docusign-soap-sdk/wiki/Code-Walkthrough-_-Anchor-Tabs
Anchor Tabs are a solution for this. Since an Anchor Tab works by matching a string that is present in the document’s text, we would just need to examine the document and see if there is a suitable bit of text. Many contracts have something like “Sign Here” printed on the document, so we could use that as the anchor text, and then DocuSign would place a Signature Tab on the document everywhere it finds the text “Sign Here”.
// Create a |SignHere| tab somewhere on the document for the recipient to sign
$signHere = new \DocuSign\eSign\Model\SignHere();
$signHere->setDocumentId("1");
$signHere->setPageNumber("1");
$signHere->setRecipientId("1");
$signHere->AnchorTabItem->AnchorTabString = "#\b";
$signHere->AnchorTabItem->Unit = "Pixels";
$signHere->AnchorTabItem->XOffset = 50;
$signHere->AnchorTabItem->YOffset = 100;
$signHere->AnchorTabItem->IgnoreIfNotPresent = true;

Related

Why has DocuSign EventNotification stopped working?

In 2017 I integrated DocuSign with a website using the Official DocuSign PHP Client (https://github.com/docusign/docusign-php-client).
I took the example code and modified it so that it registered an EventNotification which would call back to the website once the signing process is complete. Code below.
require_once('docusign-php-client/autoload.php');
$username = "XXXXX";
$password = "XXXXX";
$integrator_key = "XXXXX";
// change to production (www.docusign.net) before going live
$host = "https://www.docusign.net/restapi";
// create configuration object and configure custom auth header
$config = new DocuSign\eSign\Configuration();
$config->setHost($host);
$config->addDefaultHeader("X-DocuSign-Authentication", "{\"Username\":\"" . $username . "\",\"Password\":\"" . $password . "\",\"IntegratorKey\":\"" . $integrator_key . "\"}");
// instantiate a new docusign api client
$apiClient = new DocuSign\eSign\Client\ApiClient($config);
$accountId = null;
try {
//*** STEP 1 - Login API: get first Account ID and baseURL
$authenticationApi = new DocuSign\eSign\Api\AuthenticationApi($apiClient);
$options = new \DocuSign\eSign\Api\AuthenticationApi\LoginOptions();
$loginInformation = $authenticationApi->login($options);
if (isset($loginInformation) && count($loginInformation) > 0) {
$loginAccount = $loginInformation->getLoginAccounts()[0];
$host = $loginAccount->getBaseUrl();
$host = explode("/v2", $host);
$host = $host[0];
// UPDATE configuration object
$config->setHost($host);
// instantiate a NEW docusign api client (that has the correct baseUrl/host)
$apiClient = new DocuSign\eSign\Client\ApiClient($config);
if (isset($loginInformation)) {
$accountId = $loginAccount->getAccountId();
if (!empty($accountId)) {
//*** STEP 2 - Signature Request from a Template
// create envelope call is available in the EnvelopesApi
$envelopeApi = new DocuSign\eSign\Api\EnvelopesApi($apiClient);
// assign recipient to template role by setting name, email, and role name. Note that the
// template role name must match the placeholder role name saved in your account template.
$templateRole = new DocuSign\eSign\Model\TemplateRole();
$templateRole->setEmail($vars['client_email']['value']);
//$templateRole->setEmail("robbielewis#me.com");
$templateRole->setName($vars['client_name']['value']);
$templateRole->setRoleName("Signee");
// pre-populate text tabs
$tabFields = array();
foreach ($vars as $var) {
$tabField = new \DocuSign\eSign\Model\Text();
$tabField->setTabLabel($var['label']);
$tabField->setValue($var['value']);
$tabFields[] = $tabField;
}
$tabs = new DocuSign\eSign\Model\Tabs();
$tabs->setTextTabs($tabFields);
$templateRole->setTabs($tabs);
// create event notification webhook
$envelope_events = [
(new \DocuSign\eSign\Model\EnvelopeEvent())->setEnvelopeEventStatusCode("sent"),
(new \DocuSign\eSign\Model\EnvelopeEvent())->setEnvelopeEventStatusCode("delivered"),
(new \DocuSign\eSign\Model\EnvelopeEvent())->setEnvelopeEventStatusCode("completed"),
(new \DocuSign\eSign\Model\EnvelopeEvent())->setEnvelopeEventStatusCode("declined"),
(new \DocuSign\eSign\Model\EnvelopeEvent())->setEnvelopeEventStatusCode("voided"),
(new \DocuSign\eSign\Model\EnvelopeEvent())->setEnvelopeEventStatusCode("sent"),
(new \DocuSign\eSign\Model\EnvelopeEvent())->setEnvelopeEventStatusCode("sent")
];
$recipient_events = [
(new \DocuSign\eSign\Model\RecipientEvent())->setRecipientEventStatusCode("Sent"),
(new \DocuSign\eSign\Model\RecipientEvent())->setRecipientEventStatusCode("Delivered"),
(new \DocuSign\eSign\Model\RecipientEvent())->setRecipientEventStatusCode("Completed"),
(new \DocuSign\eSign\Model\RecipientEvent())->setRecipientEventStatusCode("Declined"),
(new \DocuSign\eSign\Model\RecipientEvent())->setRecipientEventStatusCode("AuthenticationFailed"),
(new \DocuSign\eSign\Model\RecipientEvent())->setRecipientEventStatusCode("AutoResponded")
];
$event_notification = new \DocuSign\eSign\Model\EventNotification();
$event_notification->setUrl("https://www.XXXXX.com/wp-content/plugins/XXXXX/XXXXX.php?action=docusign-callback");
$event_notification->setLoggingEnabled("true");
$event_notification->setRequireAcknowledgment("true");
$event_notification->setUseSoapInterface("false");
$event_notification->setIncludeCertificateWithSoap("false");
$event_notification->setSignMessageWithX509Cert("false");
$event_notification->setIncludeDocuments("true");
$event_notification->setIncludeEnvelopeVoidReason("true");
$event_notification->setIncludeTimeZone("true");
$event_notification->setIncludeSenderAccountAsCustomField("true");
$event_notification->setIncludeDocumentFields("true");
$event_notification->setIncludeCertificateOfCompletion("true");
$event_notification->setEnvelopeEvents($envelope_events);
$event_notification->setRecipientEvents($recipient_events);
// instantiate a new envelope object and configure settings
$envelop_definition = new DocuSign\eSign\Model\EnvelopeDefinition();
$envelop_definition->setEmailSubject("Please review and sign your booking contract");
$envelop_definition->setTemplateId("XXXXX");
$envelop_definition->setTemplateRoles(array($templateRole));
$envelop_definition->setEventNotification($event_notification);
// set envelope status to "sent" to immediately send the signature request
$envelop_definition->setStatus("sent");
// optional envelope parameters
$options = new \DocuSign\eSign\Api\EnvelopesApi\CreateEnvelopeOptions();
$options->setCdseMode(null);
$options->setMergeRolesOnDraft(null);
// create and send the envelope (aka signature request)
$envelop_summary = $envelopeApi->createEnvelope($accountId, $envelop_definition, $options);
if (!empty($envelop_summary)) {
echo "Contract sent at " . date('d/m/Y H:i:s') .' to '.$templateRole->getEmail();
}
}
}
}
} catch (DocuSign\eSign\ApiException $ex) {
echo "Exception: " . $ex->getMessage() . "\n";
file_put_contents('XXXXX.log', "\n\n" . date('d/m/Y H:i:s') . ' - Docusign API error ' . $ex->getMessage(), FILE_APPEND);
wp_mail('XXXXX', 'Docusign API error', date('d/m/Y H:i:s') . ' - Docusign API error: ' . $ex->getMessage());
}
This worked fine for a couple of years until recently we stopped getting the EventNotification request to our server from Docusign when the envelope is signed. The envelope is still created successfully and sent to the recipient.
Things I have tried to resolve the issue:
Created many test envelopes using my script and signed them
Monitored the access logs on the server for any http requests following the signing of an envelope that was created by the script, nothing received
Updated the DocuSign PHP Client to the latest version
Enabled logging in DocuSign and checked that the EventNotification request is being received by DocuSign when the envelope is created, see here: https://pastebin.com/xbS338Hx
Contacted my host to ensure that there is no hardware firewall that could be preventing the server receiving HTTP requests from DocuSign
Turned off Cloudflare DNS proxy to make sure that it isn't blocking the request to the server
Contacted DocuSign Support who said to post here as they cannot provide assistance with code issues.
What else can I try to pinpoint the cause of this issue?
Using DocuSign Connect Failures screen in DocuSign Admin I was able to see failed connections in the list.
https://www.XXXXX.com/wp-content/plugins/sXXXXX/XXXXX.php?action=docusign-callback :: Error - The remote server returned an error: (403) Forbidden.
It turned out to be iThemes Security Plugin for Wordpress denying the requests. I disabled the plugin and republished the most recent failed request in DocuSign Admin. The request came through successfully.

Making the DocuSign API transition from sandbox to live

I integrated the PHP API for DocuSign by creating a sandbox account, downloading the php sample and placing the correct credentials in, testing (which worked as expected) and then ran through the live process of 20 transactions, having an enterprise account, etc. All was approved and everything seemed in order according to the admin panel, but making the changes documented in the go live docs just results in a server 500 error. Anyone else experienced this? Maybe some part of the live transition escaped me?
The code below should return login info:
// DocuSign account credentials & Integrator Key
$username = "someemail#somewhere.com"; //or the account string
$password = "xxxxx";
$integrator_key = "abc-123";
$host = "https://demo.docusign.net/restapi";
// create a new DocuSign configuration and assign host and header(s)
$config = new DocuSign\eSign\Configuration();
$config->setHost($host);
$config->addDefaultHeader("X-DocuSign-Authentication", "{\"Username\":\"" . $username . "\",\"Password\":\"" . $password . "\",\"IntegratorKey\":\"" . $integrator_key . "\"}");
/////////////////////////////////////////////////////////////////////////
// STEP 1: Login() API
/////////////////////////////////////////////////////////////////////////
// instantiate a new docusign api client
$apiClient = new DocuSign\eSign\ApiClient($config);
// we will first make the Login() call which exists in the AuthenticationApi...
$authenticationApi = new DocuSign\eSign\Api\AuthenticationApi($apiClient);
// optional login parameters
$options = new \DocuSign\eSign\Api\AuthenticationApi\LoginOptions();
// call the login() API
$loginInformation = $authenticationApi->login($options);
// parse the login results
if(isset($loginInformation) && count($loginInformation) > 0)
{
// note: defaulting to first account found, user might be a
// member of multiple accounts
$loginAccount = $loginInformation->getLoginAccounts()[0];
if(isset($loginInformation))
{
$accountId = $loginAccount->getAccountId();
if(!empty($accountId))
{
echo "Account ID = $accountId\n";
// works as expected
}
}
}
Now, try the same thing using the live URL and credentials as suggested by the go live docs here:
$username = "live-user-account"; <--- live username or email
$password = "xxxxx"; <--- live pw
$integrator_key = "abc-123"; <--- same integrator key
$host = "https://www.docusign.net/restapi/v2/login_information"; <--- live URL
All I get is a server 500 error. I tried with just https://www.docusign.net/restapi and same thing. Server 500 error.
Is there some part of the go live process I overlooked?
Side note - this is attached to an enterprise level account
Ok so get ready for an idiotic ride....
Another stack overflow post answers this here, but I will skip to the actual answer found here
Basically - you have to redefine the $apiClient variable by calling back the api with returned info...
$username = "xxx-xx-xxxx"; <--- your username string or email
$password = "xxxxx"; <--- your password
$integrator_key = "aaa-bbb-ccc"; <--- your integrator key
$host = "https://www.docusign.net/restapi"; <--- LIVE url
// create a new DocuSign configuration and assign host and header(s)
$config = new DocuSign\eSign\Configuration();
$config->setHost($host);
$config->addDefaultHeader("X-DocuSign-Authentication", "{\"Username\":\"" . $username . "\",\"Password\":\"" . $password . "\",\"IntegratorKey\":\"" . $integrator_key . "\"}");
/////////////////////////////////////////////////////////////////////////
// STEP 1: Login() API
/////////////////////////////////////////////////////////////////////////
// instantiate a new docusign api client
$apiClient = new DocuSign\eSign\ApiClient($config);
// we will first make the Login() call which exists in the AuthenticationApi...
$authenticationApi = new DocuSign\eSign\Api\AuthenticationApi($apiClient);
// optional login parameters
$options = new \DocuSign\eSign\Api\AuthenticationApi\LoginOptions();
// call the login() API
$loginInformation = $authenticationApi->login($options);
// parse the login results
if(isset($loginInformation) && count($loginInformation) > 0)
{
// note: defaulting to first account found, user might be a
// member of multiple accounts
$loginAccount = $loginInformation->getLoginAccounts()[0];
if(isset($loginInformation))
{
$accountId = $loginAccount->getAccountId();
// HERE is where we all go wrong
$host = $loginAccount->getBaseUrl();
$host = explode("/v2",$host);
$host = $host[0];
// UPDATE configuration object and then re-call the api client
$config->setHost($host);
$apiClient = new DocuSign\eSign\ApiClient($config);
if(!empty($accountId))
{
//echo "Account ID = $accountId\n";
}
}
}
Then poof, your envelope calls will magically work after that...
This is one FUGLY implementation of a sandbox -> live process. We got some great PHP sample for sandbox but then no connected real world examples of how you have to change things around in the live environment. Yes, we get that live can differ, but just leave this one small piece commented in the php sample and say "when going live, uncomment this" ... Literally nothing else in the code is different other than the login creds.
simple as that.
It kind of makes the sandbox pointless since I now have to re-test everything to make sure this live code is stable.
Thank you support for trying.

How to re-initialize the Docusign PHP API with different credentials

We have a case where we need to check envelope status in two separate Docusign accounts. If we don't get status in the first, we want to check the second.
I'm having trouble getting the API to re-initialize with the credentials of our second account. I'm calling this snippet with the new variables:
require_once('docusign/SignatureApi.php');
$IntegratorsKey = "abcd";
$UserID = "dave#account.com";
$Password = "xxxxx";
$_apiEndpoint = $Endpoint;
$_apiWsdl = "docusign/api/APIService.wsdl";
$api_options = array('location'=>$_apiEndpoint,'trace'=>true,'features' => SOAP_SINGLE_ELEMENT_ARRAYS);
$api = new APIService($_apiWsdl, $api_options);
$api->setCredentials("[" . $IntegratorsKey . "]" . $UserID, $Password);
$res = RequestEnvelopStatuses($envelopes);
$envelopeStatuses = $res->RequestStatusesResult;
if(!count($envelopeStatuses->EnvelopeStatuses->EnvelopeStatus)){
// If we did not find envelopes, check other account
$IntegratorsKey = "wxyz";
$UserID = "fred#altaccount.com";
$Password = "xxxxx";
$api->setCredentials("[" . $IntegratorsKey . "]" . $UserID, $Password);
// retry request
$res = RequestEnvelopStatuses($envelopes);
$envelopeStatuses = $res->RequestStatusesResult;
}
It doesn't return an error, but won't return envelope status either. It seems to still use the first credentials (guessing). The second attempt always seems to return whatever the first attempt did.
Is there a better / preferred way to do this?
That does not look like the proper way to get the envelope status. Maybe that's why you are not finding them and trying to look again?
// Create a filter using account ID and today as a start time
$envStatusFilter = new EnvelopeStatusFilter();
$envStatusFilter->AccountId = $AccountID;
$beginDateTime = new EnvelopeStatusFilterBeginDateTime();
$beginDateTime->_ = todayXsdDate(); // note that this helper function
// is in CodeSnippets/include/utils.php
// in the PHP SDK
$envStatusFilter->BeginDateTime = $beginDateTime;
// Send
$requestStatusesparams = new RequestStatuses();
$requestStatusesparams->EnvelopeStatusFilter = $envStatusFilter;
$response = $api->RequestStatuses($requestStatusesparams);

Drupal 7 Not Recognizing Twilio Client in Custom Module

I have a Twilio account and I am writing a mass text message module for my Drupal site. At the beginning of the module I have set up the Twilio client with the following code:
$path = drupal_get_path("library", "twilio");
require($path . "twilio/Services/Twilio.php");
$accountSID = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$authToken = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$client = new Services_Twilio($accountSID, $authToken);
$from = "xxxxxxxxxx";
The myModule_submit() queries the database for phone numbers and sends them out via the Twilio PHP libraries referenced above. I am using code found on the Twilio site for something similar here(http://www.twilio.com/docs/howto/sms-notifications-and-alerts). The problem is when I fill in the forms for the SMS message to be sent out and press submit I get the following error message:
Notice: Undefined variable: client in myModule_submit() (line 128 of /var/www/erosas/anysite.com/sites/all/modules/myModule/myModule.module).
Notice: Trying to get property of non-object in myModule_submit() (line 128 of /var/www/erosas/anysite.com/sites/all/modules/myModule/myModule.module).
Notice: Trying to get property of non-object in myModule_submit() (line 128 of /var/www/erosas/anysite.com/sites/all/modules/myModule/myModule.module).
The submit function is:
function myModule_submit($form, &$form_state){
// Retrieve the values from the fields of the custom form
$values = $form_state['values'];
// Use Database API to retrieve current posts.
$query = db_select('field_data_field_phone_number', 'n');
$query->fields('n', array('field_phone_number_value'));
// Place queried data into an array
$phone_numbers = $query->execute();
$body = $values['sms_message'];
// Iterate over array and send SMS
foreach($phone_numbers as $number){
$client->account->sms_messages->create($from, $number, $body); // This is line 128
}
}
Any thoughts/help would be greatly appreciated, I tried searching this site and Google for an answer, but nothing specific to Drupal came up.
$client object is n/a to the submit function. Try putting the same code
$path = drupal_get_path("library", "twilio");
require($path . "twilio/Services/Twilio.php");
$accountSID = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$authToken = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$client = new Services_Twilio($accountSID, $authToken);
$from = "xxxxxxxxxx";
in the beginning of the submit function.
function pulsesurf_submit($form, &$form_state){
$path = drupal_get_path("library", "twilio");
require($path . "twilio/Services/Twilio.php");
$accountSID = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$authToken = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$client = new Services_Twilio($accountSID, $authToken);
$from = "xxxxxxxxxx";
// Retrieve the values from the fields of the custom form
$values = $form_state['values'];
// Use Database API to retrieve current posts.
$query = db_select('field_data_field_phone_number', 'n');
$query->fields('n', array('field_phone_number_value'));
// Place queried data into an array
$phone_numbers = $query->execute();
$body = $values['sms_message'];
// Iterate over array and send SMS
foreach($phone_numbers as $number){
$client->account->sms_messages->create($from, $number, $body); // This is line 128
}
...
Better making some include function without arguments the simply includes the library files and sets the tokens/sid for ease of use.
and btw, your site's domain is in the error message.

How can I tell the Google Adwords API which client/account in my MCC I am querying?

Using the latest PHP CLient Library (v2.6.3) I can't seem to figure out to get all campaigns for a client in my MCC (my client center) account.
I can easily get all accounts via:
$user = new AdWordsUser(NULL, $email, $password, $devToken, $applicationToken, $userAgent, NULL, $settingsFile);
$service = $user->GetServicedAccountService();
$selector = new ServicedAccountSelector();
$selector->enablePaging = false;
$graph = $service->get($selector);
$accounts = $graph->accounts; // all accounts!
Now that I've done that, I want to get all the campaigns within each account. Running the code as documented here doesn't work.
// Get the CampaignService.
// ** Different than example because example calls a private method ** //
$campaignService = $user->GetCampaignService('v201101');
// Create selector.
$selector = new Selector();
$selector->fields = array('Id', 'Name');
$selector->ordering = array(new OrderBy('Name', 'ASCENDING'));
// Get all campaigns.
$page = $campaignService->get($selector);
// Display campaigns.
if (isset($page->entries)) {
foreach ($page->entries as $campaign) {
print 'Campaign with name "' . $campaign->name . '" and id "'
. $campaign->id . "\" was found.\n";
}
}
All the above code will do is throw an error:
Fatal error: Uncaught SoapFault exception: [soap:Server]
QuotaCheckError.INVALID_TOKEN_HEADER # message=null
stack=com.google.ads.api.authserver.common.AuthException at
com.go;
I have a feeling that the reason this fails is that GetCampaignService needs an account's id...but I can't figure out how to specify this id.
What am I doing wrong?
The problem ended up being that I was given the wrong developerToken. I didn't think INVALID_TOKEN_HEADER really meant what it said because SOME calls still worked with the faulty token. I don't know why.

Categories