What is the process for authenticating and sending a click conversion to Google Ads using a service account and the REST API with TypeScript?

I have attempted to authenticate using this documentation and to send conversions via REST API using this REST endpoint due to the absence of a Typescript/Javascript Client Library.

However, I am encountering authentication issues. Once resolved, I aim to successfully send click conversions. Should my assumptions be incorrect, I have elaborated on my questions here. I hope the query is not too extensive. Feel free to correct me if I am mistaken.

The error I am facing can be seen here.

Configuration Overview: As per the provided guide, I have a Google Ads account with a developer token which will be utilized for sending click conversions, as demonstrated here. This token does not affect service account authentication. Hence, I have set up a service account within the Google Cloud Project with Google Ads Api enabled. This includes adding the client ID of the service account to domain-wide delegation with scope , resulting in an entry under APIs & Services as an OAuth 2.0 Client IDs. Details about this setup are here.

In addition, I have included the workspace domain in domain wide delegation and configured the OAuth consent screen with scope in Testing status with external access, although it may not be necessary for a service account.

The service account itself does not require any further permissions according to the documentation, suggesting that adding the client ID to domain wide delegation should suffice. However, I acknowledge the possibility of missing a crucial step.

Potential Issues: There could be insufficient permissions or a misunderstanding regarding the refresh token in the authenticateToGoogleAdsManager function. The JWT generated is based on Google's recommendation, yet the authentication process only returns an access token without a refresh token as anticipated.

This code snippet showcases how I execute the functions (within a test case environment, using Service Account JSON and pre-defined click conversion data).


// Generating a signed JWT
const jwt = generateJsonWebTokenForServiceAccount(
serviceAccount,
['https://www.googleapis.com/auth/adwords'],
'googleads'
)

// Authenticating to Google Ads Manager using the signed JWT
const authenticationResult = await authenticateToGoogleAdsManager(
serviceAccount.client_id,
serviceAccount.private_key,
jwt
)

console.log(authenticationResult)

// Sending the click conversion to Google Ads Manager using the access token
const test = await sendClickConversionToGoogleAdsManager(
CUSTOMERID,
clickConversion,
accessToken.access_token,
'DEV-TOKEN'
)

Below are the key functions used in the implementation:


/**
* Function to generate a JSON Web Token (JWT) for a service account.
*/
export function generateJsonWebTokenForServiceAccount(
serviceAccount: ServiceAccount,
scopes: string[],
serviceName: string = 'oauth2',
expirationTimeInSeconds = 3600
) {
...
}

/**
* Function to authenticate to Google Ads Manager using provided credentials.
*/
export async function authenticateToGoogleAdsManager(
clientId: string,
clientSecret: string,
refreshToken: string
): Promise<string> {
...
}

/**
* Function to send a click conversion to Google Ads Manager.
*/
export async function sendClickConversionToGoogleAdsManager(
customerId: number,
clickConversion: ClickConversion,
accessToken: string,
developerToken: string,
options?: ApiOptions
): Promise<void> {
...
}

Answer №1

After consulting with the Google Ads API Support team, I was advised to generate a refresh token using a google user through the console. The google user needs to be associated with the google ads manager account. Subsequently, we utilize the refresh token for authentication purposes in the google ads manager by following the steps outlined in the method authenticateToGoogleAdsManager.

Unfortunately, they did not provide me with a solution involving the service account.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Decoding the HTML5 <video> tag using the html-react-parser library

I'm working on a NextJS V13 app where I need to display HTML content fetched from a CMS. Instead of using dangerouslySetHtml, I opted for the html-react-parser package to parse the HTML and replace certain embedded tags like <a>, <img>, an ...

Show a message on form submission rather than redirecting

I'm working on a simple sign-up form and I want to show a success message directly on the page instead of redirecting to another page after submission. Is it better to display the message as a pop-up, an alert, or just on the page itself? <form a ...

"Combining the power of AngularJS2 beta with Spring Boot: the ultimate

I am currently using Atom 1.4.0 with the atom-typescript package to develop AngularJS2 modules in TypeScript. On the backend, I have a spring-boot application for handling the REST APIs. After making changes to the .ts files in Atom, it seems to compile t ...

Tips on how to implement code to pause execution while making asynchronous requests such as Ajax and capturing the returned results

