How to Send Supplier Order Confirmations and Restock ETAs to Slack

Capture supplier order-confirmation emails in Spojit, pull the expected restock date out of the PDF, log it, and post a tidy alert to your store-ops Slack channel.

What This Integration Does

Retail pharmacies and health-product stores live and die by restock timing: when a wholesaler confirms an order, the buying team needs to know the purchase order (PO) number and the expected delivery date without digging through an inbox. This workflow takes the supplier's confirmation email, reads the PO number and restock ETA out of the attached PDF, normalizes the date into a clean format, records it for reporting, and drops a short message into your store-ops Slack channel so the team can plan shelf space and customer pickups around it. It is pure procurement and logistics: no clinical, prescription, or patient information is touched.

The run starts when a supplier emails a unique Spojit address (a Mailhook trigger), so it fires within seconds of the confirmation arriving, with no mailbox or polling involved. An Attachment node fetches the PDF bytes, a Connector node in Agent mode with a Response Schema returns the PO number and raw ETA as structured fields, the date connector reshapes the ETA, the mongodb connector logs one document per confirmation, and the slack connector posts the alert. Each confirmation email is deduplicated by Spojit, so a forwarded copy of the same message will not double-post. Re-running the same email simply writes another log document and posts again, which makes testing safe on a throwaway channel.

