Shopify与NetSuite间第二代Google Cloud Function转发不稳定问题
问题:Shopify Webhook转发至NetSuite RESTlet间歇性返回403错误
我正尝试通过第二代Google Cloud Function将Shopify的order/create webhook数据转发至NetSuite RESTlet,采用NetSuite的TBA(基于令牌的认证)方式完成鉴权。目前该功能仅能间歇性正常工作,多数情况下会返回403错误(AxiosError: Request failed with status code 403 at settle),这说明consumer key和consumer secret至少是正确的。这是我首次使用Google Cloud Function,可能忽略了一些基础运行机制。
最新版本的代码与之前可正常运行版本的唯一区别是将script ID存储为环境变量,代码如下:
const axios = require('axios'); const crypto = require('crypto'); exports.shopifyToNetSuite = (req, res) => { let data = JSON.stringify(req.body); const realm = process.env.REALM; const consumerKey = process.env.CONSUMER_KEY; const consumerSecret = process.env.CONSUMER_SECRET; const tokenId = process.env.TOKEN_ID; const tokenSecret = process.env.TOKEN_SECRET; const scriptId = process.env.SCRIPT_ID; const timestamp = generateOAuthTimestamp(); const oauthNonce = crypto.randomBytes(16).toString('base64'); const oauthSignature = generateOAuthSignature(); function generateOAuthTimestamp() { const date = new Date(); return Math.floor(date.getTime() / 1000); } function generateOAuthSignature() { // Step 1: Generate Base String const httpMethod = 'POST'; const baseURL = `https://${realm}.restlets.api.netsuite.com/app/site/hosting/restlet.nl`; const parameters = { oauth_consumer_key: consumerKey, oauth_nonce: oauthNonce, oauth_signature_method: 'HMAC-SHA256', oauth_timestamp: timestamp, oauth_token: tokenId, oauth_version: '1.0', script: scriptId, deploy: '1' }; const parameterString = Object.keys(parameters) .sort() .map((key) => `${key}=${encodeURIComponent(parameters[key])}`) .join('&'); const baseString = `${httpMethod}&${encodeURIComponent(baseURL)}&${encodeURIComponent(parameterString)}`; // Step 2: Generate Signing Key const signingKey = `${encodeURIComponent(consumerSecret)}&${encodeURIComponent(tokenSecret)}`; // Step 3: Generate Signature const signature = crypto .createHmac('sha256', signingKey) .update(baseString) .digest('base64'); return signature; } let config = { method: 'post', maxBodyLength: Infinity, url: `https://${realm}.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=${scriptId}&deploy=1`, headers: { 'Content-Type': 'application/json', 'Authorization': `OAuth realm="${realm}",oauth_consumer_key="${consumerKey}",oauth_token="${tokenId}",oauth_signature_method="HMAC-SHA256",oauth_timestamp="${timestamp}",oauth_nonce="${oauthNonce}",oauth_version="1.0",oauth_signature="${oauthSignature}"`, }, data: data }; axios.request(config) .then((response) => { console.log(JSON.stringify(response.data)); }) .catch((error) => { console.log(error); }); };
我已尝试过一些排查措施,但均未解决问题:
- 将User-Agent请求头改为
Mozilla/5(因Shopify默认发送的是"Shopify-Captain-Hook",曾看到论坛提到Suitelets不接受该头,推测RESTlet可能也有此限制,但调整后无效果); - 使用
oauth-1.0a包构建请求,但未成功。
内容的提问来源于stack exchange,提问作者ampsy
相关产品推荐
相关产品推荐

