itemLookUp complete and addItem endpoint
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
import fetch from "node-fetch";
|
import fetch from "node-fetch";
|
||||||
import fetchEbayToken from "../utils/fetchEbayToken.js"; // Adjust the import path according to your project structure
|
import fetchEbayReadToken from "../utils/fetchEbayReadToken.js"; // Adjust the import path according to your project structure
|
||||||
|
|
||||||
export const itemLookup = async (req, res) => {
|
export const itemLookup = async (req, res) => {
|
||||||
const productCode = req.query.productCode;
|
const productCode = req.query.productCode;
|
||||||
const oauthToken = await fetchEbayToken();
|
const oauthToken = await fetchEbayReadToken();
|
||||||
console.log(productCode);
|
console.log(productCode);
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
// inventoryController.js
|
||||||
|
import buildAddItemRequestXML from "../utils/buildAddItemRequestXML.js";
|
||||||
|
import fetch from "node-fetch";
|
||||||
|
import fetchEbayUserToken from "../utils/fetchEbayUserToken.js"; // Adjust the import path according to your project structure
|
||||||
|
|
||||||
|
export const addItem = async (req, res) => {
|
||||||
|
const itemDetails = req.body; // Assuming item details are sent in the request body
|
||||||
|
itemDetails.userToken = await fetchEbayUserToken(); // Fetch and add the user token to itemDetails
|
||||||
|
|
||||||
|
const xmlRequest = buildAddItemRequestXML(itemDetails);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch("https://api.ebay.com/ws/api.dll", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "text/xml",
|
||||||
|
"X-EBAY-API-SITEID": "0",
|
||||||
|
"X-EBAY-API-CALL-NAME": "AddItem",
|
||||||
|
"X-EBAY-API-COMPATIBILITY-LEVEL": "967", // Ensure this is the current compatibility level
|
||||||
|
"X-EBAY-API-APP-NAME": process.env.EBAY_CLIENT_ID,
|
||||||
|
"X-EBAY-API-DEV-NAME": process.env.EBAY_DEV_ID,
|
||||||
|
"X-EBAY-API-CERT-NAME": process.env.EBAY_CLIENT_SECRET,
|
||||||
|
},
|
||||||
|
body: xmlRequest,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`eBay API responded with status ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const responseData = await response.text();
|
||||||
|
// Parse the XML response and handle it appropriately
|
||||||
|
// You might need an XML parser here to handle the response
|
||||||
|
|
||||||
|
res.json({ success: true, data: responseData }); // Send back a success response
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error adding item to eBay:", error);
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: "Failed to add item to eBay",
|
||||||
|
error: error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
12
api/routes/inventoryRoutes.js
Normal file
12
api/routes/inventoryRoutes.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
// routes/dataRoutes.js
|
||||||
|
import express from "express";
|
||||||
|
import { addItem } from "../controllers/inventoryController.js"; // Adjust the import path according to your project structure
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
// Use the itemLookup function from dataController for the GET request to '/item-lookup'
|
||||||
|
router.get("/add-item", addItem);
|
||||||
|
|
||||||
|
// You can add more data-related routes here in the future
|
||||||
|
|
||||||
|
export default router;
|
||||||
@@ -3,6 +3,7 @@ import express from "express";
|
|||||||
import cors from "cors";
|
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";
|
||||||
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
@@ -13,6 +14,7 @@ app.use(express.json());
|
|||||||
|
|
||||||
// Use the itemLookupRoute with a base path, e.g., '/api'
|
// Use the itemLookupRoute with a base path, e.g., '/api'
|
||||||
app.use("/api/data", dataRoutes);
|
app.use("/api/data", dataRoutes);
|
||||||
|
app.use("/api/inventory", inventoryRoutes);
|
||||||
|
|
||||||
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}`));
|
||||||
|
|||||||
58
api/utils/buildAddItemRequestXML.js
Normal file
58
api/utils/buildAddItemRequestXML.js
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
const buildAddItemRequestXML = (itemDetails) => {
|
||||||
|
// Constructing the XML payload using template literals
|
||||||
|
return `<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<AddItemRequest xmlns="urn:ebay:apis:eBLBaseComponents">
|
||||||
|
<RequesterCredentials>
|
||||||
|
<eBayAuthToken>${itemDetails.userToken}</eBayAuthToken>
|
||||||
|
</RequesterCredentials>
|
||||||
|
<Item>
|
||||||
|
<Title>${itemDetails.title}</Title>
|
||||||
|
<Description><![CDATA[${itemDetails.description}]]></Description>
|
||||||
|
<PrimaryCategory>
|
||||||
|
<CategoryID>${itemDetails.categoryID}</CategoryID>
|
||||||
|
</PrimaryCategory>
|
||||||
|
<StartPrice>${itemDetails.startPrice}</StartPrice>
|
||||||
|
<ConditionID>${itemDetails.conditionID}</ConditionID>
|
||||||
|
<Country>${itemDetails.country}</Country>
|
||||||
|
<Currency>${itemDetails.currency}</Currency>
|
||||||
|
<DispatchTimeMax>${itemDetails.dispatchTimeMax}</DispatchTimeMax>
|
||||||
|
<ListingDuration>${itemDetails.listingDuration}</ListingDuration>
|
||||||
|
<ListingType>${itemDetails.listingType}</ListingType>
|
||||||
|
<PaymentMethods>${itemDetails.paymentMethods}</PaymentMethods>
|
||||||
|
<PayPalEmailAddress>${itemDetails.payPalEmailAddress}</PayPalEmailAddress>
|
||||||
|
<PictureDetails>
|
||||||
|
${itemDetails.imageURLs
|
||||||
|
.map((url) => `<PictureURL>${url}</PictureURL>`)
|
||||||
|
.join("")}
|
||||||
|
</PictureDetails>
|
||||||
|
<PostalCode>${itemDetails.postalCode}</PostalCode>
|
||||||
|
<Quantity>${itemDetails.quantity}</Quantity>
|
||||||
|
<ReturnPolicy>
|
||||||
|
<ReturnsAcceptedOption>${
|
||||||
|
itemDetails.returnsAcceptedOption
|
||||||
|
}</ReturnsAcceptedOption>
|
||||||
|
<RefundOption>${itemDetails.refundOption}</RefundOption>
|
||||||
|
<ReturnsWithinOption>${
|
||||||
|
itemDetails.returnsWithinOption
|
||||||
|
}</ReturnsWithinOption>
|
||||||
|
<Description>${itemDetails.returnPolicyDescription}</Description>
|
||||||
|
<ShippingCostPaidByOption>${
|
||||||
|
itemDetails.shippingCostPaidByOption
|
||||||
|
}</ShippingCostPaidByOption>
|
||||||
|
</ReturnPolicy>
|
||||||
|
<ShippingDetails>
|
||||||
|
<ShippingType>${itemDetails.shippingType}</ShippingType>
|
||||||
|
<ShippingServiceOptions>
|
||||||
|
<ShippingServicePriority>1</ShippingServicePriority>
|
||||||
|
<ShippingService>${itemDetails.shippingService}</ShippingService>
|
||||||
|
<ShippingServiceCost>${
|
||||||
|
itemDetails.shippingServiceCost
|
||||||
|
}</ShippingServiceCost>
|
||||||
|
</ShippingServiceOptions>
|
||||||
|
</ShippingDetails>
|
||||||
|
<Site>${itemDetails.site}</Site>
|
||||||
|
</Item>
|
||||||
|
</AddItemRequest>`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default buildAddItemRequestXML;
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
|
// Need to figoure out expiration and make sure to cycle this appropriately to avoid unnecessary calls
|
||||||
import fetch from "node-fetch";
|
import fetch from "node-fetch";
|
||||||
|
|
||||||
const fetchEbayToken = async () => {
|
const fetchEbayReadToken = async () => {
|
||||||
const ebayClientId = process.env.EBAY_CLIENT_ID;
|
const ebayClientId = process.env.EBAY_CLIENT_ID;
|
||||||
const ebayClientSecret = process.env.EBAY_CLIENT_SECRET;
|
const ebayClientSecret = process.env.EBAY_CLIENT_SECRET;
|
||||||
const credentials = Buffer.from(
|
const credentials = Buffer.from(
|
||||||
@@ -35,4 +36,4 @@ const fetchEbayToken = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default fetchEbayToken;
|
export default fetchEbayReadToken;
|
||||||
41
api/utils/fetchEbayUserToken.js
Normal file
41
api/utils/fetchEbayUserToken.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import fetch from "node-fetch";
|
||||||
|
|
||||||
|
const fetchEbayUserToken = async (authorizationCode) => {
|
||||||
|
const clientId = process.env.EBAY_CLIENT_ID;
|
||||||
|
const clientSecret = process.env.EBAY_CLIENT_SECRET;
|
||||||
|
const redirectUri = process.env.EBAY_REDIRECT_URI; // Make sure this matches the URI registered with eBay
|
||||||
|
const credentials = Buffer.from(`${clientId}:${clientSecret}`).toString(
|
||||||
|
"base64"
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(
|
||||||
|
"https://api.ebay.com/identity/v1/oauth2/token",
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
|
Authorization: `Basic ${credentials}`,
|
||||||
|
},
|
||||||
|
body: `grant_type=authorization_code&code=${authorizationCode}&redirect_uri=${encodeURIComponent(
|
||||||
|
redirectUri
|
||||||
|
)}`,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorBody = await response.text();
|
||||||
|
throw new Error(
|
||||||
|
`Failed to fetch eBay user token: ${response.status} ${response.statusText} - ${errorBody}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
return data.access_token; // This is the User access token
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching eBay user token:", error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default fetchEbayUserToken;
|
||||||
Reference in New Issue
Block a user