Funções de transformação
O mapeamento extrai valores de uma solicitação. Uma função de transformação vai além: trata-se de seu próprio código JavaScript, executado em todas as solicitações antes de Shopify Flow, para que você possa reformular a Payload, consultar alguma informação, decidir se vale a pena executar um fluxo de trabalho para essa solicitação ou responder diretamente ao solicitante.
Essa opção está disponível na guia “Função” de um webhook. Um editor vazio significa que a função está desativada.
A forma de uma função
export default async function transform(payload, ctx) {
// payload - the parsed request body (JSON, form or XML)
// return an object -> it becomes the payload for mapping and Flow
// return null -> nothing is sent to Flow, and nothing counts
return { ...payload, source: "warehouse" }
}O que o site ctx oferece a você
ctx.request |
method, contentType, a solicitação headers (informações confidenciais ocultadas) e query |
ctx.webhook |
The webhooks id e name |
ctx.shop |
Seu domínio do myShopify |
ctx.log(...) |
Exibe uma linha que o senhor pode ler no painel de teste e no Histórico |
await ctx.fetch(url, init) |
Chama uma API pública |
await ctx.shopify(query, variables) |
Lê os dados das lojas com o Admin GraphQL |
ctx.storage |
Mantém valores pequenos entre as execuções (veja abaixo) |
ctx.respond(body, options) |
Atende a chamada imediatamente |
Reestruturação do payload
O uso mais comum: transformar a estrutura de um remetente nos poucos valores de que seu fluxo de trabalho necessita.
export default async function transform(payload) {
const order = payload.data.attributes
return {
orderNumber: String(order.number),
email: order.customer.email.toLowerCase(),
total: Number(order.total_cents) / 100,
}
}Excluir solicitações desnecessárias
Retorne null e a solicitação será interrompida nesse ponto: não haverá execução do Shopify Flow, nenhuma entrada no histórico e nada será contabilizado no seu plano. O chamador receberá 200 com { "skipped": true }, de modo que não fará uma nova tentativa.
export default async function transform(payload, ctx) {
if (payload.status !== "paid" || payload.total < 100) {
ctx.log("skipping", payload.id, payload.status, payload.total)
return null
}
return payload
}Lembrar-se das coisas entre as corridas
ctx.storage é um pequeno banco de dados de chave-valor que pertence à sua loja. É a ferramenta para responder à pergunta “já vi isso antes?”: armazene um ID quando um evento ocorrer e ignore a próxima solicitação que contenha o mesmo ID, mesmo que ela chegue dias depois.
| Ligar | Será que |
|---|---|
await ctx.storage.get(key) |
A loja, ou null |
await ctx.storage.set(key, value) |
Armazena qualquer valor JSON, sobrescrevendo |
await ctx.storage.delete(key) |
Remove-o; true, caso existisse |
await ctx.storage.list({ prefix, limit, cursor }) |
Principais nomes e tamanhos, página por página |
export default async function transform(payload, ctx) {
const key = `seen:${payload.id}`
if (await ctx.storage.get(key)) return null
await ctx.storage.set(key, { at: Date.now() })
return payload
}Enriquecimento com dados das lojas
ctx.shopify Executa consultas GraphQL de administração somente leitura para a sua loja, de modo que um fluxo de trabalho possa ser iniciado com dados aos quais o remetente nunca teve acesso. Ele só tem acesso ao que o senhor permitir: conceda os escopos necessários na seção “Acesso aos dados da loja”, na guia “Função”. Nada é concedido por padrão, e as mutações são recusadas.
export default async function transform(payload, ctx) {
const data = await ctx.shopify(
`query($q: String!) {
productVariants(first: 1, query: $q) { nodes { id title price } }
}`,
{ q: `sku:${payload.sku}` },
)
const variant = data.productVariants.nodes[0]
if (!variant) return null
return { sku: payload.sku, variantId: variant.id, price: variant.price }
}Atender você mesmo a chamada
ctx.respond() envia uma resposta imediatamente, o que transforma o webhook em um pequeno endpoint de API: valida algo, calcula uma resposta e responde em uma única solicitação. O Shopify Flow continua a ser executado independentemente do que o senhor retornar.
export default async function transform(payload, ctx) {
const ok = typeof payload.email === "string" && payload.email.includes("@")
ctx.respond({ accepted: ok }, { status: ok ? 200 : 422 })
return ok ? payload : null
}Testes
O painel “Teste”, na guia “Função”, executa o código no editor - incluindo alterações não salvas - com base em um payload de teste. Ele exibe o valor de retorno, a resposta que sua função enviaria, os campos do Shopify Flow gerados, suas linhas de log e a duração. Nada aciona o Shopify Flow, nada é registrado no Histórico e nada é contabilizado no seu plano. As chamadas de armazenamento, porém, são reais: uma execução de teste lê e grava no mesmo armazenamento que as solicitações em produção.
Quando uma função falha
Caso seu código gere uma exceção, atinja o tempo limite ou retorne algo inutilizável, a solicitação será rejeitada com o código de erro 422 e a falha será registrada no Histórico, juntamente com o erro e suas linhas de log, para que você possa verificar o que ocorreu. Corrija o código e repita essa entrada: a repetição executará a nova versão.
Limites
- 5 segundos e 64 MB por execução, além de 50.000 caracteres de código.
- Não há pacotes npm. O endereço
ctx.fetché a única opção disponível, e endereços internos ou privados não são aceitos. ctx.shopifypermite 10 chamadas por execução, apenas consultas, limitadas aos escopos que o senhor concedeu.- Cada execução que chega ao Shopify Flow é considerada uma invocação normal e conta para o seu plano. Uma solicitação ignorada não conta.

