135 lines
3.3 KiB
JavaScript
135 lines
3.3 KiB
JavaScript
const axios = require("axios");
|
|
const { log } = require("./logger");
|
|
|
|
const getLocationQuery = `
|
|
query {
|
|
locations(first: 1, query: "name:'Shop location'") {
|
|
nodes {
|
|
id
|
|
name
|
|
address {
|
|
address1
|
|
address2
|
|
city
|
|
province
|
|
provinceCode
|
|
country
|
|
countryCode
|
|
zip
|
|
phone
|
|
}
|
|
}
|
|
}
|
|
}
|
|
`;
|
|
|
|
async function getStoreAddress(client) {
|
|
const response = await client.post("", { query: getLocationQuery });
|
|
const location = response.data?.data?.locations?.nodes?.[0];
|
|
return location?.address || null;
|
|
}
|
|
|
|
function createLocationMutation(address) {
|
|
return `
|
|
mutation {
|
|
locationAdd(input: {
|
|
name: "(App) Race Nation Distribution"
|
|
address: {
|
|
address1: "${address?.address1 || ""}"
|
|
address2: "${address?.address2 || ""}"
|
|
city: "${address?.city || ""}"
|
|
provinceCode: "${address?.provinceCode || "ON"}"
|
|
countryCode: ${JSON.stringify(address?.countryCode || "US")}
|
|
zip: "${address?.zip || ""}"
|
|
phone: "${address?.phone || ""}"
|
|
}
|
|
fulfillsOnlineOrders: true
|
|
}) {
|
|
location {
|
|
id
|
|
name
|
|
}
|
|
userErrors {
|
|
code
|
|
field
|
|
message
|
|
}
|
|
}
|
|
}
|
|
`;
|
|
}
|
|
|
|
async function createCustomLocation(address, client) {
|
|
const response = await client.post("", { query: createLocationMutation(address) });
|
|
return response.data?.data?.locationAdd || { location: null, userErrors: [] };
|
|
}
|
|
|
|
async function createFulfillmentService(shop, accessToken) {
|
|
const client = axios.create({
|
|
baseURL: `https://${shop}/admin/api/2025-10/graphql.json`,
|
|
headers: {
|
|
"X-Shopify-Access-Token": accessToken,
|
|
"Content-Type": "application/json",
|
|
},
|
|
});
|
|
|
|
const mutation = `
|
|
mutation {
|
|
fulfillmentServiceCreate(
|
|
name: "Race Nation Distribution"
|
|
callbackUrl: "https://backend.race-nation.com/fulfillment"
|
|
) {
|
|
fulfillmentService {
|
|
id
|
|
serviceName
|
|
callbackUrl
|
|
handle
|
|
location {
|
|
id
|
|
}
|
|
}
|
|
userErrors {
|
|
field
|
|
message
|
|
}
|
|
}
|
|
}
|
|
`;
|
|
|
|
try {
|
|
log(shop, "Creating fulfillment service...");
|
|
const response = await client.post("", { query: mutation });
|
|
const data = response.data?.data?.fulfillmentServiceCreate;
|
|
|
|
if (data?.userErrors?.length) {
|
|
return { success: false, errors: data.userErrors };
|
|
}
|
|
|
|
const address = await getStoreAddress(client);
|
|
let locationId = data?.fulfillmentService?.location?.id || null;
|
|
|
|
if (address) {
|
|
const customLocation = await createCustomLocation(address, client);
|
|
if (!customLocation?.userErrors?.length && customLocation?.location?.id) {
|
|
locationId = customLocation.location.id;
|
|
}
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
fulfillmentService: data?.fulfillmentService || null,
|
|
locationId,
|
|
};
|
|
} catch (error) {
|
|
log(shop, `Fulfillment service request failed: ${error.response ? JSON.stringify(error.response.data) : error.message}`);
|
|
return {
|
|
success: false,
|
|
error: error.response ? error.response.data : error.message,
|
|
};
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
createFulfillmentService,
|
|
};
|