Prerequisites

  • A Slack connection added under Connections, with access to the channel you want to post to (for example #store-ops). The connection's app must be a member of that channel.
  • A mongodb connection to the database where you keep operational logs, with write access to a collection such as supplier_restocks.
  • The built-in date and json connectors (no auth, always available).
  • A supplier that emails order confirmations as a PDF attachment. If a supplier portal exposes a REST API instead of emailing, you can reach it with the http connector; see the cross-link in Learn More.
  • Permission to create workflows and to generate a Mailhook address in your workspace.

Step 1: Receive the supplier email with a Mailhook trigger

Create a new workflow and open the Trigger node. Set Trigger Type to Mailhook. Enter an Address prefix like restock (1 to 24 characters), then click Generate email address. Spojit produces a unique address such as restock-a1b2c3d4e5f6a7b8@mailhook.spojit.com. Copy it and give it to your supplier as the destination for order confirmations, or add a forwarding rule from your purchasing inbox to it.

To keep stray mail out, set the optional From allowlist to the supplier's sending domain and a Subject regex such as (?i)order\s*confirmation. The trigger output is available downstream as {{ input }} and includes {{ input.from }}, {{ input.subject }}, {{ input.text }}, {{ input.replyTo }}, and {{ input.attachments }} (each attachment reference carries id, filename, and contentType).

Step 2: Fetch the PDF with an Attachment node

Add an Attachment node directly after the trigger (the designer only allows this node in Mailhook workflows). Set Mode to Single so you get the first matching file as one object. Set the Content type filter to application/pdf and the Filename pattern to *.pdf to ignore signature images or logos. Turn on Fail if no attachment matches so a confirmation that arrives without its PDF stops here instead of producing an empty alert.

The node outputs { filename, contentType, size, content }, where content is the base64-encoded PDF. You will reference it downstream as {{ attachment.content }}. Attachment limits are 10 MB per file and 25 MB per run by default, which is ample for a one-page confirmation.

Step 3: Extract the PO number and ETA in Agent mode with a Response Schema

Add a Connector node and switch it to Agent mode. Agent mode lets the agent read the document and return clean fields rather than you mapping a fixed parser. In the prompt, point it at the attachment and describe exactly what you want:

Read the attached supplier order-confirmation PDF (base64): {{ attachment.content }}
Return the purchase order number and the expected restock or delivery date
exactly as written on the document. If a field is missing, return an empty string.

Define a Response Schema so the output is reliable JSON instead of prose:

{
  "type": "object",
  "properties": {
    "poNumber":  { "type": "string" },
    "supplier":  { "type": "string" },
    "etaRaw":    { "type": "string", "description": "ETA as printed on the PDF" }
  },
  "required": ["poNumber", "etaRaw"]
}

Save the result to an output variable such as extracted. You can now read {{ extracted.poNumber }} and {{ extracted.etaRaw }} downstream. Agent mode costs AI credits; Direct mode does not, which is why the deterministic steps below stay in Direct mode.

Step 4: Normalize the ETA with the date connector

Supplier PDFs print dates inconsistently (03/06/2026, 6 Mar 2026, 2026-03-06). Add a Connector node in Direct mode on the date connector and choose the format tool. Map date to {{ extracted.etaRaw }} and set format to a consistent pattern such as YYYY-MM-DD. If your suppliers use day-first dates, add a date parse step first with inputFormat set to DD/MM/YYYY, then feed its result into format. Save the formatted value to a variable such as etaDate (referenced later as {{ etaDate.result }}).

If you want one self-contained record to log, add an optional Transform node, or use the json connector's set tool to assemble a single object that combines {{ extracted.poNumber }}, {{ extracted.supplier }}, and {{ etaDate.result }} with the email metadata.

Step 5: Log the confirmation with mongodb insert-documents

Add a Connector node in Direct mode on the mongodb connector and select the insert-documents tool. Set collection to supplier_restocks and pass a one-element array to documents:

[
  {
    "poNumber":    "{{ extracted.poNumber }}",
    "supplier":    "{{ extracted.supplier }}",
    "etaDate":     "{{ etaDate.result }}",
    "fromEmail":   "{{ input.from }}",
    "subject":     "{{ input.subject }}",
    "sourceFile":  "{{ attachment.filename }}",
    "receivedAt":  "{{ input.receivedAt }}"
  }
]

The tool returns insertedCount and the inserted IDs, giving you a durable, queryable record of every restock ETA for reporting and follow-up.

Step 6: Post the restock alert to Slack

Add a final Connector node in Direct mode on the slack connector and choose the send-message tool. Set the channel to #store-ops and compose a short message from your variables:

:package: Supplier confirmation received
PO {{ extracted.poNumber }} from {{ extracted.supplier }}
Expected restock: {{ etaDate.result }}
Source: {{ attachment.filename }}

If you would rather thread alerts under a daily summary, capture the message timestamp from send-message and reuse it as a thread reference on later posts. To resolve a buyer by email into a Slack mention, you can add a lookup-user-by-email Direct-mode step before sending.

Tips

  • Use a Subject regex on the Mailhook trigger so only genuine confirmations start a run; marketing mail from the same supplier domain is filtered out before any AI credits are spent.
  • Keep the deterministic steps (date, mongodb, slack) in Direct mode so only the extraction step in Step 3 consumes AI credits.
  • If a supplier occasionally sends multiple PDFs (a confirmation plus a packing slip), switch the Attachment node to Multiple mode and add a Loop over {{ attachment.attachments }}, keeping only the file whose name matches your confirmation pattern.
  • Have the supplier reply to confirmations? You can acknowledge automatically with a Send Email node addressed to {{ input.replyTo }}.

Common Pitfalls

  • Attachment node without a Mailhook trigger. The designer refuses to save an Attachment node in any other trigger type. If you started from an Email trigger, switch the trigger to Mailhook first.
  • Date misread as month-first. A value like 03/06/2026 is ambiguous. Pin the supplier's locale by adding a date parse step with an explicit inputFormat before format, rather than relying on auto-detection.
  • Slack app not in the channel. send-message fails if the connection's app has not joined #store-ops. Invite it to the channel once before going live.
  • Empty fields from a scanned PDF. If a supplier sends an image-only scan, the extraction may return blanks. Keep Fail if no attachment matches on, and consider a Condition node that skips the Slack post when {{ extracted.poNumber }} is empty.

Testing

Before pointing real suppliers at the address, send a sample confirmation PDF from your own mailbox to the generated Mailhook address and watch the run in execution history. Point the slack step at a private test channel and the mongodb step at a scratch collection like supplier_restocks_test. Confirm the extracted PO number and ETA match the PDF, that the logged document looks right, and that the Slack message reads cleanly. Once a few sample emails post correctly, switch the channel and collection to production values and ask one supplier to send a live confirmation.

Learn More

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.