Avvisi relativi alla rimozione dei codici sconto
Quando utilizzare questo flusso di lavoro
Utilizza questo flusso di lavoro quando viene rimosso un codice sconto e hai bisogno di una registrazione immediata degli elementi interessati. Ti aiuta a registrare il codice rimosso, il numero di utilizzi, i dettagli della campagna e un riepilogo che puoi inviare al reparto finanziario o operativo su Slack.
Ciò risulta particolarmente utile in caso di divulgazione accidentale dei codici degli influencer, di diffusione non pianificata di coupon o in qualsiasi situazione in cui sia necessario redigere un rapporto documentato sull'impatto dopo la rimozione di un codice.
Cosa realizzerai
- Un flusso di lavoro di Slack che riceve una variabile
textda un webhook e pubblica lo stesso testo in un canale di Slack. - Un flusso di lavoro Shopify Flow attivato dall'evento "Codice sconto rimosso".
- Un passo dati "Ottieni sconto" che recupera lo sconto utilizzando l'ID proveniente dal trigger.
- Un passo "Esegui codice" che genera un report di rimozione.
- Un passaggio "Richiesta HTTP" che invia il report a Slack.
Prima di iniziare
- Assicurati che l'app sia installata e visibile nella sezione di amministrazione di Shopify, alla voce "Apps" > "Workflow Trigger Extensions".
- Assicurati di poter accedere a Shopify Flow.
- Crea o seleziona un canale Slack in cui devono apparire gli avvisi.
- Crea un flusso di lavoro su Slack che si avvii tramite un webhook e accetti un campo
text.
Guida video
Puoi anche guardare il video completo sull'implementazione.
Per prima cosa, crea il flusso di lavoro su Slack
In Slack, crea un flusso di lavoro con il trigger “Inizia con un webhook”. Aggiungi una variabile di testo denominata text, quindi aggiungi il passaggio “Messaggio” che invia un messaggio al canale scelto utilizzando proprio quella variabile text.

Concedere l'accesso a prezzo scontato in Workflow Trigger Extensions
Prima che il trigger compaia in Shopify Flow, abilita l’accesso agli sconti nell’app.
Nella dashboard di Shopify, vai su App > Workflow Trigger Extensions.
Nella Dashboard, cerca la lista di controllo per la configurazione.
Attiva l'opzione "Concedi accesso agli sconti". In questo modo vengono abilitati i trigger relativi agli sconti, quali "Sconto creato", "Sconto aggiornato", "Sconto eliminato", "Codice sconto aggiunto", "Codice sconto rimosso" e "Sconto scaduto".

Costruisci l’Shopify Flow
Apri Shopify Flow e crea un nuovo flusso di lavoro.
Cerca i trigger relativi agli sconti e seleziona “Codice sconto rimosso” da “Workflow Trigger Extensions”.

