← Back to blog

Employee Expense Workflow with Make.com and Slack

Route Google Forms receipt uploads through Cryvis extraction, Slack approval, and Google Sheets — write ledger rows only when managers approve.

Unreviewed OCR should not hit the books. This scenario collects employee receipts via Google Forms, extracts structured fields with Cryvis, asks a manager in Slack, and appends to Google Sheets only on approval. Rejections stop before finance.

Make overview: Make.com hub. Simpler no-approval logging: automate expense tracking. Sheets column design: receipt to Google Sheets.

Workflow

[Google Forms: Watch Responses]
   employee | project | file upload
        |
        v
[Google Drive: Download a File]
        |
        v
[Filter: pdf|jpeg|png|webp]
        |
        v
[HTTP: Make a Request]
   POST https://api.cryvis.com/v1/documents/receipt
        |
        v
[Slack: Create a Message / Approval]
   merchant, date, total, photo link
        |
        +-- approved -------+
        |                   v
        |        [Google Sheets: Add a Row]
        |        Status = Approved
        |
        +-- rejected -------+
                            v
                 [Sheets: Rejected tab]
                 or Slack DM to employee

Modules

StepModuleNotes
1Google Forms — Watch ResponsesTrigger
2Google Drive — Download a FileForm upload
3FilterMIME allowlist
4HTTP — Make a RequestCryvis Receipt
5Slack — Send Message / ApprovalBlock kit or Approve/Reject buttons if your Slack module supports them
6RouterApproved vs Rejected
7aGoogle Sheets — Add a RowApproved ledger
7bGoogle Sheets — Add a RowRejected audit (optional)
8Error HandlerCryvis/Slack failures

If your Slack app cannot do interactive approvals, approximate with reactions: a second scenario watches for :white_check_mark: on the bot message and continues. Prefer true Approve/Reject actions when available.

Form design

Keep the form short:

  • Employee email (collect automatically if Workspace)
  • Cost center / project code (required dropdown)
  • Business purpose (short text)
  • Receipt file (required upload)
  • Optional: amount estimate (helps managers spot OCR mismatch)

Do not ask users to type merchant and total if Cryvis will extract them — duplicate entry creates conflicts. Show extracted values in Slack for confirmation instead.

Cryvis HTTP configuration

SettingValue
URLhttps://api.cryvis.com/v1/documents/receipt
MethodPOST
AuthAuthorization: Bearer <API_KEY>
BodyMultipart file = Drive binary

One form response → one file → single-file envelope (success + data). Credits: 1 per page/image.

Docs: extractReceipt. Product: Receipt API.

Slack message content

Post a compact summary managers can decide in under 10 seconds:

Expense approval needed
Employee: {{form.email}}
Project: {{form.project}}
Purpose: {{form.purpose}}
Merchant: {{data.merchant.name}}
Date: {{data.transaction_date}}
Total: {{data.total_amount}} {{data.currency}}
Tax: {{data.tax_total}}
Receipt #: {{data.receipt_number}}
File: {{drive.webViewLink}}

If data.total_amount disagrees with an optional form estimate by more than 5%, bold a warning line in Slack so approvers look twice.

Response mapping

Into Slack (pre-approval)

Slack fieldSource
Merchantdata.merchant.name
Datedata.transaction_date
Totaldata.total_amount
Currencydata.currency
Taxdata.tax_total
Paymentdata.payment.method
Typedata.receipt_type

Into Sheets (approved only)

ColumnSource
Approved AtApproval timestamp
ApproverSlack user who approved
EmployeeForm email
ProjectForm project
PurposeForm purpose
Merchantdata.merchant.name
Datedata.transaction_date
Totaldata.total_amount
Taxdata.tax_total
Currencydata.currency
Receipt Numberdata.receipt_number
StatusApproved
File URLDrive link

Rejected path: write to Rejected with reason (Slack reject comment) and never to Approved. Finance pivots only the Approved tab.

Destination specifics: Slack + Sheets

Routing approvers

Use a Router or Data Store lookup: project → Slack user/channel.

ENG-*  → #eng-expenses
SALES-* → @sales-ops
default → #finance-approvals

Do not post every expense to a public company channel if receipts include personal purchases awaiting reimbursement — prefer private channels or DMs to managers.

Sheets hygiene

  • Approved tab is append-only from Make.
  • Humans may add Paid in payroll later; do not overwrite.
  • Protect header row; restrict edit on formula columns.

For duplicate detection after approval (same receipt submitted twice by an employee), combine receipt_number + transaction_date + employee email — pattern detailed in receipt to Google Sheets.

Holding state

Approvals are asynchronous. Options:

  1. Make Slack approval module that pauses the scenario until action (simplest).
  2. Split scenarios: Scenario A posts Slack + stores Cryvis JSON in Data Store keyed by response_id. Scenario B webhook/slash receives approval and reads Data Store before Sheets write.

Option 2 survives longer manager delays and scenario edits mid-flight.

Filters and edge cases

  • MIME filter before Cryvis.
  • Soft-fail if total_amount empty → Slack with “OCR incomplete — approve only if you open the file”.
  • Policy Filter: auto-reject or auto-escalate if total_amount > 500 (or your threshold) to finance lead.
  • Weekend travel: multiple Forms in one night — ensure Slack messages include Form timestamp to order them.
  • Resubmits: employees fix a rejected receipt by submitting a new Form response (new row), not by editing the old one.

Invoice-style vendor PDFs uploaded by mistake should be routed to an invoice scenario (extract invoice data) or rejected with guidance.

Errors

FailureHandling
Cryvis auth errorStop; alert #finance-ops; do not Slack-spam managers
Cryvis soft failSlack “extraction failed” with Drive link for manual review
Slack API errorIncomplete execution; do not mark Approved
Approval timeoutData Store TTL + remind manager after 48h
Sheets write fail after approveCritical alert — money was approved but not recorded

Never write Approved rows before the Slack decision bundle resolves.

Test plan

  1. Submit Form with a clear JPEG; confirm Cryvis fields in the Slack preview.
  2. Approve → exactly one Approved Sheets row.
  3. Submit again; Reject → Rejected tab only.
  4. Submit unsupported file type → Filter stops before Slack.
  5. Submit high-dollar receipt → escalation route fires.
  6. Kill API key temporarily → Error Handler notifies ops, no orphan Approved rows.

Production checklist

  • Slack bot installed to the right workspaces; least-privilege scopes.
  • Manager mapping table owned by finance, not hardcoded in one scenario.
  • Cryvis key rotation; credit budget for headcount × monthly receipts (1 credit / page / image).
  • GDPR/PII: receipt images in Drive with restricted ACL; Sheets without card PAN (Cryvis payment.last4 only if policy allows).
  • Document the employee help text: “Upload one receipt per submission.”

CTA

Extraction without control is just faster mess. Use the Cryvis Receipt API for structured merchant and totals, then gate ledger writes on Slack approval. Implementation reference: extractReceipt.