Flowobject
object
Contains functions for verifying Shopify Flow extensions.
See the Flow documentation for more information.
Verifies requests coming from Shopify Flow extensions.
Anchor to authenticate.flow-parametersParameters
- Anchor to requestrequestRequestrequired
Promise<<ConfigArg, Resources>>
AuthenticateFlow
- request
Request
Promise<FlowContext<ConfigArg, Resources>>
export type AuthenticateFlow<
ConfigArg extends AppConfigArg,
Resources extends ShopifyRestResources = ShopifyRestResources,
> = (request: Request) => Promise<FlowContext<ConfigArg, Resources>>;
FlowContext
- admin
An admin context for the Flow request. Returned only if there is a session for the shop.
AdminApiContext<ConfigArg, Resources>
- payload
The payload from the Flow request.
any
- session
A session with an offline token for the shop. Returned only if there is a session for the shop.
Session
export interface FlowContext<
ConfigArg extends AppConfigArg,
Resources extends ShopifyRestResources = ShopifyRestResources,
> {
/**
* A session with an offline token for the shop.
*
* Returned only if there is a session for the shop.
*
* @example
* <caption>Shopify session for the Flow request.</caption>
* <description>Use the session associated with this request.</description>
* ```ts
* // /app/routes/flow.tsx
* import { ActionFunctionArgs } from "@remix-run/node";
* import { authenticate } from "../shopify.server";
*
* export const action = async ({ request }: ActionFunctionArgs) => {
* const { session, admin } = await authenticate.flow(request);
*
* console.log(session.id)
*
* return new Response();
* };
* ```
*/
session: Session;
/**
* The payload from the Flow request.
*
* @example
* <caption>Flow payload.</caption>
* <description>Get the request's POST payload.</description>
* ```ts
* // /app/routes/flow.tsx
* import { ActionFunctionArgs } from "@remix-run/node";
* import { authenticate } from "../shopify.server";
*
* export const action = async ({ request }: ActionFunctionArgs) => {
* const { payload } = await authenticate.flow(request);
* return new Response();
* };
* ```
*/
payload: any;
/**
* An admin context for the Flow request.
*
* Returned only if there is a session for the shop.
*
* @example
* <caption>Flow admin context.</caption>
* <description>Use the `admin` object in the context to interact with the Admin API.</description>
* ```ts
* // /app/routes/flow.tsx
* import { ActionFunctionArgs } from "@remix-run/node";
* import { authenticate } from "../shopify.server";
*
* export async function action({ request }: ActionFunctionArgs) {
* const { admin } = await authenticate.flow(request);
*
* const response = await admin?.graphql(
* `#graphql
* mutation populateProduct($input: ProductInput!) {
* productCreate(input: $input) {
* product {
* id
* }
* }
* }`,
* { variables: { input: { title: "Product Name" } } }
* );
*
* const productData = await response.json();
* return json({ data: productData.data });
* }
* ```
*/
admin: AdminApiContext<ConfigArg, Resources>;
}
Was this section helpful?
Set a metafield on a customer after a flow call
/app/routes/**.ts
import {type ActionFunctionArgs} from '@remix-run/node';
import {authenticate} from '../shopify.server';
export const action = async ({request}: ActionFunctionArgs) => {
const {admin, payload} = await authenticate.flow(request);
const customerId = payload.properties.customer_id;
const response = await admin.graphql(
`#graphql
mutation setMetafield($customerId: ID!, $time: String!) {
metafieldsSet(metafields: {
ownerId: $customerId
namespace: "my-app",
key: "last_flow_update",
value: $time,
type: "string",
}) {
metafields {
key
value
}
}
}
`,
{
variables: {
customerId,
time: new Date().toISOString(),
},
},
);
const body = await response.json();
console.log('Updated value', body.data!.metafieldsSet!.metafields![0].value);
return new Response();
};
examples
Set a metafield on a customer after a flow call
description
Handle a flow action call
/app/routes/**.ts
import {type ActionFunctionArgs} from '@remix-run/node'; import {authenticate} from '../shopify.server'; export const action = async ({request}: ActionFunctionArgs) => { const {admin, payload} = await authenticate.flow(request); const customerId = payload.properties.customer_id; const response = await admin.graphql( `#graphql mutation setMetafield($customerId: ID!, $time: String!) { metafieldsSet(metafields: { ownerId: $customerId namespace: "my-app", key: "last_flow_update", value: $time, type: "string", }) { metafields { key value } } } `, { variables: { customerId, time: new Date().toISOString(), }, }, ); const body = await response.json(); console.log('Updated value', body.data!.metafieldsSet!.metafields![0].value); return new Response(); };
Anchor to examplesExamples
Anchor to example-flow-admin-contextFlow admin context
Use the admin
object in the context to interact with the Admin API.
Was this section helpful?
Flow admin context
/app/routes/flow.tsx
import { ActionFunctionArgs } from "@remix-run/node";
import { authenticate } from "../shopify.server";
export async function action({ request }: ActionFunctionArgs) {
const { admin } = await authenticate.flow(request);
const response = await admin?.graphql(
`#graphql
mutation populateProduct($input: ProductInput!) {
productCreate(input: $input) {
product {
id
}
}
}`,
{ variables: { input: { title: "Product Name" } } }
);
const productData = await response.json();
return json({ data: productData.data });
}
examples
Flow admin context
description
Use the `admin` object in the context to interact with the Admin API.
/app/routes/flow.tsx
import { ActionFunctionArgs } from "@remix-run/node"; import { authenticate } from "../shopify.server"; export async function action({ request }: ActionFunctionArgs) { const { admin } = await authenticate.flow(request); const response = await admin?.graphql( `#graphql mutation populateProduct($input: ProductInput!) { productCreate(input: $input) { product { id } } }`, { variables: { input: { title: "Product Name" } } } ); const productData = await response.json(); return json({ data: productData.data }); }
Anchor to example-payloadpayload
Anchor to example-flow-payloadFlow payload
Get the request's POST payload.
Was this section helpful?
Flow payload
/app/routes/flow.tsx
import { ActionFunctionArgs } from "@remix-run/node";
import { authenticate } from "../shopify.server";
export const action = async ({ request }: ActionFunctionArgs) => {
const { payload } = await authenticate.flow(request);
return new Response();
};
examples
Flow payload
description
Get the request's POST payload.
/app/routes/flow.tsx
import { ActionFunctionArgs } from "@remix-run/node"; import { authenticate } from "../shopify.server"; export const action = async ({ request }: ActionFunctionArgs) => { const { payload } = await authenticate.flow(request); return new Response(); };
Anchor to example-sessionsession
Anchor to example-shopify-session-for-the-flow-requestShopify session for the Flow request
Use the session associated with this request.
Was this section helpful?
Shopify session for the Flow request
/app/routes/flow.tsx
import { ActionFunctionArgs } from "@remix-run/node";
import { authenticate } from "../shopify.server";
export const action = async ({ request }: ActionFunctionArgs) => {
const { session, admin } = await authenticate.flow(request);
console.log(session.id)
return new Response();
};
examples
Shopify session for the Flow request
description
Use the session associated with this request.
/app/routes/flow.tsx
import { ActionFunctionArgs } from "@remix-run/node"; import { authenticate } from "../shopify.server"; export const action = async ({ request }: ActionFunctionArgs) => { const { session, admin } = await authenticate.flow(request); console.log(session.id) return new Response(); };