After doing a lot of research on this topic, it seems like nobody else is facing the same issue as me. In my main code, I have the following: // getHtmlInfoWindows contains an ajax request var infowindowString = getHtmlInfoWindow(selectedTrucks[i], true ...

What is the best way to integrate a new unique identifier into an existing MongoDB document using NodeJS?

I am looking to add up a field in a document when I input a new entry that has a replicated unique id. This is the code I have so far: MongoClient.connect(process.env.MONGODB_URI || process.env.DB_CONNECTION, { useUnifiedTopology: true, useNewUrlParser ...

Numerous JSON entities

Curious to know if it's achievable to load more than one JSON file with just a single jQuery.ajax() call. Or do I have to make separate calls for each file? Warm regards, Smccullough ...

Troubleshooting: The issue with json_encode in Ajax calls

I am facing an issue with my ajax call and the json response. The console is indicating that my php file is not returning a json format, but I am unable to pinpoint the exact reason behind it. Below is my ajax function: function showEspece(espece, categori ...

What is the best way to combine a string that is constructed across two separate callback functions using Mongoose in Node.js?

I am facing a situation where I have two interconnected models. When deleting a mongo document from the first model, I also need to delete its parent document. There is a possibility of an exception being thrown during the second deletion process. Regardl ...

Is nesting directives possible within AngularJS?

Having trouble creating a Directive that includes another directive from the AngularJS UI. Check out my html: <div class="col-md-12" ng-show="continent == '2'"> <my-rating></my-rating> </div> Here is the directiv ...

Tips for keeping several buttons in the spotlight: HTML/CSS/JS

Looking for a solution to keep multiple buttons toggled on? I'm not very familiar with JavaScript, but I know that adding a class on click won't work if there's already a class set. Maybe giving the element an ID could be a possible solution ...

Creating a class that can be easily mocked for connecting to mongoDB

I've been attempting to develop a class that connects to MongoDB (and accesses a gridFS connection using gridfs-stream). However, I have encountered two specific problems: Sometimes, I receive the mongo Error server instance in invalid state connect ...

PapaParse is not properly recognizing the date format

Having trouble creating a chart using JSON data from papaparse, resulting in the following error: c3.js:2100 Failed to parse x '10-18-2018' to Date object I've tried adjusting the date format in the CSV file but haven't had any luck. I ...

Automatic Slideshow

I am trying to implement autoplay in my slider, but I am having trouble figuring out how to do it. The slider itself is working fine, but I know that I need to use an interval for the autoplay feature. If anyone could provide some assistance on how to ac ...

Troubleshooting: JSColor Is Failing to Function Properly in Volusion's

Recently, I've encountered some issues with the JSColor plugin () on the Volusion e-commerce platform. Despite having successfully used it before, getting it to load correctly seems to be a challenge. My current task involves working on a test produc ...

Implementing location functionality in Nextjs 13+ for both server-side rendering and client-side components

I need help displaying an active link in the header navigation. Previously, I used useRoute() for versions under 13, but it stopped working in version 13 and above. Additionally, useRoute is not mounted when using SSR. To work around this issue, I ensured ...

What is the best method for securely storing and managing refresh and access tokens within a node.js application?

Currently, I am working with next.js and I am looking for a way to persist an API refresh token without using a database in my application. What would be the recommended practice for storing this token securely so that it can be updated as needed? Storin ...

Exploring ways to analyze data that shares similarities within a JSON object document

I'm currently working on an application to detect duplicate and unique data within a JSON file. My goal is to accurately count the number of unique records present. Within the JSON object, there are numerous first and last names. My aim is to not onl ...

Converting JSON data from ASP.NET MVC to a Canvas.js chart

Despite my efforts to find a solution by looking through similar posts, I am unable to resolve the issue. Within my asp.net MVC controller, I have a method called public object OfferChart() List<Det> obj = new List<Det>(); foreach ...

Utilize an imported function within a React component's return statement to avoid an invalid hook call issue

Hey everyone, I've created a reusable component that can translate keys into a chosen language using keynames as strings or variables. Typically, I would use a <t> tag for this purpose, but due to certain reasons, I am replacing current transl ...

How can we effectively test arrow functions in unit tests for Angular development?

this.function = () => { -- code statements go here -- } I am looking to write jasmine unit tests in Angular for the function above. Any suggestions on how to achieve this? it("should call service",()=>{ // I want to invoke the arrow funct ...