dreame-action/scripts/setup-metaobject.ts

94 lines
2.7 KiB
TypeScript

type GraphqlResponse<T> = {
data?: T;
errors?: unknown;
};
type UserError = {
field?: string[];
message: string;
};
const shop = requiredEnv("SHOPIFY_SHOP_DOMAIN");
const token = requiredEnv("SHOPIFY_ADMIN_ACCESS_TOKEN");
const metaobjectType = process.env.METAOBJECT_TYPE || "$app:dreame_activity";
const metaobjectHandle = process.env.METAOBJECT_HANDLE || "dreame-activity-config";
const endpoint = `https://${shop}/admin/api/2026-01/graphql.json`;
const metaobjectMutation = `#graphql
mutation DreameMetaobjectUpsert($handle: MetaobjectHandleInput!, $metaobject: MetaobjectUpsertInput!) {
metaobjectUpsert(handle: $handle, metaobject: $metaobject) {
metaobject {
id
handle
}
userErrors {
field
message
}
}
}
`;
async function main() {
const result = await graphql<{
metaobjectUpsert?: {
userErrors: UserError[];
};
}>(metaobjectMutation, {
handle: {
type: metaobjectType,
handle: metaobjectHandle,
},
metaobject: {
fields: [
{ key: "activity_id", value: "12" },
{ key: "api_app_id", value: "mock-app-id" },
{ key: "api_secret", value: "mock-secret" },
{ key: "status_api_url", value: "https://third-party.example/status" },
{ key: "push_api_url", value: "https://third-party.example/push" },
{ key: "status_success_code", value: "0" },
{ key: "status_active_required", value: "true" },
{ key: "push_success_code", value: "0" },
{ key: "redirect_url", value: "https://activity.example.com" },
{ key: "button_text", value: JSON.stringify({ en: "Claim Your Reward", "zh-CN": "领取奖励" }) },
{ key: "shop", value: shop },
],
},
});
const userErrors = result.data?.metaobjectUpsert?.userErrors || [];
if (userErrors.length) {
throw new Error(JSON.stringify(userErrors));
}
}
async function graphql<T>(query: string, variables: Record<string, unknown>): Promise<GraphqlResponse<T>> {
const response = await fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Shopify-Access-Token": token,
},
body: JSON.stringify({ query, variables }),
});
const payload = (await response.json()) as GraphqlResponse<T>;
if (!response.ok || payload.errors) {
throw new Error(JSON.stringify(payload.errors || payload));
}
console.log(JSON.stringify(payload, null, 2));
return payload;
}
function requiredEnv(name: string): string {
const value = process.env[name];
if (!value) {
throw new Error(`${name} is required`);
}
return value;
}
main().catch((error) => {
console.error(error);
process.exit(1);
});