Aggiungi l'azione Shopify "Ottieni i dati sugli sconti".
In "Seleziona una query per filtrare i dati", scegli "Avanzate". In "Modifica query", utilizza l'ID dello sconto presente nel trigger e rimuovi il prefisso GID Shopify:
id:"{{discount.id|remove:'gid://shopify/DiscountCodeNode/'}}"
Aggiungi un passaggio "Esegui codice" dopo "Ottieni dati sullo sconto".
Utilizza la seguente query GraphQL nei campi di selezione dei passaggi precedenti:
query {
redeemCode {
code
usageCount
bulkRemoval
}
getDiscountData {
discount {
... on DiscountCodeBasic {
title
startsAt
endsAt
asyncUsageCount
codes {
code
asyncUsageCount
}
customerGets {
value {
... on DiscountAmount {
amount { amount currencyCode }
}
... on DiscountPercentage {
percentage
}
}
}
}
}
}
}Definisci le uscite in questo modo:
"Output of discount code removal report"
type Output {
"Discount code that was removed"
code: String!
"Discount campaign title"
title: String!
"Campaign start date"
startsAt: String!
"Campaign end date"
endsAt: String!
"Number of times it was redeemed"
usageCount: Int!
"Total discount impact as a formatted string"
totalImpact: String!
"When it was removed"
removedAt: String!
"Full summary for alerts"
summary: String!
}Quindi incolla questo codice nel campo "Scrivi codice":
export default function main(input) {
// ── Trigger: removed code ──
const removedCode = input?.redeemCode?.code ?? "Unknown";
const usageCount = input?.redeemCode?.usageCount ?? null; // null = bulk removal or unknown
const bulkRemoval = input?.redeemCode?.bulkRemoval ?? false;
const currency = input?.shop?.currencyCode ?? "";
const shopName = input?.shop?.name ?? "(not bound)";
const removedAt = new Date().toISOString();
// ── Find matching discount ──
const dataItems = input?.getDiscountData ?? [];
let matchedDiscount = null;
for (const item of dataItems) {
const d = item?.discount?.DiscountCodeBasic ?? item?.discount;
if (!d) continue;
const codesArray = Array.isArray(d.codes)
? d.codes.map(c => (typeof c === "string" ? c : c?.code ?? ""))
: [];
if (codesArray.includes(removedCode)) {
matchedDiscount = d;
break;
}
}
// fallback to first entry if removed code already gone from list
if (!matchedDiscount && dataItems.length > 0) {
matchedDiscount =
dataItems[0]?.discount?.DiscountCodeBasic ?? dataItems[0]?.discount ?? null;
}
const title = matchedDiscount?.title ?? "Untitled";
const startsAt = matchedDiscount?.startsAt ?? "N/A";
const endsAt = matchedDiscount?.endsAt ?? "None (no expiry)";
const totalUsageCount = matchedDiscount?.asyncUsageCount ?? null;
// ── Discount value ──
const valueWrapper = matchedDiscount?.customerGets?.value ?? {};
const pctObj = valueWrapper?.DiscountPercentage ?? null;
const amtObj = valueWrapper?.DiscountAmount ?? valueWrapper?.amount ?? null;
let discountLabel = "Unknown";
if (pctObj?.percentage != null) {
discountLabel = `${(pctObj.percentage * 100).toFixed(0)}% off`;
} else if (amtObj?.amount != null) {
const cur = amtObj.currencyCode || currency;
discountLabel = `${cur} ${parseFloat(amtObj.amount).toFixed(2)} off`;
}
// ── This code's impact ──
let thisCodeImpact;
if (bulkRemoval) {
thisCodeImpact = `Not available - removed as part of bulk deletion`;
} else if (usageCount === null) {
thisCodeImpact = `Could not be determined`;
} else if (pctObj?.percentage != null) {
thisCodeImpact = `${discountLabel} × ${usageCount} use(s)`;
} else if (amtObj?.amount != null) {
const perUse = parseFloat(amtObj.amount);
const cur = amtObj.currencyCode || currency;
thisCodeImpact = `${cur} ${(perUse * usageCount).toFixed(2)} (${cur} ${perUse.toFixed(2)} × ${usageCount} uses)`;
} else {
thisCodeImpact = "Unknown";
}
// ── Campaign-wide impact using asyncUsageCount on the discount ──
let campaignImpact;
if (totalUsageCount === null) {
campaignImpact = "Not available";
} else if (pctObj?.percentage != null) {
campaignImpact = `${discountLabel} × ${totalUsageCount} total use(s) across all codes`;
} else if (amtObj?.amount != null) {
const perUse = parseFloat(amtObj.amount);
const cur = amtObj.currencyCode || currency;
campaignImpact = `${cur} ${(perUse * totalUsageCount).toFixed(2)} total (${cur} ${perUse.toFixed(2)} × ${totalUsageCount} uses)`;
} else {
campaignImpact = "Unknown";
}
// ── Per-code breakdown ──
const codesNodes = Array.isArray(matchedDiscount?.codes)
? matchedDiscount.codes
: [];
const allCodes = codesNodes
.map(c => (typeof c === "string" ? c : c?.code ?? ""))
.filter(Boolean);
const codesRoster = codesNodes.length
? codesNodes.map(c => {
const code = typeof c === "string" ? c : c?.code ?? "";
const used = c?.asyncUsageCount ?? "?";
const flag = code === removedCode ? " ← REMOVED" : "";
return `${code} (used ${used}×)${flag}`;
}).join("\n ")
: "N/A";
const usageCountLabel = bulkRemoval
? "N/A (bulk removal)"
: usageCount !== null
? String(usageCount)
: "Unknown";
const summary =
`DISCOUNT CODE REMOVED\n` +
`─────────────────────\n` +
`Store: ${shopName}\n` +
`Code removed: ${removedCode}\n` +
`Bulk removal: ${bulkRemoval ? "Yes" : "No"}\n` +
`Campaign: ${title}\n` +
`Discount: ${discountLabel}\n` +
`Valid from: ${startsAt}\n` +
`Valid until: ${endsAt}\n` +
`\n` +
`THIS CODE\n` +
` Times used: ${usageCountLabel}\n` +
` Impact: ${thisCodeImpact}\n` +
`\n` +
`CAMPAIGN TOTAL\n` +
` Total uses: ${totalUsageCount ?? "Unknown"}\n` +
` Total impact: ${campaignImpact}\n` +
`\n` +
`CODE BREAKDOWN\n` +
` ${codesRoster}\n` +
`\n` +
`Removed at: ${removedAt}`;
const safeSummary = summary
.replace(/\\/g, "\\\\") // escape backslashes first
.replace(/"/g, '\\"') // escape quotes
.replace(/\n/g, "\\n") // escape newlines
.replace(/\r/g, "\\r");
return {
code: removedCode,
bulkRemoval,
title,
discountLabel,
startsAt,
endsAt,
usageCount: usageCount ?? 0,
usageCountLabel,
thisCodeImpact,
totalUsageCount: totalUsageCount ?? 0,
campaignImpact,
allCodes,
codesRoster,
removedAt,
summary: safeSummary,
};
}
Aggiungi l'azione "Richiesta HTTP". Nel campo "Variabili" o "Sostituzione corpo (JSON)", invia il riepilogo restituito dal passo "Esegui codice":
{
"body": {
"text": "{{runCode.summary}}"
}
}Questo invia il riepilogo generato al flusso di lavoro del webhook di Slack utilizzando la variabile text.

Salva il flusso di lavoro una volta completati tutti i passaggi.
Per effettuare un test, elimina un codice sconto dalla tua campagna di sconti e verifica che il canale Slack riceva il messaggio di riepilogo.

Cosa comprende l'avviso su Slack
- Il codice sconto rimosso
- Che si trattasse di uno sgombero di grandi quantità
- Il titolo della campagna
- Il valore dello sconto
- Date di inizio e di fine
- Tempi impiegati per il codice rimosso
- Impatto stimato della rimozione del codice
- Utilizzo e impatto a livello di campagna
- Una ripartizione per codice, ove disponibile
- La data e l'ora in cui è stata elaborata la rimozione
Risoluzione dei problemi
Torna su App > Workflow Trigger Extensions e verifica che l'opzione "Concedi accesso agli sconti" sia abilitata. I trigger relativi agli sconti compaiono solo dopo che è stato concesso l'accesso.
Controlla attentamente la query avanzata nella sezione “Modifica query”. L’ID deve essere formattato esattamente come mostrato:
id:"{{discount.id|remove:'gid://shopify/DiscountCodeNode/'}}"Assicurati che il flusso di lavoro di Slack abbia inizio con un webhook, che l'URL del webhook sia quello utilizzato dalla tua richiesta HTTP e che il corpo della richiesta includa il campo text.
Alcune rimozioni potrebbero rientrare in un'azione collettiva oppure potrebbero non fornire dettagli completi sull'utilizzo. In tali casi, il riepilogo fornirà comunque le migliori informazioni disponibili e indicherà chiaramente i valori mancanti.
Migliori pratiche
- Invia questi avvisi a un canale dedicato alla finanza o alle operazioni, anziché a un canale di assistenza generale.
- Assegna al flusso di lavoro un nome specifico, ad esempio “Codice sconto rimosso”, in modo che sia facile da identificare su Shopify Flow e su Slack.
- Effettua prima un test con un codice sconto non destinato alla produzione per verificare il formato del messaggio e il funzionamento del webhook.

