Finds every record for one person, shows exactly what it found, and erases it only after a person approves.
Uses
Airtable
Slack
Handle a data erasure request, with approval
request.When someone types “erase” in a channel. Save it as request.airtableBaseId to blank.Set airtableBaseId to blank.recordsTable to blank.Set recordsTable to blank.deletionLogTable to blank.Set deletionLogTable to blank.maxRecordsPerRequest to 25.Set maxRecordsPerRequest to 25.requestedBySlackUser to request.user_id.Set requestedBySlackUser to request.user_id.requestChannel to request.channel_id.Set requestChannel to request.channel_id.requestMessageTs to request.message_ts.Set requestMessageTs to request.message_ts.emailAddress to blank.Set emailAddress to blank.identifierErrorIf a step below fails, save the error as identifierErrorTry
request.arguments lowercase and save it as emailAddress.Make request.arguments lowercase and save it as emailAddress.On error
emailAddress is emptyIf emailAddress is emptyYes
No
No steps
emailAddress is a valid email address is noIf emailAddress is a valid email address is noYes
No
No steps
emailAddress contains ' or emailAddress contains \If emailAddress contains ' or emailAddress contains \Yes
No
No steps
searchFormula to LOWER({Email}) = '@emailAddress'.Set searchFormula to LOWER({Email}) = '@emailAddress'.searchLimit to maxRecordsPerRequest multiplied by 1 plus 1.Set searchLimit to maxRecordsPerRequest multiplied by 1 plus 1.recordsTable. Save it as searchResult.List records in recordsTable. Save it as searchResult.matchedRecordIds to an empty list.Set matchedRecordIds to an empty list.unreadableRecords to 0.Set unreadableRecords to 0.record in searchResult.records:For each record in searchResult.records:recordErrorIf a step below fails, save the error as recordErrorTry
record.fields.Email lowercase and save it as recordEmail.Make record.fields.Email lowercase and save it as recordEmail.recordEmail is emailAddressIf recordEmail is emailAddressYes
record.id to the end of matchedRecordIds and save it as matchedRecordIds.Add record.id to the end of matchedRecordIds and save it as matchedRecordIds.No
No steps
On error
unreadableRecords.Add 1 to unreadableRecords.matchedRecordIds and save it as matchCount.Count the items in matchedRecordIds and save it as matchCount.matchedRecordIds with , and save it as matchedIdList.Join matchedRecordIds with , and save it as matchedIdList.matchCount is 0If matchCount is 0Yes
requestChannel.Reply in a thread in requestChannel.
Reply To: requestMessageTsNo records match emailAddress in the recordsTable table, so there is nothing to erase. Nothing was deleted.No
No steps
matchCount multiplied by 1 is greater than maxRecordsPerRequest multiplied by…If matchCount multiplied by 1 is greater than maxRecordsPerRequest multiplied by…Yes
requestChannel.Reply in a thread in requestChannel.
Reply To: requestMessageTsRefusing this erase request. emailAddress matches matchCount records, which is more than the limit of maxRecordsPerRequest set on the 'maxRecordsPerRequest' step. Nothing was deleted. Check the request is right before raising the limit.No
No steps
foundSummary to Erasure request for emailAddressSet foundSummary to Erasure request for emailAddress
Found matchCount record(s) in the recordsTable table.foundDetail to Matched on a whole-address, case-insensitive match of the Email column.Set foundDetail to Matched on a whole-address, case-insensitive match of the Email column.
Record ids: matchedIdList
Records skipped because their Email could not be read: unreadableRecords.requestChannel.Reply in a thread in requestChannel.
Reply To: requestMessageTsfoundSummary
foundDetail
Nothing has been deleted. This run is now waiting for a person to approve the erasure in Lodol.logRequestLine to Requested by Slack user requestedBySlackUser in channel requestChannel (message requestMessageTs).Set logRequestLine to Requested by Slack user requestedBySlackUser in channel requestChannel (message requestMessageTs).logSearchLine to Identifier requested: emailAddressSet logSearchLine to Identifier requested: emailAddress
Searched table: recordsTable in base airtableBaseId
Match rule: whole-address, case-insensitive match on the Email column.logOpening to logRequestLineSet logOpening to logRequestLine
logSearchLine.logFindings to logOpeningSet logFindings to logOpening
foundDetail
Written before any deletion. Status at this point: awaiting approval, nothing erased.deletionLogTable. Save it as deletionRecord.Add a record to deletionLogTable. Save it as deletionRecord.deletionRecordId to deletionRecord.id.Set deletionRecordId to deletionRecord.id.approvalHeader to Requested by Slack user requestedBySlackUser in channel requestChannel.Set approvalHeader to Requested by Slack user requestedBySlackUser in channel requestChannel.approvalBody to Erase every record for: emailAddressSet approvalBody to Erase every record for: emailAddress
Airtable base: airtableBaseId
Table: recordsTable
foundDetail.approvalFooter to Approving permanently deletes these matchCount record(s) and cannot be undone. Rejecting it, or leaving it until the request runs out, cancels the request and deletes nothing.Set approvalFooter to Approving permanently deletes these matchCount record(s) and cannot be undone. Rejecting it, or leaving it until the request runs out, cancels the request and deletes nothing.approvalDetails to approvalHeaderSet approvalDetails to approvalHeader
approvalBody
approvalFooter.matchCount record(s) for emailAddress? Save it as erasureReview.Request approval: Permanently erase matchCount record(s) for emailAddress? Save it as erasureReview.approvalDetailsdecidedBy to not recorded.Set decidedBy to not recorded.deciderErrorIf a step below fails, save the error as deciderErrorTry
erasureReview.decided_by.email and save it as deciderEmail.Trim erasureReview.decided_by.email and save it as deciderEmail.erasureReview.decided_by.name and save it as deciderName.Trim erasureReview.decided_by.name and save it as deciderName.deciderEmail isn't emptyIf deciderEmail isn't emptyYes
decidedBy to deciderEmail.Change decidedBy to deciderEmail.deciderName isn't emptyIf deciderName isn't emptyYes
decidedBy to deciderName (deciderEmail).Change decidedBy to deciderName (deciderEmail).No
No steps
Else if @deciderName isn't empty
decidedBy to deciderName.Change decidedBy to deciderName.Otherwise
No steps
On error
The approval did not say who decided it, so the deletion record says 'not recorded'..Show in the output: The approval did not say who decided it, so the deletion record says 'not recorded'..reviewNote to blank.Set reviewNote to blank.erasureReview.comment isn't blankIf erasureReview.comment isn't blankYes
reviewNote to Change reviewNote to
Note from the approval: erasureReview.comment.No
No steps
erasedIds to an empty list.Set erasedIds to an empty list.failedIds to an empty list.Set failedIds to an empty list.outcome to blank.Set outcome to blank.erasureReview.approved is yesIf erasureReview.approved is yesYes
recordId in matchedRecordIds:For each recordId in matchedRecordIds:deleteError If a step below fails, save the error as deleteErrorTry
recordId from recordsTable.Delete recordId from recordsTable.recordId to the end of erasedIds and save it as erasedIds.Add recordId to the end of erasedIds and save it as erasedIds.On error
recordId to the end of failedIds and save it as failedIds.Add recordId to the end of failedIds and save it as failedIds.outcome to APPROVED and erased by decidedBy.Change outcome to APPROVED and erased by decidedBy.
Records erased: the length of erasedIds of matchCount
Erased ids: erasedIds joined by ,
Could not be erased: failedIds joined by , @reviewNote.Else if @erasureReview.timed_out is yes
outcome to NO DECISION: the approval request ran out before anyone decided, so nothing was erased. The matchCount matching record(s) are untouched.Change outcome to NO DECISION: the approval request ran out before anyone decided, so nothing was erased. The matchCount matching record(s) are untouched.Otherwise
outcome to DECLINED at the approval step by decidedBy. Nothing was erased. The matchCount matching record(s) are untouched.@reviewNote.Change outcome to DECLINED at the approval step by decidedBy. Nothing was erased. The matchCount matching record(s) are untouched.@reviewNote.logUpdateErrorIf a step below fails, save the error as logUpdateErrorTry
deletionRecordId in deletionLogTable.Update deletionRecordId in deletionLogTable.On error
logUpdateError as text.Show in the output: Could not close the deletion record: logUpdateError as text.requestChannel.Reply in a thread in requestChannel.
Reply To: requestMessageTsErasure request for emailAddress
outcome