import { authenticate } from "../shopify.server"; export async function getTurn14AccessTokenFromMetafield(request) { const { admin, session } = await authenticate.admin(request); const shop = session.shop; // Step 1: Get credentials from metafield const gqlRes = await admin.graphql(` { shop { id metafield(namespace: "turn14", key: "credentials") { value } } } `); const result = await gqlRes.json(); const shopId = result?.data?.shop?.id; const raw = result?.data?.shop?.metafield?.value; if (!raw) { throw new Error("❌ No Turn14 credentials found in Shopify metafield."); } let creds; try { creds = JSON.parse(raw); } catch (err) { console.error("❌ Failed to parse Turn14 metafield JSON:", err); throw new Error("Malformed Turn14 credential metafield."); } const now = new Date(); const expiresAt = new Date(creds.expiresAt); const isExpired = now > expiresAt; if (!isExpired && creds.accessToken) { return creds.accessToken; } // ⏰ Expired — refresh token from Turn14 API const response = await fetch("https://turn14.data4autos.com/v1/auth/token", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ grant_type: "client_credentials", client_id: creds.clientId, client_secret: creds.clientSecret, }), }); const data = await response.json(); if (!response.ok) { console.error("❌ Failed to refresh Turn14 token:", data); throw new Error(data.error || "Failed to refresh Turn14 token"); } const newToken = data.access_token; const newExpiresAt = new Date(Date.now() + 3600 * 1000).toISOString(); const newValue = JSON.stringify({ clientId: creds.clientId, clientSecret: creds.clientSecret, accessToken: newToken, expiresAt: newExpiresAt, }).replace(/"/g, '\\"'); // Step 3: Update metafield in Shopify await admin.graphql(` mutation { metafieldsSet(metafields: [ { ownerId: "${shopId}" namespace: "turn14" key: "credentials" type: "json" value: "${newValue}" } ]) { userErrors { field message } } } `); return newToken; }