@things-factory/integration-marketplace 4.2.3 → 4.2.8
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/dist-server/controllers/index.js +1 -0
- package/dist-server/controllers/index.js.map +1 -1
- package/dist-server/controllers/magento/apis/get-store-orders.js +2 -1
- package/dist-server/controllers/magento/apis/get-store-orders.js.map +1 -1
- package/dist-server/controllers/magento/apis/get-store-products.js +8 -9
- package/dist-server/controllers/magento/apis/get-store-products.js.map +1 -1
- package/dist-server/controllers/magento/apis/update-order-status.js +39 -14
- package/dist-server/controllers/magento/apis/update-order-status.js.map +1 -1
- package/dist-server/controllers/store-api/index.js +14 -0
- package/dist-server/controllers/store-api/index.js.map +1 -1
- package/dist-server/controllers/tiktok/apis/echo.js +19 -0
- package/dist-server/controllers/tiktok/apis/echo.js.map +1 -0
- package/dist-server/controllers/tiktok/apis/get-store-order-document.js +27 -0
- package/dist-server/controllers/tiktok/apis/get-store-order-document.js.map +1 -0
- package/dist-server/controllers/tiktok/apis/get-store-order-package.js +47 -0
- package/dist-server/controllers/tiktok/apis/get-store-order-package.js.map +1 -0
- package/dist-server/controllers/tiktok/apis/get-store-order-packages.js +39 -0
- package/dist-server/controllers/tiktok/apis/get-store-order-packages.js.map +1 -0
- package/dist-server/controllers/tiktok/apis/get-store-order.js +137 -0
- package/dist-server/controllers/tiktok/apis/get-store-order.js.map +1 -0
- package/dist-server/controllers/tiktok/apis/get-store-orders.js +47 -0
- package/dist-server/controllers/tiktok/apis/get-store-orders.js.map +1 -0
- package/dist-server/controllers/tiktok/apis/get-store-product-attributes.js +30 -0
- package/dist-server/controllers/tiktok/apis/get-store-product-attributes.js.map +1 -0
- package/dist-server/controllers/tiktok/apis/get-store-product-categories.js +28 -0
- package/dist-server/controllers/tiktok/apis/get-store-product-categories.js.map +1 -0
- package/dist-server/controllers/tiktok/apis/get-store-product.js +91 -0
- package/dist-server/controllers/tiktok/apis/get-store-product.js.map +1 -0
- package/dist-server/controllers/tiktok/apis/get-store-products.js +36 -0
- package/dist-server/controllers/tiktok/apis/get-store-products.js.map +1 -0
- package/dist-server/controllers/tiktok/apis/index.js +26 -0
- package/dist-server/controllers/tiktok/apis/index.js.map +1 -0
- package/dist-server/controllers/tiktok/apis/update-order-status.js +27 -0
- package/dist-server/controllers/tiktok/apis/update-order-status.js.map +1 -0
- package/dist-server/controllers/tiktok/apis/update-store-product-variation-price.js +28 -0
- package/dist-server/controllers/tiktok/apis/update-store-product-variation-price.js.map +1 -0
- package/dist-server/controllers/tiktok/apis/update-store-product-variation-stock.js +32 -0
- package/dist-server/controllers/tiktok/apis/update-store-product-variation-stock.js.map +1 -0
- package/dist-server/controllers/tiktok/client/index.js +15 -0
- package/dist-server/controllers/tiktok/client/index.js.map +1 -0
- package/dist-server/controllers/tiktok/client/signature.js +63 -0
- package/dist-server/controllers/tiktok/client/signature.js.map +1 -0
- package/dist-server/controllers/tiktok/client/tiktok.js +93 -0
- package/dist-server/controllers/tiktok/client/tiktok.js.map +1 -0
- package/dist-server/controllers/tiktok/client/types.js +3 -0
- package/dist-server/controllers/tiktok/client/types.js.map +1 -0
- package/dist-server/controllers/tiktok/index.js +30 -0
- package/dist-server/controllers/tiktok/index.js.map +1 -0
- package/dist-server/controllers/tiktok/platform-action.js +44 -0
- package/dist-server/controllers/tiktok/platform-action.js.map +1 -0
- package/dist-server/controllers/woocommerce/apis/get-store-products.js +17 -6
- package/dist-server/controllers/woocommerce/apis/get-store-products.js.map +1 -1
- package/package.json +2 -2
- package/server/controllers/index.ts +1 -0
- package/server/controllers/magento/apis/get-store-orders.ts +3 -1
- package/server/controllers/magento/apis/get-store-products.ts +1 -2
- package/server/controllers/magento/apis/update-order-status.ts +43 -15
- package/server/controllers/store-api/index.ts +6 -0
- package/server/controllers/tiktok/apis/echo.ts +14 -0
- package/server/controllers/tiktok/apis/get-store-order-document.ts +26 -0
- package/server/controllers/tiktok/apis/get-store-order-package.ts +46 -0
- package/server/controllers/tiktok/apis/get-store-order-packages.ts +43 -0
- package/server/controllers/tiktok/apis/get-store-order.ts +169 -0
- package/server/controllers/tiktok/apis/get-store-orders.ts +52 -0
- package/server/controllers/tiktok/apis/get-store-product-attributes.ts +29 -0
- package/server/controllers/tiktok/apis/get-store-product-categories.ts +27 -0
- package/server/controllers/tiktok/apis/get-store-product.ts +95 -0
- package/server/controllers/tiktok/apis/get-store-products.ts +38 -0
- package/server/controllers/tiktok/apis/index.ts +13 -0
- package/server/controllers/tiktok/apis/update-order-status.ts +22 -0
- package/server/controllers/tiktok/apis/update-store-product-variation-price.ts +24 -0
- package/server/controllers/tiktok/apis/update-store-product-variation-stock.ts +28 -0
- package/server/controllers/tiktok/client/index.ts +2 -0
- package/server/controllers/tiktok/client/signature.ts +78 -0
- package/server/controllers/tiktok/client/tiktok.ts +139 -0
- package/server/controllers/tiktok/client/types.ts +20 -0
- package/server/controllers/tiktok/index.ts +8 -0
- package/server/controllers/tiktok/platform-action.ts +48 -0
- package/server/controllers/woocommerce/apis/get-store-products.ts +33 -22
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/* https://bytedance.feishu.cn/docs/doccnDyz5Bbk26iOdejbBRBlLrb#ytBXoS */
|
|
2
|
+
|
|
3
|
+
/* status: 0-all, 1-draft, 2-pending, 3-failed, 4-live, 5-seller_deactivated,
|
|
4
|
+
6-platform-deactivated, 7-freeze, 8-deleted
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export function getStoreProduct() {
|
|
8
|
+
return {
|
|
9
|
+
method: 'get',
|
|
10
|
+
path: '/api/products/details',
|
|
11
|
+
denormalize(req) {
|
|
12
|
+
var { productId } = req || {}
|
|
13
|
+
|
|
14
|
+
return { payload: { product_id: productId } }
|
|
15
|
+
},
|
|
16
|
+
async normalize(res) {
|
|
17
|
+
const { data } = res
|
|
18
|
+
|
|
19
|
+
const productVariations: any[] = data.skus
|
|
20
|
+
|
|
21
|
+
let variants: any[] = []
|
|
22
|
+
if (productVariations && productVariations?.length > 0) {
|
|
23
|
+
variants = productVariations.map(variant => {
|
|
24
|
+
let totalProductQty: number = 0
|
|
25
|
+
let stockInfos = variant.stock_infos
|
|
26
|
+
stockInfos.map(stockInfo => {
|
|
27
|
+
totalProductQty += stockInfo.available_stock
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
variationId: variant.id,
|
|
32
|
+
variationSku: variant.seller_sku || variant.id.toString(),
|
|
33
|
+
channelSku: variant.seller_sku || variant.id.toString(),
|
|
34
|
+
name: data.product_name,
|
|
35
|
+
qty: totalProductQty,
|
|
36
|
+
primaryUnit: 'N/A',
|
|
37
|
+
primaryUnitValue: data.package_weight === '' ? null : parseFloat(data.package_weight),
|
|
38
|
+
costPrice: variant.price.original_price === '' ? null : parseFloat(variant.price.original_price),
|
|
39
|
+
sellPrice: variant.price.original_price === '' ? null : parseFloat(variant.price.original_price),
|
|
40
|
+
isEnabled: data.product_status == 4 ? true : false,
|
|
41
|
+
length: data?.package_length ? data.package_length * 10 : 1,
|
|
42
|
+
width: data?.package_width ? data.package_width * 10 : 1,
|
|
43
|
+
height: data?.package_height ? data.package_height * 10 : 1,
|
|
44
|
+
weight: data.package_weight === '' ? null : parseFloat(data.package_weight)
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
} else {
|
|
48
|
+
variants = [
|
|
49
|
+
{
|
|
50
|
+
variationId: data.product_id,
|
|
51
|
+
variationSku: data.product_name,
|
|
52
|
+
channelSku: data.product_name,
|
|
53
|
+
name: data.product_name,
|
|
54
|
+
qty: 0,
|
|
55
|
+
primaryUnit: 'N/A',
|
|
56
|
+
primaryUnitValue: data.package_weight === '' ? null : parseFloat(data.package_weight),
|
|
57
|
+
costPrice: null,
|
|
58
|
+
sellPrice: null,
|
|
59
|
+
isEnabled: data.product_status == 4 ? true : false,
|
|
60
|
+
length: data?.package_length ? data.package_length * 10 : 1,
|
|
61
|
+
width: data?.package_width ? data.package_width * 10 : 1,
|
|
62
|
+
height: data?.package_height ? data.package_height * 10 : 1,
|
|
63
|
+
weight: data.package_weight === '' ? null : parseFloat(data.package_weight)
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const result = {
|
|
69
|
+
itemId: data.product_id,
|
|
70
|
+
name: data.product_name,
|
|
71
|
+
brand: data?.brand?.name || null,
|
|
72
|
+
isVerified: data.product_status == 4 ? true : false,
|
|
73
|
+
categoryId: data?.category_list?.length > 0 ? data.category_list[0].id : '',
|
|
74
|
+
images: getImageUrl(data.images),
|
|
75
|
+
variations: variants
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return result
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function getImageUrl(images) {
|
|
84
|
+
let imageSrc: any = []
|
|
85
|
+
|
|
86
|
+
if (images) {
|
|
87
|
+
images.map(image => {
|
|
88
|
+
image.url_list.map(url => {
|
|
89
|
+
imageSrc.push(url)
|
|
90
|
+
})
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return imageSrc
|
|
95
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/* https://bytedance.feishu.cn/docs/doccnDyz5Bbk26iOdejbBRBlLrb#ytBXoS */
|
|
2
|
+
|
|
3
|
+
/* status: 0-all, 1-draft, 2-pending, 3-failed, 4-live, 5-seller_deactivated,
|
|
4
|
+
6-platform-deactivated, 7-freeze, 8-deleted
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { StoreAPI } from '../../store-api'
|
|
8
|
+
|
|
9
|
+
export function getStoreProducts() {
|
|
10
|
+
return {
|
|
11
|
+
method: 'post',
|
|
12
|
+
path: '/api/products/search',
|
|
13
|
+
denormalize(req) {
|
|
14
|
+
var { pagination } = req || {}
|
|
15
|
+
var { page, limit } = pagination || { page: 0, limit: 100 }
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
payload: { page_size: limit, page_number: page + 1, search_status: 0 },
|
|
19
|
+
resource: {}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
async normalize(res, { store }) {
|
|
23
|
+
const { data } = res
|
|
24
|
+
|
|
25
|
+
const products: any[] = data?.products || []
|
|
26
|
+
const total: number = data?.total || 0
|
|
27
|
+
|
|
28
|
+
let results: any[] = []
|
|
29
|
+
for (let i = 0; i < products.length; i++) {
|
|
30
|
+
const product: any = products[i]
|
|
31
|
+
const productDetails = await StoreAPI.getStoreProduct(store, { productId: product.id })
|
|
32
|
+
results.push({ ...productDetails })
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return { results, total }
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from './echo'
|
|
2
|
+
export * from './get-store-order'
|
|
3
|
+
export * from './get-store-orders'
|
|
4
|
+
export * from './get-store-order-document'
|
|
5
|
+
export * from './get-store-order-packages'
|
|
6
|
+
export * from './get-store-order-package'
|
|
7
|
+
export * from './get-store-product-attributes'
|
|
8
|
+
export * from './get-store-product-categories'
|
|
9
|
+
export * from './get-store-product'
|
|
10
|
+
export * from './get-store-products'
|
|
11
|
+
export * from './update-store-product-variation-stock'
|
|
12
|
+
export * from './update-store-product-variation-price'
|
|
13
|
+
export * from './update-order-status'
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function updateOrderStatus() {
|
|
2
|
+
return {
|
|
3
|
+
path: '/api/order/rts',
|
|
4
|
+
method: 'post',
|
|
5
|
+
async denormalize(req, { store }) {
|
|
6
|
+
let { orderId, status } = req
|
|
7
|
+
|
|
8
|
+
if (status == 'ready_to_ship') {
|
|
9
|
+
return {
|
|
10
|
+
payload: {
|
|
11
|
+
order_id: orderId
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
} else {
|
|
15
|
+
return
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
normalize(res) {
|
|
19
|
+
return res
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export function updateStoreProductVariationPrice() {
|
|
2
|
+
return {
|
|
3
|
+
path: '/api/products/prices',
|
|
4
|
+
method: 'put',
|
|
5
|
+
denormalize(req) {
|
|
6
|
+
const { variationId, sellPrice, productId } = (Array.isArray(req) ? req[0] : req) || {}
|
|
7
|
+
|
|
8
|
+
return {
|
|
9
|
+
payload: {
|
|
10
|
+
product_id: productId,
|
|
11
|
+
skus: [
|
|
12
|
+
{
|
|
13
|
+
id: variationId,
|
|
14
|
+
original_price: sellPrice.toString()
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
normalize(res) {
|
|
21
|
+
return res
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export function updateStoreProductVariationStock() {
|
|
2
|
+
return {
|
|
3
|
+
method: 'put',
|
|
4
|
+
path: '/api/products/stocks',
|
|
5
|
+
denormalize(req) {
|
|
6
|
+
const { variationId, qty, itemId } = (Array.isArray(req) ? req[0] : req) || {}
|
|
7
|
+
|
|
8
|
+
return {
|
|
9
|
+
payload: {
|
|
10
|
+
product_id: itemId,
|
|
11
|
+
skus: [
|
|
12
|
+
{
|
|
13
|
+
id: variationId,
|
|
14
|
+
stock_infos: [
|
|
15
|
+
{
|
|
16
|
+
available_stock: qty
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
normalize(res) {
|
|
25
|
+
return res
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import crypto from 'crypto'
|
|
2
|
+
import { Parameter, PublicRequestParameters } from './types'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* { key: value } => 'keyvalue'
|
|
6
|
+
* @param {Object} parameters
|
|
7
|
+
* @return {string} concatString
|
|
8
|
+
*/
|
|
9
|
+
const concatObjectKeyValue = (parameters: Parameter): string => {
|
|
10
|
+
if (!parameters) return ''
|
|
11
|
+
return Object.entries(parameters)
|
|
12
|
+
.sort(([k1, v1], [k2, v2]) => (k2 > k1 ? -1 : 1))
|
|
13
|
+
.map(([k, v]) => `${k}${v}`)
|
|
14
|
+
.join('')
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Calculate a signature hash
|
|
19
|
+
* @param {string} appSecret
|
|
20
|
+
* @param {string} apiPath e.g. /order/get
|
|
21
|
+
* @param {Object} params
|
|
22
|
+
* @return {string} signature hash
|
|
23
|
+
*/
|
|
24
|
+
export const signRequest = (appSecret: string, apiPath: string, params: Parameter): string => {
|
|
25
|
+
const hash = crypto
|
|
26
|
+
.createHmac('sha256', appSecret)
|
|
27
|
+
.update(appSecret + apiPath + concatObjectKeyValue(params) + appSecret)
|
|
28
|
+
.digest('hex')
|
|
29
|
+
|
|
30
|
+
return hash
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Gather system and business parameters to compute signature
|
|
35
|
+
* @param {string} appKey
|
|
36
|
+
* @param {string} appSecret
|
|
37
|
+
* @param {string} apiPath
|
|
38
|
+
* @param {string?} accessToken
|
|
39
|
+
* @param {Parameter?} payload
|
|
40
|
+
* @return {SystemParameters}
|
|
41
|
+
*/
|
|
42
|
+
export function makePublicRequestParameters(
|
|
43
|
+
appKey: string,
|
|
44
|
+
appSecret: string,
|
|
45
|
+
apiPath: string,
|
|
46
|
+
accessToken: string,
|
|
47
|
+
shopId: string,
|
|
48
|
+
payload?: Parameter
|
|
49
|
+
): PublicRequestParameters {
|
|
50
|
+
const ts = Math.floor(new Date(new Date().toUTCString()).getTime() / 1000).toString()
|
|
51
|
+
|
|
52
|
+
const publicRequestParams: {
|
|
53
|
+
app_key: string
|
|
54
|
+
timestamp: string
|
|
55
|
+
access_token: string
|
|
56
|
+
shop_id?: string
|
|
57
|
+
} = {
|
|
58
|
+
app_key: appKey,
|
|
59
|
+
timestamp: ts,
|
|
60
|
+
access_token: accessToken
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let signatureParams: any = {
|
|
64
|
+
app_key: publicRequestParams.app_key,
|
|
65
|
+
timestamp: publicRequestParams.timestamp
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (shopId) {
|
|
69
|
+
publicRequestParams.shop_id = shopId
|
|
70
|
+
|
|
71
|
+
signatureParams.shop_id = shopId
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
...publicRequestParams,
|
|
76
|
+
sign: signRequest(appSecret, apiPath, { ...payload, ...signatureParams })
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import fetch from 'node-fetch'
|
|
2
|
+
|
|
3
|
+
import { makePublicRequestParameters } from './signature'
|
|
4
|
+
import { Parameter } from './types'
|
|
5
|
+
|
|
6
|
+
const debug = require('debug')('things-factory:integration-marketplace:tiktok')
|
|
7
|
+
|
|
8
|
+
export type TiktokConfig = {
|
|
9
|
+
appKey: string
|
|
10
|
+
appSecret: string
|
|
11
|
+
accessToken: string
|
|
12
|
+
channelShopId: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class Tiktok {
|
|
16
|
+
private config: TiktokConfig
|
|
17
|
+
|
|
18
|
+
constructor(config: TiktokConfig) {
|
|
19
|
+
this.config = {
|
|
20
|
+
...config
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getBaseURL() {
|
|
25
|
+
return `https://open-api.tiktokglobalshop.com`
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @summary Get Method
|
|
30
|
+
* @description Using v3 API, map the consumer_key, consumer_secret to the endpoint path.
|
|
31
|
+
* X-WP-Total is to get the total items from the response
|
|
32
|
+
*/
|
|
33
|
+
async get(path: string, params: Parameter) {
|
|
34
|
+
const { appKey, appSecret, accessToken, channelShopId } = this.config
|
|
35
|
+
|
|
36
|
+
const qs = Object.entries({
|
|
37
|
+
...params,
|
|
38
|
+
...makePublicRequestParameters(appKey, appSecret, path, accessToken, channelShopId, params)
|
|
39
|
+
})
|
|
40
|
+
.map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`)
|
|
41
|
+
.join('&')
|
|
42
|
+
|
|
43
|
+
const endpoint = `${this.getBaseURL()}${path}?${qs ? qs : ''}`
|
|
44
|
+
debug('endpoint', endpoint)
|
|
45
|
+
|
|
46
|
+
const response = await fetch(endpoint, {
|
|
47
|
+
headers: {
|
|
48
|
+
'Content-Type': 'application/json'
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
var result: any = {}
|
|
53
|
+
const resResult: any = await response.json()
|
|
54
|
+
result.data = resResult.data
|
|
55
|
+
|
|
56
|
+
debug('response result', result)
|
|
57
|
+
|
|
58
|
+
return result
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async post(path: string, data: any = {}) {
|
|
62
|
+
const { appKey, appSecret, accessToken, channelShopId } = this.config
|
|
63
|
+
|
|
64
|
+
debug('data', data)
|
|
65
|
+
|
|
66
|
+
const jsondata = JSON.stringify(data)
|
|
67
|
+
|
|
68
|
+
const { app_key, timestamp, access_token, sign, shop_id } = makePublicRequestParameters(
|
|
69
|
+
appKey,
|
|
70
|
+
appSecret,
|
|
71
|
+
path,
|
|
72
|
+
accessToken,
|
|
73
|
+
channelShopId
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
const qs = Object.entries({
|
|
77
|
+
app_key,
|
|
78
|
+
timestamp,
|
|
79
|
+
access_token,
|
|
80
|
+
sign,
|
|
81
|
+
shop_id
|
|
82
|
+
})
|
|
83
|
+
.map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`)
|
|
84
|
+
.join('&')
|
|
85
|
+
|
|
86
|
+
const endpoint = `${this.getBaseURL()}${path}?${qs ? '&' + qs : ''}`
|
|
87
|
+
const response = await fetch(endpoint, {
|
|
88
|
+
method: 'post',
|
|
89
|
+
headers: {
|
|
90
|
+
'Content-Type': 'application/json'
|
|
91
|
+
},
|
|
92
|
+
body: jsondata
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
const result = await response.json()
|
|
96
|
+
debug('response result', result)
|
|
97
|
+
|
|
98
|
+
return result
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async put(path: string, data: any = {}) {
|
|
102
|
+
const { appKey, appSecret, accessToken, channelShopId } = this.config
|
|
103
|
+
|
|
104
|
+
debug('data', data)
|
|
105
|
+
|
|
106
|
+
const jsondata = JSON.stringify(data)
|
|
107
|
+
|
|
108
|
+
const { app_key, timestamp, access_token, sign } = makePublicRequestParameters(
|
|
109
|
+
appKey,
|
|
110
|
+
appSecret,
|
|
111
|
+
path,
|
|
112
|
+
accessToken,
|
|
113
|
+
channelShopId
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
const qs = Object.entries({
|
|
117
|
+
app_key,
|
|
118
|
+
timestamp,
|
|
119
|
+
access_token,
|
|
120
|
+
sign
|
|
121
|
+
})
|
|
122
|
+
.map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`)
|
|
123
|
+
.join('&')
|
|
124
|
+
|
|
125
|
+
const endpoint = `${this.getBaseURL()}${path}?${qs ? '&' + qs : ''}`
|
|
126
|
+
const response = await fetch(endpoint, {
|
|
127
|
+
method: 'put',
|
|
128
|
+
headers: {
|
|
129
|
+
'Content-Type': 'application/json'
|
|
130
|
+
},
|
|
131
|
+
body: jsondata
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
const result = await response.json()
|
|
135
|
+
debug('response result', result)
|
|
136
|
+
|
|
137
|
+
return result
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type Parameter = {
|
|
2
|
+
[key: string]: any
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Tiktok Open Platform Public Request Parameters
|
|
7
|
+
* @typedef PublicRequestParameters
|
|
8
|
+
* @property {string} timestamp :mandatory
|
|
9
|
+
* @property {string} app_key :mandatory
|
|
10
|
+
* @property {string} access_token :mandatory
|
|
11
|
+
* @property {string} shop_id :mandatory
|
|
12
|
+
* @property {string} sign :mandatory
|
|
13
|
+
*/
|
|
14
|
+
export interface PublicRequestParameters {
|
|
15
|
+
timestamp: string
|
|
16
|
+
app_key: string
|
|
17
|
+
access_token: string
|
|
18
|
+
sign: string
|
|
19
|
+
shop_id?: string
|
|
20
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Tiktok } from './client/tiktok'
|
|
2
|
+
|
|
3
|
+
function substitute(path, obj) {
|
|
4
|
+
var props = []
|
|
5
|
+
var re = /{([^}]+)}/g
|
|
6
|
+
var text
|
|
7
|
+
|
|
8
|
+
while ((text = re.exec(path))) {
|
|
9
|
+
props.push(text[1])
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
var result = path
|
|
13
|
+
props.forEach(prop => {
|
|
14
|
+
let value = obj[prop.trim()]
|
|
15
|
+
result = result.replace(`{${prop}}`, value === undefined ? '' : value)
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
return result
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @summary Building Path Method and Payload
|
|
23
|
+
* @description After denormalise of data is done,
|
|
24
|
+
* platform API method will be called with its path and payload,
|
|
25
|
+
* this section is to build path and substitution of the resource in url as well as the payload for body request.
|
|
26
|
+
* Every Tiktok API call requires consumer_key, consumer_secret, access_token.
|
|
27
|
+
* consumer_key, consumer_secret, access_token are retrieved from tokencraft
|
|
28
|
+
* to avoid permission error from TikTok.
|
|
29
|
+
*/
|
|
30
|
+
export const action = async ({ store, method = 'get', path, request }) => {
|
|
31
|
+
const client = new Tiktok({
|
|
32
|
+
appKey: store.accessKey || '5p6q6g',
|
|
33
|
+
appSecret: store.accessSecret || 'c30cf452265ab418514bb81fa49fc333aecbf081',
|
|
34
|
+
accessToken: store.accessToken,
|
|
35
|
+
channelShopId: store.channelShopId
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
const { resource = {}, payload = {} } = request
|
|
39
|
+
|
|
40
|
+
path = substitute(path, resource)
|
|
41
|
+
|
|
42
|
+
var response = await client[method](path, payload)
|
|
43
|
+
if (response.code) {
|
|
44
|
+
throw response
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return response
|
|
48
|
+
}
|
|
@@ -17,7 +17,6 @@ export function getStoreProducts() {
|
|
|
17
17
|
return { payload }
|
|
18
18
|
},
|
|
19
19
|
async normalize(res, { store }) {
|
|
20
|
-
|
|
21
20
|
const { items, totalItems: totalProducts } = res
|
|
22
21
|
|
|
23
22
|
let results: any[] = []
|
|
@@ -36,13 +35,17 @@ export function getStoreProducts() {
|
|
|
36
35
|
images: product.images.map(image => {
|
|
37
36
|
return image.src
|
|
38
37
|
}),
|
|
39
|
-
attributes:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
attributes:
|
|
39
|
+
product?.attributes?.map(attribute => {
|
|
40
|
+
return {
|
|
41
|
+
attributeId: attribute.id,
|
|
42
|
+
name: attribute.name,
|
|
43
|
+
originalValue: attribute.options,
|
|
44
|
+
native_attribute_id: attribute.id,
|
|
45
|
+
attribute_key: attribute.name,
|
|
46
|
+
values: attribute.options
|
|
47
|
+
}
|
|
48
|
+
}) || [],
|
|
46
49
|
isVerified: product.purchasable,
|
|
47
50
|
variations:
|
|
48
51
|
productVariations.length === 0
|
|
@@ -57,13 +60,17 @@ export function getStoreProducts() {
|
|
|
57
60
|
primaryUnitValue: product.weight === '' ? null : parseFloat(product.weight),
|
|
58
61
|
costPrice: product.price === '' ? null : parseFloat(product.price),
|
|
59
62
|
sellPrice: product.sale_price === '' ? null : parseFloat(product.sale_price),
|
|
60
|
-
attributes:
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
attributes:
|
|
64
|
+
product?.attributes?.map(attribute => {
|
|
65
|
+
return {
|
|
66
|
+
attributeId: attribute.id,
|
|
67
|
+
name: attribute.name,
|
|
68
|
+
originalValue: attribute.options,
|
|
69
|
+
native_attribute_id: attribute.id,
|
|
70
|
+
attribute_key: attribute.name,
|
|
71
|
+
values: attribute.options
|
|
72
|
+
}
|
|
73
|
+
}) || [],
|
|
67
74
|
isEnabled: product.purchasable,
|
|
68
75
|
length: product.dimensions.length * 10,
|
|
69
76
|
width: product.dimensions.width * 10,
|
|
@@ -83,13 +90,17 @@ export function getStoreProducts() {
|
|
|
83
90
|
primaryUnitValue: variant.weight === '' ? null : parseFloat(variant.weight),
|
|
84
91
|
costPrice: variant.price === '' ? null : parseFloat(variant.price),
|
|
85
92
|
sellPrice: variant.sale_price === '' ? null : parseFloat(variant.sale_price),
|
|
86
|
-
attributes:
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
+
attributes:
|
|
94
|
+
variant?.attributes?.map(attribute => {
|
|
95
|
+
return {
|
|
96
|
+
attributeId: attribute.id,
|
|
97
|
+
name: attribute.name,
|
|
98
|
+
originalValue: attribute.options,
|
|
99
|
+
native_attribute_id: attribute.id,
|
|
100
|
+
attribute_key: attribute.name,
|
|
101
|
+
values: [attribute.option]
|
|
102
|
+
}
|
|
103
|
+
}) || [],
|
|
93
104
|
isEnabled: variant.purchasable,
|
|
94
105
|
length: variant.dimensions.length * 10,
|
|
95
106
|
width: variant.dimensions.width * 10,
|