Reads order emails hourly, has AI pull out each line item, and appends it to your order sheet.
Uses
Gmail
Google Sheets
OpenAI
Turn order emails into spreadsheet rows
spreadsheetUrl to blank.Set spreadsheetUrl to blank.sheetName to blank.Set sheetName to blank.orderEmailSearch to blank.Set orderEmailSearch to blank.maxEmails to 25.Set maxEmails to 25.loggedLabel to Order logged.Set loggedLabel to Order logged.reviewLabel to Order needs review.Set reviewLabel to Order needs review.tabHeadings to an empty list.Set tabHeadings to an empty list.tabErrorIf a step below fails, save the error as tabErrorTry
spreadsheetUrl. Save it as orderTab.Read the rows of spreadsheetUrl. Save it as orderTab.tabHeadings to orderTab.headers.Change tabHeadings to orderTab.headers.On error
tabError.message). Check the link in 'spreadsheetUrl' and the tab name in 'sheetName', then run it again.Stop and report a problem: Could not open the '@sheetName' tab of your order spreadsheet (tabError.message). Check the link in 'spreadsheetUrl' and the tab name in 'sheetName', then run it again.tabHeadings is emptyIf tabHeadings is emptyYes
No
No steps
tabHeadings and save it as firstHeadings.Take the first 6 items of tabHeadings and save it as firstHeadings.firstHeadings with , and save it as headingLine.Join firstHeadings with , and save it as headingLine.headingLine in lowercase is not "customer, order reference, item, quantity,…If headingLine in lowercase is not "customer, order reference, item, quantity,…Yes
headingLine. Fix the headings, then run it again.Stop and report a problem: Rows are added to the '@sheetName' tab column by column, so row 1 must read: Customer, Order reference, Item, Quantity, Requested delivery date, Gmail message ID. It reads: headingLine. Fix the headings, then run it again.No
No steps
@loggedLabel -label:@reviewLabel'. Save it as inbox.List emails matching '@orderEmailSearch -label:@loggedLabel -label:@reviewLabel'. Save it as inbox.rowsAdded to 0.Set rowsAdded to 0.ordersLogged to 0.Set ordersLogged to 0.reviewNotes to an empty list.Set reviewNotes to an empty list.failures to an empty list.Set failures to an empty list.aiFailed to an empty list.Set aiFailed to an empty list.lastAiProblem to blank.Set lastAiProblem to blank.email in inbox.emails:For each email in inbox.emails:email.subject, or (no subject) if it is empty and save it as subject.Use email.subject, or (no subject) if it is empty and save it as subject.email.body and save it as emailBody.Trim email.body and save it as emailBody.reviewReason to it has no text to read; an order sent only as an attachment has to be typed in by hand.Set reviewReason to it has no text to read; an order sent only as an attachment has to be typed in by hand.orderRows to an empty list.Set orderRows to an empty list.emailBody isn't emptyIf emailBody isn't emptyYes
extracted to an empty record.Set extracted to an empty record.aiProblem to blank.Set aiProblem to blank.aiErrorIf a step below fails, save the error as aiErrorTry
email.from Subject: subject emailBody and save it as reading.Run an AI agent: Copy the order out of this email. From: email.from Subject: subject emailBody and save it as reading.extracted to reading.output.Change extracted to reading.output.On error
aiProblem to aiError.message.Change aiProblem to aiError.message.aiProblem isn't emptyIf aiProblem isn't emptyYes
aiFailed and save it as aiFailed.Add '@subject' to the end of aiFailed and save it as aiFailed.lastAiProblem to aiProblem.Change lastAiProblem to aiProblem.No
No steps
extracted.customer and save it as customer.Trim extracted.customer and save it as customer.extracted.order_reference, or Not given if it is empty and save it as orderReference.Use extracted.order_reference, or Not given if it is empty and save it as orderReference.extracted.delivery_date, or Not given if it is empty and save it as deliveryDate.Use extracted.delivery_date, or Not given if it is empty and save it as deliveryDate.incompleteLines to 0.Set incompleteLines to 0.line in extracted.items:For each line in extracted.items:line.item and save it as itemName. Trim line.item and save it as itemName.itemName isn't empty and line.quantity is greater than 0 If itemName isn't empty and line.quantity is greater than 0Yes
customer, orderReference, itemName, line.quantity, deliveryDate, email.id] to the end of orderRows and save it as orderRows.Add [customer, orderReference, itemName, line.quantity, deliveryDate, email.id] to the end of orderRows and save it as orderRows.No
incompleteLines.Add 1 to incompleteLines.extracted.is_order is noIf extracted.is_order is noYes
reviewReason to the AI did not see an order in it.Change reviewReason to the AI did not see an order in it.Else if @extracted.is_order is not "yes"
reviewReason to the AI could not tell whether it places an order.Change reviewReason to the AI could not tell whether it places an order.Else if @customer is empty
reviewReason to it does not say who the customer is.Change reviewReason to it does not say who the customer is.Else if @orderRows is empty
reviewReason to no ordered item was found in it.Change reviewReason to no ordered item was found in it.Else if @incompleteLines is greater than 0
reviewReason to an item's name or quantity is missing or unclear.Change reviewReason to an item's name or quantity is missing or unclear.Otherwise
reviewReason to blank.Change reviewReason to blank.No
No steps
reviewReason isn't emptyIf reviewReason isn't emptyYes
reviewLabelErrorIf a step below fails, save the error as reviewLabelErrorTry
reviewLabel to email email. Save it as flagged.Add label reviewLabel to email email. Save it as flagged.reviewReason) to the end of reviewNotes and save it as reviewNotes.Add '@subject' (reviewReason) to the end of reviewNotes and save it as reviewNotes.On error
reviewReason) but the label could not be added (reviewLabelError.message) to the end of failures and save it as failures.Add '@subject' needs review (reviewReason) but the label could not be added (reviewLabelError.message) to the end of failures and save it as failures.No
No steps
rowsWritten to 0.Set rowsWritten to 0.writeProblem to blank.Set writeProblem to blank.orderRow in orderRows:For each orderRow in orderRows:sheetErrorIf a step below fails, save the error as sheetErrorTry
sheetName in spreadsheetUrl. Save it as added.Add a row to sheetName in spreadsheetUrl. Save it as added.rowsWritten.Add 1 to rowsWritten.On error
writeProblem to sheetError.message.Change writeProblem to sheetError.message.rowsAdded to rowsAdded plus rowsWritten.Change rowsAdded to rowsAdded plus rowsWritten.writeProblem isn't emptyIf writeProblem isn't emptyYes
rowsWritten is 0If rowsWritten is 0Yes
writeProblem), so '@subject' and any emails after it were left unlabelled to be tried again next hour to the end of failures and save it as failures.Add no rows could be added to the '@sheetName' tab (writeProblem), so '@subject' and any emails after it were left unlabelled to be tried again next hour to the end of failures and save it as failures.No
partLabelErrorIf a step below fails, save the error as partLabelErrorTry
reviewLabel to email email. Save it as partlyFlagged.Add label reviewLabel to email email. Save it as partlyFlagged.On error
No steps
rowsWritten line(s) of '@subject' were added before the sheet stopped taking rows (writeProblem); the email is labelled '@reviewLabel' so the rest can be added by hand, and any emails after it are tried again next hour to the end of failures and save it as failures.Add only the first rowsWritten line(s) of '@subject' were added before the sheet stopped taking rows (writeProblem); the email is labelled '@reviewLabel' so the rest can be added by hand, and any emails after it are tried again next hour to the end of failures and save it as failures.No
No steps
loggedLabelErrorIf a step below fails, save the error as loggedLabelErrorTry
loggedLabel to email email. Save it as logged.Add label loggedLabel to email email. Save it as logged.ordersLogged.Add 1 to ordersLogged.On error
loggedLabelError.message): label it by hand, or its rows will be added again next hour to the end of failures and save it as failures.Add the rows for '@subject' were added but the '@loggedLabel' label could not be put on the email (loggedLabelError.message): label it by hand, or its rows will be added again next hour to the end of failures and save it as failures.aiFailed isn't emptyIf aiFailed isn't emptyYes
aiFailed with , and save it as aiFailedList.Join aiFailed with , and save it as aiFailedList.aiFailedList (lastAiProblem), so they were left unlabelled to be read again next hour to the end of failures and save it as failures.Add the AI could not read aiFailedList (lastAiProblem), so they were left unlabelled to be read again next hour to the end of failures and save it as failures.No
No steps
reportLines to an empty list.Set reportLines to an empty list.rowsAdded row(s) from ordersLogged order email(s). to the end of reportLines and save it as reportLines.Add Added rowsAdded row(s) from ordersLogged order email(s). to the end of reportLines and save it as reportLines.reviewNotes isn't emptyIf reviewNotes isn't emptyYes
reviewNotes with ; and save it as reviewList.Join reviewNotes with ; and save it as reviewList.reviewList. to the end of reportLines and save it as reportLines.Add Labelled '@reviewLabel' for a person to check: reviewList. to the end of reportLines and save it as reportLines.No
No steps
inbox.emails is greater than or equal to maxEmailsIf the length of inbox.emails is greater than or equal to maxEmailsYes
maxEmails emails are read per run, so more may be waiting; they are read next hour. to the end of reportLines and save it as reportLines.Add Only maxEmails emails are read per run, so more may be waiting; they are read next hour. to the end of reportLines and save it as reportLines.No
No steps
reportLines with a space and save it as report.Join reportLines with a space and save it as report.failures isn't emptyIf failures isn't emptyYes
failures with ; and save it as problemList.Join failures with ; and save it as problemList.report Needs attention: problemList.Stop and report a problem: report Needs attention: problemList.No
No steps
report.Finish the run: report.