Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New format google ads #3526

Merged
merged 50 commits into from
Jul 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
272f46c
Add basic layout with icon for Google Ads
cgobrech Feb 2, 2022
dffc2f6
Add node versioning(V1)
cgobrech Feb 2, 2022
2ed376b
Add node and credential to package
cgobrech Feb 2, 2022
e753b63
Add basic layout with icon for Google Ads
agobrech Feb 2, 2022
121459e
Add node versioning(V1)
agobrech Feb 2, 2022
18b2818
Add node and credential to package
agobrech Feb 2, 2022
322e6c8
Merge branch 'feature/n8n-2811-node-google-ads' of https://github.com…
agobrech Feb 2, 2022
283237e
Merge remote-tracking branch 'upstream/master' into feature/n8n-2811-…
agobrech Feb 2, 2022
73aea6c
Add api call to getall
agobrech Feb 2, 2022
6c26e8f
Fix formdata in the body for the request
agobrech Feb 7, 2022
3daa3bc
Merge remote-tracking branch 'upstream/master' into feature/n8n-2811-…
agobrech Feb 8, 2022
b0210fd
N8N-2928 Added custom queries to campaign
agobrech Feb 8, 2022
0e0034a
Fix header bug and add developer-token field
agobrech Feb 9, 2022
39413c1
Add operation and fields to campaign new format
agobrech Feb 10, 2022
132b62f
Add more configurations and queries
agobrech Feb 14, 2022
281b9f9
Merge remote-tracking branch 'upstream/master' into N8N-2929-Invoice-…
agobrech Feb 15, 2022
3f29521
Add Invoice ressources and operations
agobrech Feb 15, 2022
0f0f138
Remov old version from the node
agobrech Feb 15, 2022
e9219d6
Merge branch 'master' into N8N-2929-Invoice-ressource-google-ads
agobrech Feb 15, 2022
746fe89
Fixed bud with typo
agobrech Feb 15, 2022
72db837
Correctly prepends the baseURL
agobrech Feb 15, 2022
6165d73
Merge branch 'n8n-2969-bug-baseurl-ignored' into N8N-2929-Invoice-res…
agobrech Feb 16, 2022
6ef5577
add query to invocie request
agobrech Feb 16, 2022
a196184
Fixes header not parsing the expression
agobrech Feb 22, 2022
9f02299
Invoice param changes
agobrech Feb 22, 2022
cd1f638
Merge branch 'master' into N8N-2942-new-format-google-ads
agobrech Feb 22, 2022
3997111
Fixes bug related to headers not being parsed, and bug with auth
agobrech Feb 25, 2022
922fcea
Remove useless imports
agobrech Feb 25, 2022
ad58750
Added analytics to google ad node and removed useless header
agobrech Feb 25, 2022
28ab1a1
Removed url for testing
agobrech Feb 28, 2022
b8d630e
Fixed inconsistent behaviour with the access token not being refreshed
agobrech Mar 1, 2022
bcf85ff
Added placeholders to help user
agobrech Mar 1, 2022
314e882
Merge remote-tracking branch 'upstream/master' into N8N-2942-new-form…
agobrech Mar 1, 2022
3d8aa84
Removed useless comments
agobrech Mar 3, 2022
1af49f2
Resolved name confusion
agobrech Mar 3, 2022
b1a070c
Added support for body in a GET method
agobrech Mar 3, 2022
b7de188
Removed hyphens, parse body's expression
agobrech Mar 3, 2022
56b4fa6
Renamed operation for clarity
agobrech Mar 3, 2022
086d536
Remove unused code
agobrech Mar 3, 2022
d8abce4
Removed invoice resource and fixed bug with body and headers
krynble Mar 22, 2022
49d3080
Improve campagin operation and remove analytics; fix tests
krynble Jun 16, 2022
07f042f
Merge with master
krynble Jun 16, 2022
5f32130
Improve tooltips and descriptions
krynble Jun 28, 2022
d629ed7
Update with master
krynble Jun 28, 2022
f1bfc10
Fix lint issues
krynble Jun 28, 2022
6ecc401
Improve tooltip to explain amounts in micros
krynble Jun 29, 2022
f920444
Change wording for micros
krynble Jun 30, 2022
1d65a8c
Merge branch 'master' into N8N-2942-new-format-google-ads
krynble Jul 4, 2022
ac88242
Change the fix to a more elegant solution
krynble Jul 4, 2022
ef3a8c7
Merge branch 'master' into N8N-2942-new-format-google-ads
krynble Jul 4, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 56 additions & 11 deletions packages/core/src/NodeExecuteFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ import {
LoggerProxy as Logger,
IExecuteData,
OAuth2GrantType,
IOAuth2Credentials,
} from 'n8n-workflow';

import { Agent } from 'https';
Expand All @@ -78,6 +77,7 @@ import { fromBuffer } from 'file-type';
import { lookup } from 'mime-types';

import axios, {
AxiosError,
AxiosPromise,
AxiosProxyConfig,
AxiosRequestConfig,
Expand Down Expand Up @@ -731,6 +731,10 @@ function convertN8nRequestToAxios(n8nRequest: IHttpRequestOptions): AxiosRequest
axiosRequest.headers = axiosRequest.headers || {};
axiosRequest.headers['Content-Type'] = 'application/x-www-form-urlencoded';
}
} else if (
axiosRequest.headers[existingContentTypeHeaderKey] === 'application/x-www-form-urlencoded'
) {
axiosRequest.data = new URLSearchParams(n8nRequest.body as Record<string, string>);
}
}

