delete/create api
This commit is contained in:
@@ -1,65 +1,205 @@
|
|||||||
import fetch from "node-fetch";
|
import fetch from "node-fetch";
|
||||||
import fetchEbayUserToken from "../utils/fetchEbayUserToken.js";
|
import fetchEbayUserToken from "../utils/fetchEbayUserToken.js";
|
||||||
|
|
||||||
export const addItem = async (req, res) => {
|
export const createAndListItem = async (req, res) => {
|
||||||
const itemDetails = req.body;
|
const {
|
||||||
// must be called with req/res due to cookie access - cookie flow is inside fetchEbayUserToken()
|
sku,
|
||||||
const token = await fetchEbayUserToken(req, res)
|
marketplaceId,
|
||||||
|
format,
|
||||||
|
availableQuantity,
|
||||||
|
categoryId,
|
||||||
|
condition,
|
||||||
|
listingDescription,
|
||||||
|
pricingSummary,
|
||||||
|
merchantLocationKey,
|
||||||
|
quantityLimitPerBuyer,
|
||||||
|
product, // Extract the entire product object
|
||||||
|
packageWeightAndSize, // Adjusted to packageWeightAndSize from the refined payload
|
||||||
|
imageUrls,
|
||||||
|
} = req.body;
|
||||||
|
|
||||||
// Constructing the payload for the Inventory API
|
const token = await fetchEbayUserToken(req, res); // Get the eBay user token
|
||||||
const offerPayload = {
|
|
||||||
sku: itemDetails.sku,
|
|
||||||
marketplaceId: itemDetails.marketplaceId,
|
let dynamicAspects = {};
|
||||||
format: itemDetails.format,
|
for (const [key, value] of Object.entries(product.aspects)) {
|
||||||
listingDescription: itemDetails.listingDescription,
|
dynamicAspects[key] = Array.isArray(value) ? value : [value];
|
||||||
availableQuantity: itemDetails.availableQuantity,
|
}
|
||||||
categoryId: itemDetails.categoryId,
|
|
||||||
listingPolicies: {
|
|
||||||
paymentPolicyId: itemDetails.listingPolicies.paymentPolicyId,
|
|
||||||
fulfillmentPolicyId: itemDetails.listingPolicies.fulfillmentPolicyId,
|
|
||||||
returnPolicyId: itemDetails.listingPolicies.returnPolicyId,
|
|
||||||
},
|
|
||||||
pricingSummary: {
|
|
||||||
price: {
|
|
||||||
currency: itemDetails.pricingSummary.price.currency,
|
|
||||||
value: itemDetails.pricingSummary.price.value,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
merchantLocationKey: itemDetails.merchantLocationKey,
|
|
||||||
quantityLimitPerBuyer: itemDetails.quantityLimitPerBuyer,
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
// Create the inventory item
|
||||||
"https://api.ebay.com/sell/inventory/v1/offer",
|
const inventoryItemPayload = {
|
||||||
|
sku,
|
||||||
|
condition,
|
||||||
|
product: {
|
||||||
|
title: product.title.substring(0, 80), // Utilizing product title
|
||||||
|
brand: product.brand, // Using brand from the product object
|
||||||
|
description: product.description, // Using product description
|
||||||
|
imageUrls: product.imageUrls, // Using all imageUrls from product
|
||||||
|
aspects: dynamicAspects
|
||||||
|
},
|
||||||
|
availability: {
|
||||||
|
shipToLocationAvailability: {
|
||||||
|
quantity: availableQuantity,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Package weight and dimensions, adjusted to the new structure
|
||||||
|
packageWeightAndSize: {
|
||||||
|
weight: {
|
||||||
|
value: parseFloat(packageWeightAndSize.weight.value),
|
||||||
|
unit: packageWeightAndSize.weight.unit,
|
||||||
|
},
|
||||||
|
dimensions: {
|
||||||
|
length: parseFloat(packageWeightAndSize.dimensions.length),
|
||||||
|
width: parseFloat(packageWeightAndSize.dimensions.width),
|
||||||
|
height: parseFloat(packageWeightAndSize.dimensions.height),
|
||||||
|
unit: packageWeightAndSize.dimensions.unit,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const createItemResponse = await fetch(
|
||||||
|
`https://api.ebay.com/sell/inventory/v1/inventory_item/${sku}`,
|
||||||
|
{
|
||||||
|
method: "PUT",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Content-Language": "en-US",
|
||||||
|
"Authorization": `Bearer ${token}`,
|
||||||
|
"Accept": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(inventoryItemPayload),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Optionally, you can parse the response body if eBay's API returns useful information in it
|
||||||
|
const itemResponseData = await createItemResponse;
|
||||||
|
console.log(itemResponseData);
|
||||||
|
|
||||||
|
// 2. Create the offer for the inventory item
|
||||||
|
const offerPayload = {
|
||||||
|
sku,
|
||||||
|
marketplaceId,
|
||||||
|
format,
|
||||||
|
listing: {
|
||||||
|
categoryId,
|
||||||
|
listingDescription,
|
||||||
|
merchantLocationKey,
|
||||||
|
},
|
||||||
|
pricingSummary,
|
||||||
|
quantityLimitPerBuyer,
|
||||||
|
};
|
||||||
|
|
||||||
|
const offerResponse = await fetch(
|
||||||
|
`https://api.ebay.com/sell/inventory/v1/offer`,
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"Content-Language": "en-US",
|
"Content-Language": "en-US",
|
||||||
"Authorization": `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
},
|
},
|
||||||
body: JSON.stringify(offerPayload),
|
body: JSON.stringify(offerPayload),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(response)
|
if (!offerResponse.ok) {
|
||||||
if (!response.ok) {
|
// Handle error in creating the offer
|
||||||
const errorBody = await response.text(); // Get the response body as text
|
const errorBody = await offerResponse.text();
|
||||||
console.error(`eBay API responded with status ${response.status}: ${errorBody}`);
|
throw new Error(
|
||||||
throw new Error(`eBay API responded with status ${response.status}: ${errorBody}`);
|
`Failed to create offer: ${offerResponse.status} - ${errorBody}`
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const offerData = await offerResponse.json();
|
||||||
|
const offerId = offerData.offerId;
|
||||||
|
|
||||||
const responseData = await response.json();
|
// 3. Publish the offer to convert it into a live listing
|
||||||
res.json({ success: true, data: responseData });
|
await fetch(
|
||||||
|
`https://api.ebay.com/sell/inventory/v1/offer/${offerId}/publish/`,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
res.json({ success: true, message: "Item listed successfully" });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error adding item to eBay via Inventory API:", error);
|
console.error("Error in createAndListItem endpoint:", error);
|
||||||
console.log(error.message);
|
|
||||||
res.status(500).json({
|
res.status(500).json({
|
||||||
success: false,
|
success: false,
|
||||||
message: "Failed to add item to eBay via Inventory API",
|
message: "Failed to create and list item on eBay",
|
||||||
error: error.message,
|
error: error.message,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const deleteItemBySku = async (req, res) => {
|
||||||
|
const { sku } = req.params; // Assuming SKU is provided as a URL parameter
|
||||||
|
|
||||||
|
try {
|
||||||
|
const token = await fetchEbayUserToken(req, res); // Get the eBay user token
|
||||||
|
|
||||||
|
// Perform the deletion of the inventory item
|
||||||
|
const deleteResponse = await fetch(`https://api.ebay.com/sell/inventory/v1/inventory_item/${sku}`, {
|
||||||
|
method: "DELETE",
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Bearer ${token}`,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Accept": "application/json",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!deleteResponse.ok) {
|
||||||
|
// Handle unsuccessful deletion
|
||||||
|
const errorBody = await deleteResponse.text();
|
||||||
|
throw new Error(`Failed to delete inventory item: ${deleteResponse.status} - ${errorBody}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Successfully deleted the item
|
||||||
|
res.json({ success: true, message: `Item with SKU: ${sku} deleted successfully.` });
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error in deleteItemBySku endpoint:", error);
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: `Failed to delete item with SKU: ${sku} from eBay`,
|
||||||
|
error: error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getAllInventory = async (req, res) => {
|
||||||
|
const limit = req.query.limit || '100'; // Set default limit
|
||||||
|
const offset = req.query.offset || '0'; // Set default offset
|
||||||
|
|
||||||
|
try {
|
||||||
|
const token = await fetchEbayUserToken(req, res); // Assuming fetchEbayUserToken doesn't need req, res passed and handles token internally
|
||||||
|
|
||||||
|
const response = await fetch(`https://api.ebay.com/sell/inventory/v1/inventory_item?limit=${limit}&offset=${offset}`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Authorization": `Bearer ${token}`,
|
||||||
|
"Accept-Language": "en-US",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
// If the response is not okay, throw an error with status and statusText
|
||||||
|
throw new Error(`Failed to retrieve inventory items: ${response.status} ${response.statusText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const inventoryItems = await response.json(); // Parsing the JSON body of the response
|
||||||
|
res.json(inventoryItems); // Sending the inventory items back to the client
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching inventory:', error);
|
||||||
|
res.status(500).json({
|
||||||
|
error: 'Internal Server Error',
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
// routes/dataRoutes.js
|
// routes/dataRoutes.js
|
||||||
import express from "express";
|
import express from "express";
|
||||||
import { addItem } from "../controllers/inventoryController.js";
|
import { createAndListItem, deleteItemBySku, getAllInventory } from "../controllers/inventoryController.js";
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
router.post("/add-item", addItem);
|
router.post("/create-list-item", createAndListItem);
|
||||||
|
router.get("/delete-item-by-sku", deleteItemBySku);
|
||||||
|
router.get("/get-all-inventory", getAllInventory)
|
||||||
|
|
||||||
// You can add more data-related routes here in the future
|
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import cors from "cors";
|
|||||||
import dotenv from "dotenv";
|
import dotenv from "dotenv";
|
||||||
import dataRoutes from "./routes/dataRoutes.js";
|
import dataRoutes from "./routes/dataRoutes.js";
|
||||||
import inventoryRoutes from "./routes/inventoryRoutes.js";
|
import inventoryRoutes from "./routes/inventoryRoutes.js";
|
||||||
import cookieParser from 'cookie-parser';
|
import cookieParser from "cookie-parser";
|
||||||
|
import fetchEbayUserToken from "./utils/fetchEbayUserToken.js";
|
||||||
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
@@ -17,6 +18,35 @@ app.use(cookieParser());
|
|||||||
app.use("/api/data", dataRoutes);
|
app.use("/api/data", dataRoutes);
|
||||||
app.use("/api/inventory", inventoryRoutes);
|
app.use("/api/inventory", inventoryRoutes);
|
||||||
|
|
||||||
|
app.get("/check-inventory", async (req, res) => {
|
||||||
|
try {
|
||||||
|
const token = "v^1.1#i^1#r^0#p^3#f^0#I^3#t^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"
|
||||||
|
const limit = req.query.limit || '100'; // Default limit to 10 if not specified
|
||||||
|
const offset = req.query.offset || '0'; // Default offset to 0 if not specified
|
||||||
|
|
||||||
|
const response = await fetch(`https://api.ebay.com/sell/inventory/v1/inventory_item?limit=${limit}&offset=${offset}`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Authorization": `Bearer ${token}`,
|
||||||
|
"Accept-Language": "en-US", // Explicitly setting the Accept-Language header
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(response)
|
||||||
|
|
||||||
|
const inventoryItems = await response.json();
|
||||||
|
console.log(inventoryItems);
|
||||||
|
res.json(inventoryItems);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error checking inventory:', error);
|
||||||
|
if (!res.headersSent) {
|
||||||
|
res.status(500).json({ error: 'Internal Server Error' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
the below code needs to be encapsulated somehow. It requires a manual flow, including QUICKLY copy/pasting the code query string from the result of localhost:300/auth/ebay (below)
|
the below code needs to be encapsulated somehow. It requires a manual flow, including QUICKLY copy/pasting the code query string from the result of localhost:300/auth/ebay (below)
|
||||||
|
|
||||||
@@ -32,42 +62,48 @@ app.use("/api/inventory", inventoryRoutes);
|
|||||||
2. Add a fetchEbayUserToken endpoint and figure how to cycle user tokens every 2 hours with refresh token
|
2. Add a fetchEbayUserToken endpoint and figure how to cycle user tokens every 2 hours with refresh token
|
||||||
3. Add refresh token to .env and figure out how to safely store user tokens serverside (cookie? knowledge gap here)
|
3. Add refresh token to .env and figure out how to safely store user tokens serverside (cookie? knowledge gap here)
|
||||||
*/
|
*/
|
||||||
app.get('/auth/ebay', async (req, res) => {
|
app.get("/auth/ebay", async (req, res) => {
|
||||||
// the below URL is hardcoded because it's static in the eBay dev dashboard
|
// the below URL is hardcoded because it's static in the eBay dev dashboard
|
||||||
const authUrl = `https://auth.ebay.com/oauth2/authorize?client_id=TylerPul-ebayimpo-PRD-a983027cf-9b6b8bba&response_type=code&redirect_uri=Tyler_Pulse-TylerPul-ebayim-ledkmyo&scope=https://api.ebay.com/oauth/api_scope https://api.ebay.com/oauth/api_scope/sell.marketing.readonly https://api.ebay.com/oauth/api_scope/sell.marketing https://api.ebay.com/oauth/api_scope/sell.inventory.readonly https://api.ebay.com/oauth/api_scope/sell.inventory https://api.ebay.com/oauth/api_scope/sell.account.readonly https://api.ebay.com/oauth/api_scope/sell.account https://api.ebay.com/oauth/api_scope/sell.fulfillment.readonly https://api.ebay.com/oauth/api_scope/sell.fulfillment https://api.ebay.com/oauth/api_scope/sell.analytics.readonly https://api.ebay.com/oauth/api_scope/sell.finances https://api.ebay.com/oauth/api_scope/sell.payment.dispute https://api.ebay.com/oauth/api_scope/commerce.identity.readonly https://api.ebay.com/oauth/api_scope/sell.reputation https://api.ebay.com/oauth/api_scope/sell.reputation.readonly https://api.ebay.com/oauth/api_scope/commerce.notification.subscription https://api.ebay.com/oauth/api_scope/commerce.notification.subscription.readonly https://api.ebay.com/oauth/api_scope/sell.stores https://api.ebay.com/oauth/api_scope/sell.stores.readonly`;
|
const authUrl = `https://auth.ebay.com/oauth2/authorize?client_id=TylerPul-ebayimpo-PRD-a983027cf-9b6b8bba&response_type=code&redirect_uri=Tyler_Pulse-TylerPul-ebayim-ledkmyo&scope=https://api.ebay.com/oauth/api_scope https://api.ebay.com/oauth/api_scope/sell.marketing.readonly https://api.ebay.com/oauth/api_scope/sell.marketing https://api.ebay.com/oauth/api_scope/sell.inventory.readonly https://api.ebay.com/oauth/api_scope/sell.inventory https://api.ebay.com/oauth/api_scope/sell.account.readonly https://api.ebay.com/oauth/api_scope/sell.account https://api.ebay.com/oauth/api_scope/sell.fulfillment.readonly https://api.ebay.com/oauth/api_scope/sell.fulfillment https://api.ebay.com/oauth/api_scope/sell.analytics.readonly https://api.ebay.com/oauth/api_scope/sell.finances https://api.ebay.com/oauth/api_scope/sell.payment.dispute https://api.ebay.com/oauth/api_scope/commerce.identity.readonly https://api.ebay.com/oauth/api_scope/sell.reputation https://api.ebay.com/oauth/api_scope/sell.reputation.readonly https://api.ebay.com/oauth/api_scope/commerce.notification.subscription https://api.ebay.com/oauth/api_scope/commerce.notification.subscription.readonly https://api.ebay.com/oauth/api_scope/sell.stores https://api.ebay.com/oauth/api_scope/sell.stores.readonly`;
|
||||||
res.redirect(authUrl); // Redirect the user to eBay's sign-in page
|
res.redirect(authUrl); // Redirect the user to eBay's sign-in page
|
||||||
});
|
});
|
||||||
|
|
||||||
// Step 2: Handle the redirect from eBay
|
// Step 2: Handle the redirect from eBay
|
||||||
app.get('/auth/ebay/callback', async (req, res) => {
|
app.get("/auth/ebay/callback", async (req, res) => {
|
||||||
// this code comes from a query string at localhost:3000/auth/ebay when we redirect
|
// this code comes from a query string at localhost:3000/auth/ebay when we redirect
|
||||||
const code = 'v%5E1.1%23i%5E1%23p%5E3%23f%5E0%23r%5E1%23I%5E3%23t%5EUl41Xzc6NUE2ODc0NkU5Q0Q4N0QxQjhENTVCNzAxQTAwMEM2MzlfMF8xI0VeMjYw'
|
const code =
|
||||||
|
"v%5E1.1%23i%5E1%23p%5E3%23f%5E0%23r%5E1%23I%5E3%23t%5EUl41Xzc6NUE2ODc0NkU5Q0Q4N0QxQjhENTVCNzAxQTAwMEM2MzlfMF8xI0VeMjYw";
|
||||||
try {
|
try {
|
||||||
// Step 3: Exchange the authorization code for access and refresh tokens
|
// Step 3: Exchange the authorization code for access and refresh tokens
|
||||||
const tokenResponse = await fetch('https://api.ebay.com/identity/v1/oauth2/token', {
|
const tokenResponse = await fetch(
|
||||||
method: 'POST',
|
"https://api.ebay.com/identity/v1/oauth2/token",
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
'Authorization': `Basic ${Buffer.from(`${process.env.EBAY_CLIENT_ID}:${process.env.EBAY_CLIENT_SECRET}`).toString('base64')}`
|
Authorization: `Basic ${Buffer.from(
|
||||||
|
`${process.env.EBAY_CLIENT_ID}:${process.env.EBAY_CLIENT_SECRET}`
|
||||||
|
).toString("base64")}`,
|
||||||
},
|
},
|
||||||
// we use Tyler_Pulse-TylerPul-ebayim-ledkmyo and not the initial redirect URL
|
// we use Tyler_Pulse-TylerPul-ebayim-ledkmyo and not the initial redirect URL
|
||||||
body: `grant_type=authorization_code&code=${code}&redirect_uri=Tyler_Pulse-TylerPul-ebayim-ledkmyo`
|
body: `grant_type=authorization_code&code=${code}&redirect_uri=Tyler_Pulse-TylerPul-ebayim-ledkmyo`,
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
if (!tokenResponse.ok) {
|
if (!tokenResponse.ok) {
|
||||||
throw new Error('Failed to exchange authorization code for tokens');
|
throw new Error("Failed to exchange authorization code for tokens");
|
||||||
}
|
}
|
||||||
|
|
||||||
const tokenData = await tokenResponse.json();
|
const tokenData = await tokenResponse.json();
|
||||||
console.log('Access Token:', tokenData.access_token);
|
console.log("Access Token:", tokenData.access_token);
|
||||||
console.log('Refresh Token:', tokenData.refresh_token);
|
console.log("Refresh Token:", tokenData.refresh_token);
|
||||||
|
|
||||||
res.send('Authentication successful! Tokens acquired.'); // For demonstration purposes; you might want to redirect the user or show a different message
|
res.send("Authentication successful! Tokens acquired."); // For demonstration purposes; you might want to redirect the user or show a different message
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error during token exchange:', error);
|
console.error("Error during token exchange:", error);
|
||||||
res.status(500).send('Internal Server Error');
|
res.status(500).send("Internal Server Error");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const PORT = process.env.PORT || 3000;
|
const PORT = process.env.PORT || 3000;
|
||||||
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
|
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
|
||||||
|
|||||||
Reference in New Issue
Block a user