Add tutorial on getting accessToken and shop name and creating simple REST API call
In the current app version no information about how we can store accessToken, shop name, and use they.
server/server.js
!!! CustomSessionStorage !!!
import RedisStore from './redis-store';
const sessionStorage = new RedisStore();
Shopify.Context.initialize({
API_KEY: process.env.SHOPIFY_API_KEY,
API_SECRET_KEY: process.env.SHOPIFY_API_SECRET,
SCOPES: process.env.SCOPES.split(','),
HOST_NAME: process.env.HOST.replace(/https:\/\//, ''),
API_VERSION: ApiVersion.January21,
IS_EMBEDDED_APP: true,
SESSION_STORAGE: new Shopify.Session.CustomSessionStorage(
sessionStorage.storeCallback,
sessionStorage.loadCallback,
sessionStorage.deleteCallback,
)
});
------
!!! accessToken !!!
createShopifyAuth({
async afterAuth(ctx) {
// Access token and shop available in ctx.state.shopify
const {shop, accessToken, scope} = ctx.state.shopify;
For example, get themes (using isomorphic-fetch and koa-router):
server/routes.js
const baseURL = `https://${SHOPIFY_API_KEY}:${accessToken}@${shopOrigin}/admin/api/${ApiVersion.January21}`;
router.get('/themeId', async (ctx) => {
const res = await fetch(
`${baseUrl}/themes.json`
);
try {
ctx.body = await res.json();
ctx.status = 200;
} catch (e) {
console.log('error:', e.message);
}
});
SHOPIFY_API_KEY - is environment variable, OK But how I can save shop and accessToken?
The official tutorial doesn't contain any information about this.
Hi @SerhiDi, this app is built on the Shopify Node API library, which provides a REST client that apps can use to make requests.
You can find some documentation on how the client works and how to make requests in that repo's documentation, but essentially the shop and accessToken come from the session.
@paulomarg,
I added this code:
const session = await Shopify.Utils.loadCurrentSession(ctx.request, ctx.response, false);
console.log('SESSION', session);
const shopOrigin = session.shop;
const accessToken = session.accessToken;
const baseURL = `https://${SHOPIFY_API_KEY}:${accessToken}@${shopOrigin}/admin/api/${ApiVersion.January21}`;
router.get('/themeId', async (ctx) => {
const res = await fetch(
`${baseUrl}/themes.json`
);
try {
ctx.body = await res.json();
ctx.status = 200;
} catch (e) {
console.log('error:', e.message);
}
});
When I reload the app server and reload the app page in the browser I see:
-
when app loading (is reinstalling after server reload) I see in log 'SESSION' - session object, all OK.
-
after loading, when the app page opened, I see in log 'SESSION' - undefined
How it works? Why is there no example with Shopify.Utils.loadCurrentSession in the application code?
@paulomarg hello, Any news about this?
const session = await Shopify.Utils.loadCurrentSession(ctx.request, ctx.response, false);
console.log('SESSION', session);
// SESSION undefined
The main functionality in my app does not work and I can't complete it.
You can read the same issue here: https://github.com/Shopify/shopify-app-node/issues/619
@paulomarg, You have at least two developers who have tested the code from the tutorial and who have the same errors. Сould you please check the code you referenced? that repo's documentation
It did not shed light on why Shopify.Utils.loadCurrentSession(ctx.request, ctx.response, false); still undefined
@paulomarg hello,
What is the problem to create a simple application as an example of getting some data?
For example:
GET /admin/api/2021-04/products.json Link
In the current replies, I see only theory and links with small pieces of code(like this), which don't work with the newly generated app. I'm sure most applications use API calls, but current documentation doesn't contain a normal example of a simple request.
It would be nice if the Shopify community will receive a code example with the REST API call. I mean example with a full development cycle. Generated Nodejs/React app with current structure and files.
New project: shopify create Link
Add custom storage: Link
And API call: Link
Hi @SerhiDi, thank you for your feedback. We will take it into consideration to continue to improve our documentation. We do provide working code examples like the one I mentioned, which you can add to any action in your app as long as the request is made using authenticatedFetch in your client.
However, repeatedly mentioning me or any other team member will not expedite a response, so we ask that you please don't do that. GitHub issues are meant to track issues with our code, and we strive to address any actual problems as quickly as we can. Unfortunately, we don't have the bandwidth to support every partner individually, but we encourage partners to discuss their apps and solutions in the Community Forums, and report back to us via GitHub issues if there is evidence that our code is doing something incorrectly.
In the future, please make sure you adhere to the Code of Conduct when interacting in our repositories.
I created a new app, https://github.com/SerhiDi/session-bug
The only change is these lines: https://github.com/SerhiDi/session-bug/blob/3f8114cf8476e5fa1b2ec07e45917feef5eb1a02/server/server.js#L82-L86
If you try open app route link:
https://my-store.myshopify.com/admin/apps/app-name/token
you will get undefined.
I can state the fact that the function Shopify.Utils.loadCurrentSession does not work.
And the question remains open, how to get a token inside the route.
Also don't see an example with authenticatedFetch. I can get session token there, but not accessToken
Hello. Providing the JWT in the header resolved the undefined issue for me when trying to make a REST API call from the front end.
// pages/index.js
import { useAppBridge } from "@shopify/app-bridge-react";
import { getSessionToken, authenticatedFetch } from "@shopify/app-bridge-utils";
function Index() {
const app = useAppBridge();
//const aFetch = authenticatedFetch(app);
async function getCheckouts() {
const token = await getSessionToken(app);
const response = await fetch("/api/checkouts", {
headers: { "Authorization": `Bearer ${token}` }
});
//const response = await aFetch("/api/checkouts");
const checkouts = await response.json();
console.log(checkouts);
}
return (
<Page>
</Page>
);
}
// server/server.js
router.get("/api/:object", verifyRequest({ returnHeader: true }), async (ctx) => {
// Load the current session to get the `accessToken`.
const session = await Shopify.Utils.loadCurrentSession(ctx.req, ctx.res);
// Create a new client for the specified shop.
const client = new Shopify.Clients.Rest(session.shop, session.accessToken);
// Use `client.get` to request the specified Shopify REST API endpoint, e.g. `products`.
const results = await client.get({
path: ctx.params.object,
});
ctx.body = results.body;
ctx.res.status = 200;
});
Hope this helps anyone who is still struggling.
Hello. Providing the JWT in the header resolved the undefined issue for me when trying to make a REST API call from the front end.
// pages/index.js import { useAppBridge } from "@shopify/app-bridge-react"; import { getSessionToken, authenticatedFetch } from "@shopify/app-bridge-utils"; function Index() { const app = useAppBridge(); //const aFetch = authenticatedFetch(app); async function getCheckouts() { const token = await getSessionToken(app); const response = await fetch("/api/checkouts", { headers: { "Authorization": `Bearer ${token}` } }); //const response = await aFetch("/api/checkouts"); const checkouts = await response.json(); console.log(checkouts); } return ( <Page> </Page> ); }// server/server.js router.get("/api/:object", verifyRequest({ returnHeader: true }), async (ctx) => { // Load the current session to get the `accessToken`. const session = await Shopify.Utils.loadCurrentSession(ctx.req, ctx.res); // Create a new client for the specified shop. const client = new Shopify.Clients.Rest(session.shop, session.accessToken); // Use `client.get` to request the specified Shopify REST API endpoint, e.g. `products`. const results = await client.get({ path: ctx.params.object, }); ctx.body = results.body; ctx.res.status = 200; });Hope this helps anyone who is still struggling.
Yes it helps but still means you cannot run API calls in getServerSideProps nextjs as getSessionToken wont work as not in app bridge
This issue is stale because it has been open for 60 days with no activity. It will be closed if no further action occurs in 14 days.
Congratulations to all involved, nothing has appeared in the documentation for a year and a half.
This issue is stale because it has been open for 60 days with no activity. It will be closed if no further action occurs in 14 days.
We have made quite a few changes in the v6 of shopify-api. In particular session storage implementations (and the interface they all implement) are now in their own packages. This should give greater flexibility for developers to implement their own session storage should they want to. Or they can use one of many implementation that we provide there. I have run through the last version of the tutorial on shopify.dev and everything works as expected. Closing this one for now.