Expand Down Expand Up @@ -761,6 +765,12 @@ async function httpRequest(
requestOptions: IHttpRequestOptions,
): Promise<IN8nHttpFullResponse | IN8nHttpResponse> {
const axiosRequest = convertN8nRequestToAxios(requestOptions);
if (
axiosRequest.data === undefined ||
(axiosRequest.method !== undefined && axiosRequest.method.toUpperCase() === 'GET')
) {
delete axiosRequest.data;
}
const result = await axios(axiosRequest);
if (requestOptions.returnFullResponse) {
return {
Expand Down Expand Up @@ -886,7 +896,7 @@ export async function requestOAuth2(
oAuth2Options?: IOAuth2Options,
isN8nRequest = false,
) {
const credentials = (await this.getCredentials(credentialsType)) as unknown as IOAuth2Credentials;
const credentials = await this.getCredentials(credentialsType);

// Only the OAuth2 with authorization code grant needs connection
if (
Expand All @@ -897,10 +907,10 @@ export async function requestOAuth2(
}

const oAuthClient = new clientOAuth2({
clientId: credentials.clientId,
clientSecret: credentials.clientSecret,
accessTokenUri: credentials.accessTokenUrl,
scopes: credentials.scope.split(' '),
clientId: credentials.clientId as string,
clientSecret: credentials.clientSecret as string,
accessTokenUri: credentials.accessTokenUrl as string,
scopes: (credentials.scope as string).split(' '),
});

let oauthTokenData = credentials.oauthTokenData as clientOAuth2.Data;
Expand Down Expand Up @@ -936,15 +946,53 @@ export async function requestOAuth2(
// Signs the request by adding authorization headers or query parameters depending
// on the token-type used.
const newRequestOptions = token.sign(requestOptions as clientOAuth2.RequestObject);

// If keep bearer is false remove the it from the authorization header
if (oAuth2Options?.keepBearer === false) {
// @ts-ignore
newRequestOptions?.headers?.Authorization =
// @ts-ignore
newRequestOptions?.headers?.Authorization.split(' ')[1];
}

if (isN8nRequest) {
return this.helpers.httpRequest(newRequestOptions).catch(async (error: AxiosError) => {
if (error.response?.status === 401) {
Logger.debug(
`OAuth2 token for "${credentialsType}" used by node "${node.name}" expired. Should revalidate.`,
);
const tokenRefreshOptions: IDataObject = {};
if (oAuth2Options?.includeCredentialsOnRefreshOnBody) {
const body: IDataObject = {
client_id: credentials.clientId as string,
client_secret: credentials.clientSecret as string,
};
tokenRefreshOptions.body = body;
tokenRefreshOptions.headers = {
Authorization: '',
};
}
const newToken = await token.refresh(tokenRefreshOptions);
Logger.debug(
`OAuth2 token for "${credentialsType}" used by node "${node.name}" has been renewed.`,
);
credentials.oauthTokenData = newToken.data;
// Find the credentials
if (!node.credentials || !node.credentials[credentialsType]) {
throw new Error(
`The node "${node.name}" does not have credentials of type "${credentialsType}"!`,
);
}
const nodeCredentials = node.credentials[credentialsType];
await additionalData.credentialsHelper.updateCredentials(
nodeCredentials,
credentialsType,
credentials,
);
const refreshedRequestOption = newToken.sign(requestOptions as clientOAuth2.RequestObject);
return this.helpers.httpRequest(refreshedRequestOption);
}
throw error;
});
}
return this.helpers.request!(newRequestOptions).catch(async (error: IResponseError) => {
const statusCodeReturned =
oAuth2Options?.tokenExpiredStatusCode === undefined
Expand Down Expand Up @@ -1081,7 +1129,6 @@ export async function requestOAuth1(

// @ts-ignore
requestOptions.headers = oauth.toHeader(oauth.authorize(requestOptions, token));

if (isN8nRequest) {
return this.helpers.httpRequest(requestOptions as IHttpRequestOptions);
}
Expand All @@ -1103,7 +1150,6 @@ export async function httpRequestWithAuthentication(
) {
try {
const parentTypes = additionalData.credentialsHelper.getParentTypes(credentialsType);

if (parentTypes.includes('oAuth1Api')) {
return await requestOAuth1.call(this, credentialsType, requestOptions, true);
}
Expand Down Expand Up @@ -1141,7 +1187,6 @@ export async function httpRequestWithAuthentication(
node,
additionalData.timezone,
);

return await httpRequest(requestOptions);
} catch (error) {
throw new NodeApiError(this.getNode(), error);
Expand Down
32 changes: 32 additions & 0 deletions packages/nodes-base/credentials/GoogleAdsOAuth2Api.credentials.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {
ICredentialType,
INodeProperties,
} from 'n8n-workflow';

const scopes = [
'https://www.googleapis.com/auth/adwords',
];

export class GoogleAdsOAuth2Api implements ICredentialType {
name = 'googleAdsOAuth2Api';
extends = [
'googleOAuth2Api',
];
displayName = 'Google Ads OAuth2 API';
documentationUrl = 'google';
properties: INodeProperties[] = [
{
displayName: 'Developer Token',
name: 'developerToken',
type: 'string',
default: '',
},
{
displayName: 'Scope',
name: 'scope',
type: 'hidden',
default: scopes.join(' '),
},
];

}
Loading