@adtrackify/at-service-common 1.0.59 → 1.0.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +12 -12
- package/.vscode/settings.json +9 -9
- package/build.js +21 -21
- package/dist/index.d.ts +5 -1
- package/dist/index.js +11 -14
- package/dist/index.js.map +2 -2
- package/jest.config.ts +41 -0
- package/package.json +18 -9
- package/src/__tests__/helpers/subscription-helper.spec.ts +41 -0
- package/src/clients/generic/axios.d.ts +7 -7
- package/src/clients/generic/dynamodb-client.ts +113 -113
- package/src/clients/generic/eventbridge-client.ts +52 -52
- package/src/clients/internal-api/accounts-client.ts +107 -107
- package/src/clients/internal-api/destinations-client.ts +58 -58
- package/src/clients/internal-api/users-auth-client.ts +8 -7
- package/src/clients/third-party/shopify-client.ts +128 -128
- package/src/helpers/input-validation-helper.ts +21 -21
- package/src/helpers/shopify-helper.ts +39 -39
- package/src/helpers/subscription-helper.ts +217 -217
- package/src/libs/http-error.ts +6 -6
- package/src/libs/index.ts +7 -7
- package/src/libs/url.ts +9 -9
- package/src/types/internal-events/event-detail-types.ts +9 -9
- package/tsconfig.json +2 -1
|
@@ -1,108 +1,108 @@
|
|
|
1
|
-
import * as log from 'lambda-log';
|
|
2
|
-
import { ApiResponse } from '../../types/api-response';
|
|
3
|
-
import { ACCOUNT_STATUS, Destination } from '@adtrackify/at-tracking-event-types';
|
|
4
|
-
import { axiosHttpService } from '../generic/http-client';
|
|
5
|
-
|
|
6
|
-
//const BASE_API_URL = process.env.BASE_API_URL;
|
|
7
|
-
|
|
8
|
-
//const SERVICE_API_ROOT_URL = `${BASE_API_URL}/accounts`;
|
|
9
|
-
//const ACCOUNTS_API_KEY = process.env.ACCOUNTS_API_KEY;
|
|
10
|
-
|
|
11
|
-
export interface AccountResponseData {
|
|
12
|
-
account: boolean;
|
|
13
|
-
[ key: string ]: any;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface IsAuthorizedUserResponseData {
|
|
17
|
-
isAccountUser: boolean;
|
|
18
|
-
[ key: string ]: any;
|
|
19
|
-
}
|
|
20
|
-
export interface PixelConfigResponseData {
|
|
21
|
-
id: string;
|
|
22
|
-
destinations: Destination[];
|
|
23
|
-
[ key: string ]: any;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export interface UpdateAccountRequest {
|
|
27
|
-
accountName?: string,
|
|
28
|
-
companyName?: string,
|
|
29
|
-
primaryEmail?: string,
|
|
30
|
-
ownerId?: string,
|
|
31
|
-
subscriptionId?: string,
|
|
32
|
-
accountStatus?: ACCOUNT_STATUS;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export class AccountsClient {
|
|
36
|
-
public BASE_API_URL: string;
|
|
37
|
-
public ACCOUNTS_API_KEY?: string;
|
|
38
|
-
|
|
39
|
-
constructor (baseApiUrl: string, accountsApiKey?: string) {
|
|
40
|
-
this.BASE_API_URL = baseApiUrl;
|
|
41
|
-
this.ACCOUNTS_API_KEY = accountsApiKey;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
getConfig = () => {
|
|
45
|
-
const SERVICE_API_ROOT_URL = `${this.BASE_API_URL}/accounts`;
|
|
46
|
-
const params: any = {
|
|
47
|
-
baseURL: SERVICE_API_ROOT_URL
|
|
48
|
-
};
|
|
49
|
-
if (this.ACCOUNTS_API_KEY) {
|
|
50
|
-
params.headers = {
|
|
51
|
-
common: {
|
|
52
|
-
'x-api-key': this.ACCOUNTS_API_KEY
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
return params;
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
getClient = async () => {
|
|
60
|
-
return axiosHttpService(this.getConfig());
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
createAccount = async (createAccountRequest: any) => {
|
|
64
|
-
const client = await this.getClient();
|
|
65
|
-
const createAccountResponse = await client.post('', createAccountRequest);
|
|
66
|
-
log.info('createAccountResponse', { createAccountResponse });
|
|
67
|
-
return createAccountResponse;
|
|
68
|
-
};
|
|
69
|
-
updateAccount = async (accountId: string, body: any): Promise<ApiResponse<AccountResponseData>> => {
|
|
70
|
-
const client = await this.getClient();
|
|
71
|
-
const response = await client.patch(`/${accountId}/`, body);
|
|
72
|
-
log.info('update Account response', { response });
|
|
73
|
-
return response as ApiResponse<AccountResponseData>;
|
|
74
|
-
};
|
|
75
|
-
addOwner = async (accountId: string, userId: string) => {
|
|
76
|
-
const client = await this.getClient();
|
|
77
|
-
const addOwnerResponse = await client.post('/addOwner', { accountId, userId });
|
|
78
|
-
log.info('addOwnerResponse', { addOwnerResponse });
|
|
79
|
-
return addOwnerResponse;
|
|
80
|
-
};
|
|
81
|
-
isAuthorizedUser = async (userId: string, accountId: string, pixelId?: string): Promise<ApiResponse<IsAuthorizedUserResponseData>> => {
|
|
82
|
-
const client = await this.getClient();
|
|
83
|
-
const body = {
|
|
84
|
-
userId, accountId, pixelId
|
|
85
|
-
};
|
|
86
|
-
const response = await client.post('/checkUserAuthorization', body);
|
|
87
|
-
log.info('checkUserAuthorization', { response });
|
|
88
|
-
return response as ApiResponse<IsAuthorizedUserResponseData>;
|
|
89
|
-
};
|
|
90
|
-
adminDeleteAccount = async (accountId: string) => {
|
|
91
|
-
const client = await this.getClient();
|
|
92
|
-
const success = await client.delete(`/${accountId}`);
|
|
93
|
-
log.info('adminDeleteAccount');
|
|
94
|
-
return success;
|
|
95
|
-
};
|
|
96
|
-
getPixelConfigById = async (pixelId: string): Promise<ApiResponse<PixelConfigResponseData>> => {
|
|
97
|
-
const client = await this.getClient();
|
|
98
|
-
const pixelResponse = await client.get(`/px/${pixelId}/config`);
|
|
99
|
-
log.debug('pixelResponse', { pixelResponse });
|
|
100
|
-
return pixelResponse;
|
|
101
|
-
};
|
|
102
|
-
// setAccountSubscriptionId = async (accountId: string, subscriptionId: string): Promise<ApiResponse<any>> => {
|
|
103
|
-
// const client = await this.getClient();
|
|
104
|
-
// const pixelResponse = await client.get(`/px/${pixelId}/config`);
|
|
105
|
-
// log.debug('pixelResponse', { pixelResponse });
|
|
106
|
-
// return pixelResponse;
|
|
107
|
-
// };
|
|
1
|
+
import * as log from 'lambda-log';
|
|
2
|
+
import { ApiResponse } from '../../types/api-response';
|
|
3
|
+
import { ACCOUNT_STATUS, Destination } from '@adtrackify/at-tracking-event-types';
|
|
4
|
+
import { axiosHttpService } from '../generic/http-client';
|
|
5
|
+
|
|
6
|
+
//const BASE_API_URL = process.env.BASE_API_URL;
|
|
7
|
+
|
|
8
|
+
//const SERVICE_API_ROOT_URL = `${BASE_API_URL}/accounts`;
|
|
9
|
+
//const ACCOUNTS_API_KEY = process.env.ACCOUNTS_API_KEY;
|
|
10
|
+
|
|
11
|
+
export interface AccountResponseData {
|
|
12
|
+
account: boolean;
|
|
13
|
+
[ key: string ]: any;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface IsAuthorizedUserResponseData {
|
|
17
|
+
isAccountUser: boolean;
|
|
18
|
+
[ key: string ]: any;
|
|
19
|
+
}
|
|
20
|
+
export interface PixelConfigResponseData {
|
|
21
|
+
id: string;
|
|
22
|
+
destinations: Destination[];
|
|
23
|
+
[ key: string ]: any;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface UpdateAccountRequest {
|
|
27
|
+
accountName?: string,
|
|
28
|
+
companyName?: string,
|
|
29
|
+
primaryEmail?: string,
|
|
30
|
+
ownerId?: string,
|
|
31
|
+
subscriptionId?: string,
|
|
32
|
+
accountStatus?: ACCOUNT_STATUS;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class AccountsClient {
|
|
36
|
+
public BASE_API_URL: string;
|
|
37
|
+
public ACCOUNTS_API_KEY?: string;
|
|
38
|
+
|
|
39
|
+
constructor (baseApiUrl: string, accountsApiKey?: string) {
|
|
40
|
+
this.BASE_API_URL = baseApiUrl;
|
|
41
|
+
this.ACCOUNTS_API_KEY = accountsApiKey;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
getConfig = () => {
|
|
45
|
+
const SERVICE_API_ROOT_URL = `${this.BASE_API_URL}/accounts`;
|
|
46
|
+
const params: any = {
|
|
47
|
+
baseURL: SERVICE_API_ROOT_URL
|
|
48
|
+
};
|
|
49
|
+
if (this.ACCOUNTS_API_KEY) {
|
|
50
|
+
params.headers = {
|
|
51
|
+
common: {
|
|
52
|
+
'x-api-key': this.ACCOUNTS_API_KEY
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return params;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
getClient = async () => {
|
|
60
|
+
return axiosHttpService(this.getConfig());
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
createAccount = async (createAccountRequest: any) => {
|
|
64
|
+
const client = await this.getClient();
|
|
65
|
+
const createAccountResponse = await client.post('', createAccountRequest);
|
|
66
|
+
log.info('createAccountResponse', { createAccountResponse });
|
|
67
|
+
return createAccountResponse;
|
|
68
|
+
};
|
|
69
|
+
updateAccount = async (accountId: string, body: any): Promise<ApiResponse<AccountResponseData>> => {
|
|
70
|
+
const client = await this.getClient();
|
|
71
|
+
const response = await client.patch(`/${accountId}/`, body);
|
|
72
|
+
log.info('update Account response', { response });
|
|
73
|
+
return response as ApiResponse<AccountResponseData>;
|
|
74
|
+
};
|
|
75
|
+
addOwner = async (accountId: string, userId: string) => {
|
|
76
|
+
const client = await this.getClient();
|
|
77
|
+
const addOwnerResponse = await client.post('/addOwner', { accountId, userId });
|
|
78
|
+
log.info('addOwnerResponse', { addOwnerResponse });
|
|
79
|
+
return addOwnerResponse;
|
|
80
|
+
};
|
|
81
|
+
isAuthorizedUser = async (userId: string, accountId: string, pixelId?: string): Promise<ApiResponse<IsAuthorizedUserResponseData>> => {
|
|
82
|
+
const client = await this.getClient();
|
|
83
|
+
const body = {
|
|
84
|
+
userId, accountId, pixelId
|
|
85
|
+
};
|
|
86
|
+
const response = await client.post('/checkUserAuthorization', body);
|
|
87
|
+
log.info('checkUserAuthorization', { response });
|
|
88
|
+
return response as ApiResponse<IsAuthorizedUserResponseData>;
|
|
89
|
+
};
|
|
90
|
+
adminDeleteAccount = async (accountId: string) => {
|
|
91
|
+
const client = await this.getClient();
|
|
92
|
+
const success = await client.delete(`/${accountId}`);
|
|
93
|
+
log.info('adminDeleteAccount');
|
|
94
|
+
return success;
|
|
95
|
+
};
|
|
96
|
+
getPixelConfigById = async (pixelId: string): Promise<ApiResponse<PixelConfigResponseData>> => {
|
|
97
|
+
const client = await this.getClient();
|
|
98
|
+
const pixelResponse = await client.get(`/px/${pixelId}/config`);
|
|
99
|
+
log.debug('pixelResponse', { pixelResponse });
|
|
100
|
+
return pixelResponse;
|
|
101
|
+
};
|
|
102
|
+
// setAccountSubscriptionId = async (accountId: string, subscriptionId: string): Promise<ApiResponse<any>> => {
|
|
103
|
+
// const client = await this.getClient();
|
|
104
|
+
// const pixelResponse = await client.get(`/px/${pixelId}/config`);
|
|
105
|
+
// log.debug('pixelResponse', { pixelResponse });
|
|
106
|
+
// return pixelResponse;
|
|
107
|
+
// };
|
|
108
108
|
}
|
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
import * as log from 'lambda-log';
|
|
2
|
-
//const log = require('lambda-log');
|
|
3
|
-
import { ApiResponse } from '../../types/api-response';
|
|
4
|
-
import { axiosHttpService } from '../generic/http-client';
|
|
5
|
-
import { Destination } from '@adtrackify/at-tracking-event-types';
|
|
6
|
-
//const BASE_API_URL = process.env.BASE_API_URL;
|
|
7
|
-
//const DESTINATIONS_API_KEY = process.env.DESTINATIONS_API_KEY;
|
|
8
|
-
|
|
9
|
-
export interface GetDestinationsResponseData {
|
|
10
|
-
destinations: Destination[];
|
|
11
|
-
[ key: string ]: any;
|
|
12
|
-
}
|
|
13
|
-
export interface CreateDestinationResponseData {
|
|
14
|
-
destination: Destination;
|
|
15
|
-
[ key: string ]: any;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
export class DestinationsClient {
|
|
20
|
-
|
|
21
|
-
public BASE_API_URL: string;
|
|
22
|
-
public DESTINATIONS_API_KEY: string;
|
|
23
|
-
|
|
24
|
-
constructor (baseApiUrl: string, destinationsApiKey: string) {
|
|
25
|
-
this.BASE_API_URL = baseApiUrl;
|
|
26
|
-
this.DESTINATIONS_API_KEY = destinationsApiKey;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
getConfig = () => {
|
|
30
|
-
const SERVICE_API_ROOT_URL = `${this.BASE_API_URL}/destinations`;
|
|
31
|
-
return {
|
|
32
|
-
baseURL: SERVICE_API_ROOT_URL,
|
|
33
|
-
headers: {
|
|
34
|
-
common: {
|
|
35
|
-
'x-api-key': this.DESTINATIONS_API_KEY
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
getClient = async () => {
|
|
42
|
-
return axiosHttpService(this.getConfig());
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
createDestination = async (createDestinationRequest: any): Promise<ApiResponse<CreateDestinationResponseData>> => {
|
|
46
|
-
const client = await this.getClient();
|
|
47
|
-
const response = await client.post('/', createDestinationRequest);
|
|
48
|
-
log.info('createDestinationResponse', { response });
|
|
49
|
-
return response as ApiResponse<CreateDestinationResponseData>;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
getPixelDestinations = async (pixelId: string): Promise<ApiResponse<GetDestinationsResponseData>> => {
|
|
53
|
-
const client = await this.getClient();
|
|
54
|
-
const response = await client.get(`/?pixelId=${pixelId}`);
|
|
55
|
-
log.info('getPixelResponse', { response });
|
|
56
|
-
return response as ApiResponse<GetDestinationsResponseData>;
|
|
57
|
-
};
|
|
58
|
-
}
|
|
1
|
+
import * as log from 'lambda-log';
|
|
2
|
+
//const log = require('lambda-log');
|
|
3
|
+
import { ApiResponse } from '../../types/api-response';
|
|
4
|
+
import { axiosHttpService } from '../generic/http-client';
|
|
5
|
+
import { Destination } from '@adtrackify/at-tracking-event-types';
|
|
6
|
+
//const BASE_API_URL = process.env.BASE_API_URL;
|
|
7
|
+
//const DESTINATIONS_API_KEY = process.env.DESTINATIONS_API_KEY;
|
|
8
|
+
|
|
9
|
+
export interface GetDestinationsResponseData {
|
|
10
|
+
destinations: Destination[];
|
|
11
|
+
[ key: string ]: any;
|
|
12
|
+
}
|
|
13
|
+
export interface CreateDestinationResponseData {
|
|
14
|
+
destination: Destination;
|
|
15
|
+
[ key: string ]: any;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
export class DestinationsClient {
|
|
20
|
+
|
|
21
|
+
public BASE_API_URL: string;
|
|
22
|
+
public DESTINATIONS_API_KEY: string;
|
|
23
|
+
|
|
24
|
+
constructor (baseApiUrl: string, destinationsApiKey: string) {
|
|
25
|
+
this.BASE_API_URL = baseApiUrl;
|
|
26
|
+
this.DESTINATIONS_API_KEY = destinationsApiKey;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
getConfig = () => {
|
|
30
|
+
const SERVICE_API_ROOT_URL = `${this.BASE_API_URL}/destinations`;
|
|
31
|
+
return {
|
|
32
|
+
baseURL: SERVICE_API_ROOT_URL,
|
|
33
|
+
headers: {
|
|
34
|
+
common: {
|
|
35
|
+
'x-api-key': this.DESTINATIONS_API_KEY
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
getClient = async () => {
|
|
42
|
+
return axiosHttpService(this.getConfig());
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
createDestination = async (createDestinationRequest: any): Promise<ApiResponse<CreateDestinationResponseData>> => {
|
|
46
|
+
const client = await this.getClient();
|
|
47
|
+
const response = await client.post('/', createDestinationRequest);
|
|
48
|
+
log.info('createDestinationResponse', { response });
|
|
49
|
+
return response as ApiResponse<CreateDestinationResponseData>;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
getPixelDestinations = async (pixelId: string): Promise<ApiResponse<GetDestinationsResponseData>> => {
|
|
53
|
+
const client = await this.getClient();
|
|
54
|
+
const response = await client.get(`/?pixelId=${pixelId}`);
|
|
55
|
+
log.info('getPixelResponse', { response });
|
|
56
|
+
return response as ApiResponse<GetDestinationsResponseData>;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -66,20 +66,21 @@ export class UsersAuthClient {
|
|
|
66
66
|
};
|
|
67
67
|
|
|
68
68
|
//userName is same as user id
|
|
69
|
-
adminConfirmUser = async (
|
|
69
|
+
adminConfirmUser = async (email: string) => {
|
|
70
70
|
//confirm user
|
|
71
71
|
//@TODO update user auth service with admin confirm user endpoint
|
|
72
|
-
log.info('Attempting to admin confirm user', {
|
|
72
|
+
log.info('Attempting to admin confirm user', { email });
|
|
73
73
|
|
|
74
74
|
const client = await this.getClient();
|
|
75
|
-
const response = await client.post('/admin/confirm',
|
|
75
|
+
const response = await client.post('/admin/confirm',
|
|
76
|
+
{
|
|
77
|
+
email
|
|
78
|
+
}, {
|
|
76
79
|
headers: {
|
|
77
80
|
'x-api-key': this.USERS_AUTH_API_KEY
|
|
78
|
-
},
|
|
79
|
-
params: {
|
|
80
|
-
userName
|
|
81
81
|
}
|
|
82
|
-
}
|
|
82
|
+
}
|
|
83
|
+
);
|
|
83
84
|
|
|
84
85
|
// Check if Successful or throw error
|
|
85
86
|
if (response.status !== 200) {
|
|
@@ -1,128 +1,128 @@
|
|
|
1
|
-
import { axiosHttpService } from '../generic/http-client';
|
|
2
|
-
import * as log from 'lambda-log';
|
|
3
|
-
|
|
4
|
-
export class ShopifyClient {
|
|
5
|
-
static _shopify_api_version = process.env.SHOPIFY_API_VERSION as string;
|
|
6
|
-
static getConfig = (shopifyDomain: string, accessToken: string) => {
|
|
7
|
-
const config = {
|
|
8
|
-
baseURL: `https://${shopifyDomain}/admin/api/${this._shopify_api_version}`,
|
|
9
|
-
headers: {
|
|
10
|
-
common: {
|
|
11
|
-
'X-Shopify-Access-Token': accessToken,
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
};
|
|
15
|
-
return config;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
static getClient = (shopifyDomain: string, accessToken: string) => {
|
|
19
|
-
return axiosHttpService(
|
|
20
|
-
this.getConfig(shopifyDomain, accessToken)
|
|
21
|
-
);
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
static registerApp = async (shop: string, code: string, appKey: string, appSecret: string) => {
|
|
25
|
-
const client = axiosHttpService();
|
|
26
|
-
const url = 'https://' + shop + '/admin/oauth/access_token';
|
|
27
|
-
const payload = {
|
|
28
|
-
client_id: appKey,
|
|
29
|
-
client_secret: appSecret,
|
|
30
|
-
code
|
|
31
|
-
};
|
|
32
|
-
const res = await client.post(url, payload);
|
|
33
|
-
return res;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
static registerWebhookTopic = async (shop: string, accessToken: string, eventBridgeArn: string, topic: string) => {
|
|
37
|
-
const client = axiosHttpService();
|
|
38
|
-
const url = `https://${shop}/admin/api/${this._shopify_api_version}/webhooks.json`;
|
|
39
|
-
const payload = {
|
|
40
|
-
webhook: {
|
|
41
|
-
topic,
|
|
42
|
-
address: eventBridgeArn,
|
|
43
|
-
format: 'json'
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
const res = await client.post(url, payload, { headers: { 'X-Shopify-Access-Token': accessToken } });
|
|
47
|
-
if (res.status >= 400) {
|
|
48
|
-
log.error('Failed to register Webhook Topic', { shop, accessToken, eventBridgeArn, topic, url, payload });
|
|
49
|
-
}
|
|
50
|
-
log.debug('Shopify Client Webhook Registration Response', { registrationResponse: res });
|
|
51
|
-
return res;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
static updateShopifyAppMetafield = async (shop: string, accessToken: string, pixelId: string) => {
|
|
55
|
-
const url = `https://${shop}/admin/api/${this._shopify_api_version}/metafields.json`;
|
|
56
|
-
const payload = {
|
|
57
|
-
metafield: {
|
|
58
|
-
namespace: 'adtr',
|
|
59
|
-
key: 'adtr.config',
|
|
60
|
-
value: pixelId,
|
|
61
|
-
type: 'single_line_text_field'
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
const res = await this.genericShopifyPost(url, accessToken, payload);
|
|
65
|
-
|
|
66
|
-
if (res.status >= 400) {
|
|
67
|
-
log.error('Failed to register Webhook Topic', { shop, accessToken, url, payload });
|
|
68
|
-
}
|
|
69
|
-
return res;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
static getShopifyStoreProperties = async (shop: string, accessToken: string) => {
|
|
73
|
-
const url = `https://${shop}/admin/api/${this._shopify_api_version}/shop.json`;
|
|
74
|
-
const res = await this.genericShopifyGet(url, accessToken);
|
|
75
|
-
|
|
76
|
-
if (res.status >= 400) {
|
|
77
|
-
log.error('Failed to get Shopify Store Properties', { shop, accessToken, url });
|
|
78
|
-
}
|
|
79
|
-
return res;
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
static createAppSubscription = async (shop: string, accessToken: string,
|
|
83
|
-
planName: string, price: number, returnUrl: string, trialDays: number, test?: boolean) => {
|
|
84
|
-
const url = `https://${shop}/admin/api/${this._shopify_api_version}/recurring_application_charges.json`;
|
|
85
|
-
const recurring_application_charge = {
|
|
86
|
-
name: planName,
|
|
87
|
-
price,
|
|
88
|
-
return_url: returnUrl,
|
|
89
|
-
trial_days: trialDays,
|
|
90
|
-
test
|
|
91
|
-
};
|
|
92
|
-
const res = await this.genericShopifyPost(url, accessToken, { recurring_application_charge });
|
|
93
|
-
if (res.status >= 400) {
|
|
94
|
-
log.error('Failed to create App Subscription', { shop, accessToken, url });
|
|
95
|
-
}
|
|
96
|
-
return res;
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
static listAppSubscriptions = async (shop: string, accessToken: string) => {
|
|
100
|
-
const url = `https://${shop}/admin/api/${this._shopify_api_version}/recurring_application_charges.json`;
|
|
101
|
-
const res = await this.genericShopifyGet(url, accessToken);
|
|
102
|
-
if (res.status >= 400) {
|
|
103
|
-
log.error('Failed to get App Subscriptions', { shop, accessToken, url });
|
|
104
|
-
}
|
|
105
|
-
return res;
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
static genericShopifyPost = async (url: string, accessToken: string, payload: any) => {
|
|
109
|
-
const client = axiosHttpService();
|
|
110
|
-
const res = await client.post(url, payload, { headers: { 'X-Shopify-Access-Token': accessToken } });
|
|
111
|
-
log.debug('Shopify Client Response', { res });
|
|
112
|
-
return res;
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
static genericShopifyGet = async (url: string, accessToken: string) => {
|
|
116
|
-
const client = axiosHttpService();
|
|
117
|
-
const res = await client.get(url, { headers: { 'X-Shopify-Access-Token': accessToken } });
|
|
118
|
-
log.debug('Shopify Client Response', { res });
|
|
119
|
-
return res;
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
static genericShopifyPut = async (url: string, accessToken: string, payload: any) => {
|
|
123
|
-
const client = axiosHttpService();
|
|
124
|
-
const res = await client.put(url, payload, { headers: { 'X-Shopify-Access-Token': accessToken } });
|
|
125
|
-
log.debug('Shopify Client Response', { res });
|
|
126
|
-
return res;
|
|
127
|
-
};
|
|
128
|
-
}
|
|
1
|
+
import { axiosHttpService } from '../generic/http-client';
|
|
2
|
+
import * as log from 'lambda-log';
|
|
3
|
+
|
|
4
|
+
export class ShopifyClient {
|
|
5
|
+
static _shopify_api_version = process.env.SHOPIFY_API_VERSION as string;
|
|
6
|
+
static getConfig = (shopifyDomain: string, accessToken: string) => {
|
|
7
|
+
const config = {
|
|
8
|
+
baseURL: `https://${shopifyDomain}/admin/api/${this._shopify_api_version}`,
|
|
9
|
+
headers: {
|
|
10
|
+
common: {
|
|
11
|
+
'X-Shopify-Access-Token': accessToken,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
return config;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
static getClient = (shopifyDomain: string, accessToken: string) => {
|
|
19
|
+
return axiosHttpService(
|
|
20
|
+
this.getConfig(shopifyDomain, accessToken)
|
|
21
|
+
);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
static registerApp = async (shop: string, code: string, appKey: string, appSecret: string) => {
|
|
25
|
+
const client = axiosHttpService();
|
|
26
|
+
const url = 'https://' + shop + '/admin/oauth/access_token';
|
|
27
|
+
const payload = {
|
|
28
|
+
client_id: appKey,
|
|
29
|
+
client_secret: appSecret,
|
|
30
|
+
code
|
|
31
|
+
};
|
|
32
|
+
const res = await client.post(url, payload);
|
|
33
|
+
return res;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
static registerWebhookTopic = async (shop: string, accessToken: string, eventBridgeArn: string, topic: string) => {
|
|
37
|
+
const client = axiosHttpService();
|
|
38
|
+
const url = `https://${shop}/admin/api/${this._shopify_api_version}/webhooks.json`;
|
|
39
|
+
const payload = {
|
|
40
|
+
webhook: {
|
|
41
|
+
topic,
|
|
42
|
+
address: eventBridgeArn,
|
|
43
|
+
format: 'json'
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const res = await client.post(url, payload, { headers: { 'X-Shopify-Access-Token': accessToken } });
|
|
47
|
+
if (res.status >= 400) {
|
|
48
|
+
log.error('Failed to register Webhook Topic', { shop, accessToken, eventBridgeArn, topic, url, payload });
|
|
49
|
+
}
|
|
50
|
+
log.debug('Shopify Client Webhook Registration Response', { registrationResponse: res });
|
|
51
|
+
return res;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
static updateShopifyAppMetafield = async (shop: string, accessToken: string, pixelId: string) => {
|
|
55
|
+
const url = `https://${shop}/admin/api/${this._shopify_api_version}/metafields.json`;
|
|
56
|
+
const payload = {
|
|
57
|
+
metafield: {
|
|
58
|
+
namespace: 'adtr',
|
|
59
|
+
key: 'adtr.config',
|
|
60
|
+
value: pixelId,
|
|
61
|
+
type: 'single_line_text_field'
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const res = await this.genericShopifyPost(url, accessToken, payload);
|
|
65
|
+
|
|
66
|
+
if (res.status >= 400) {
|
|
67
|
+
log.error('Failed to register Webhook Topic', { shop, accessToken, url, payload });
|
|
68
|
+
}
|
|
69
|
+
return res;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
static getShopifyStoreProperties = async (shop: string, accessToken: string) => {
|
|
73
|
+
const url = `https://${shop}/admin/api/${this._shopify_api_version}/shop.json`;
|
|
74
|
+
const res = await this.genericShopifyGet(url, accessToken);
|
|
75
|
+
|
|
76
|
+
if (res.status >= 400) {
|
|
77
|
+
log.error('Failed to get Shopify Store Properties', { shop, accessToken, url });
|
|
78
|
+
}
|
|
79
|
+
return res;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
static createAppSubscription = async (shop: string, accessToken: string,
|
|
83
|
+
planName: string, price: number, returnUrl: string, trialDays: number, test?: boolean) => {
|
|
84
|
+
const url = `https://${shop}/admin/api/${this._shopify_api_version}/recurring_application_charges.json`;
|
|
85
|
+
const recurring_application_charge = {
|
|
86
|
+
name: planName,
|
|
87
|
+
price,
|
|
88
|
+
return_url: returnUrl,
|
|
89
|
+
trial_days: trialDays,
|
|
90
|
+
test
|
|
91
|
+
};
|
|
92
|
+
const res = await this.genericShopifyPost(url, accessToken, { recurring_application_charge });
|
|
93
|
+
if (res.status >= 400) {
|
|
94
|
+
log.error('Failed to create App Subscription', { shop, accessToken, url });
|
|
95
|
+
}
|
|
96
|
+
return res;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
static listAppSubscriptions = async (shop: string, accessToken: string) => {
|
|
100
|
+
const url = `https://${shop}/admin/api/${this._shopify_api_version}/recurring_application_charges.json`;
|
|
101
|
+
const res = await this.genericShopifyGet(url, accessToken);
|
|
102
|
+
if (res.status >= 400) {
|
|
103
|
+
log.error('Failed to get App Subscriptions', { shop, accessToken, url });
|
|
104
|
+
}
|
|
105
|
+
return res;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
static genericShopifyPost = async (url: string, accessToken: string, payload: any) => {
|
|
109
|
+
const client = axiosHttpService();
|
|
110
|
+
const res = await client.post(url, payload, { headers: { 'X-Shopify-Access-Token': accessToken } });
|
|
111
|
+
log.debug('Shopify Client Response', { res });
|
|
112
|
+
return res;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
static genericShopifyGet = async (url: string, accessToken: string) => {
|
|
116
|
+
const client = axiosHttpService();
|
|
117
|
+
const res = await client.get(url, { headers: { 'X-Shopify-Access-Token': accessToken } });
|
|
118
|
+
log.debug('Shopify Client Response', { res });
|
|
119
|
+
return res;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
static genericShopifyPut = async (url: string, accessToken: string, payload: any) => {
|
|
123
|
+
const client = axiosHttpService();
|
|
124
|
+
const res = await client.put(url, payload, { headers: { 'X-Shopify-Access-Token': accessToken } });
|
|
125
|
+
log.debug('Shopify Client Response', { res });
|
|
126
|
+
return res;
|
|
127
|
+
};
|
|
128
|
+
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import Joi from 'joi';
|
|
2
|
-
import * as log from 'lambda-log';
|
|
3
|
-
import { HttpError } from '../libs/http-error';
|
|
4
|
-
|
|
5
|
-
export const validateInput = (schema: Joi.ObjectSchema<any>, input: any) => {
|
|
6
|
-
const { error, value } = schema.validate(input);
|
|
7
|
-
if (error) {
|
|
8
|
-
log.info('', { error });
|
|
9
|
-
|
|
10
|
-
const httperr = HttpError.badRequest('Bad Request', {
|
|
11
|
-
errors: error.details.map(detail => ({
|
|
12
|
-
message: detail?.message,
|
|
13
|
-
key: detail?.context?.key,
|
|
14
|
-
path: detail?.path,
|
|
15
|
-
}))
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
log.info('', { httperr });
|
|
19
|
-
throw httperr;
|
|
20
|
-
}
|
|
21
|
-
return value;
|
|
1
|
+
import Joi from 'joi';
|
|
2
|
+
import * as log from 'lambda-log';
|
|
3
|
+
import { HttpError } from '../libs/http-error';
|
|
4
|
+
|
|
5
|
+
export const validateInput = (schema: Joi.ObjectSchema<any>, input: any) => {
|
|
6
|
+
const { error, value } = schema.validate(input);
|
|
7
|
+
if (error) {
|
|
8
|
+
log.info('', { error });
|
|
9
|
+
|
|
10
|
+
const httperr = HttpError.badRequest('Bad Request', {
|
|
11
|
+
errors: error.details.map(detail => ({
|
|
12
|
+
message: detail?.message,
|
|
13
|
+
key: detail?.context?.key,
|
|
14
|
+
path: detail?.path,
|
|
15
|
+
}))
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
log.info('', { httperr });
|
|
19
|
+
throw httperr;
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
22
|
};
|