I’m building shopify app using Express and React.
I made api to delete soldout items (quantity = 0)
This is shopify.js file.
import { BillingInterval, LATEST_API_VERSION } from '@shopify/shopify-api';
import { shopifyApp } from '@shopify/shopify-app-express';
import { MongoDBSessionStorage } from '@shopify/shopify-app-session-storage-mongodb';
import { restResources } from '@shopify/shopify-api/rest/admin/2024-04';
import dotenv from 'dotenv';
dotenv.config();
const shopify = shopifyApp({
api: {
apiVersion: LATEST_API_VERSION,
restResources,
billing: undefined
},
auth: {
path: '/api/auth',
callbackPath: '/api/auth/callback'
},
webhooks: {
path: '/api/webhooks'
},
// This should be replaced with your preferred storage strategy
sessionStorage: new MongoDBSessionStorage(
process.env.DATABASE_URL,
process.env.DATABASE_NAME
)
});
export default shopify;
initial file index.js.
// @ts-check
import { join } from 'path';
import { readFileSync } from 'fs';
import express from 'express';
import serveStatic from 'serve-static';
import shopify from './shopify.js';
import productCreator from './product-creator.js';
import PrivacyWebhookHandlers from './privacy.js';
import deleteSoldOutItems from './deleteSoldOutItems.js';
const PORT = parseInt(
process.env.BACKEND_PORT || process.env.PORT || '3000',
10
);
const STATIC_PATH =
process.env.NODE_ENV === 'production'
? `${process.cwd()}/frontend/dist`
: `${process.cwd()}/frontend/`;
const app = express();
// Set up Shopify authentication and webhook handling
app.get(shopify.config.auth.path, shopify.auth.begin());
app.get(
shopify.config.auth.callbackPath,
shopify.auth.callback(),
shopify.redirectToShopifyOrAppRoot()
);
app.post(
shopify.config.webhooks.path,
shopify.processWebhooks({ webhookHandlers: PrivacyWebhookHandlers })
);
// If you are adding routes outside of the /api path, remember to
// also add a proxy rule for them in web/frontend/vite.config.js
app.use('/api/*', shopify.validateAuthenticatedSession());
app.use(express.json());
app.delete('/api/products/delete-sold-out', async (_req, res) => {
let status = 200;
let error = null;
try {
await deleteSoldOutItems(res.locals.shopify.session);
} catch (e) {
console.log(`Failed to delete sold-out products: ${e.message}`);
status = 500;
error = e.message;
}
res.status(status).send({ success: status === 200, error });
});
app.use(shopify.cspHeaders());
app.use(serveStatic(STATIC_PATH, { index: false }));
app.use('/*', shopify.ensureInstalledOnShop(), async (_req, res, _next) => {
return res
.status(200)
.set('Content-Type', 'text/html')
.send(readFileSync(join(STATIC_PATH, 'index.html')));
});
app.listen(PORT);
This is my index.jsx frontend page.
import { TitleBar } from '@shopify/app-bridge-react';
import { Layout, Page, Button } from '@shopify/polaris';
import { useAuthenticatedFetch } from '../hooks/index.js';
export default function HomePage() {
const fetch = useAuthenticatedFetch();
const handleArchive = async () => {
try {
await fetch('/api/products/delete-sold-out', {
method: 'DELETE'
});
} catch (error) {
console.error('Failed to archive sold out items:', error);
}
};
return (
<Page narrowWidth>
<TitleBar title='Auto archive sold out items' primaryAction={null} />
<Layout>
<Layout.Section>
<Button primary onClick={handleArchive}>
Archive sold out items
</Button>
</Layout.Section>
</Layout>
</Page>
);
}
I deployed it on Heroku.
When I installed the app everything worked fine.
What I need is to implement this functionality automatically.
I know I can use the Heroku scheduler for that, but I do not know how to implement it with Shopify apps.
Shopify version is (2024-04).
Abdallah Tanna is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.