Trigger Actions Directly in Email

Info below provided as-is, you may need to tweak and adjust things to suit your situation and please take note of the security concern outlined below.

There are 2 apps needed to make this solutions (explained below):

  1. Approve from Email (primary app)
  2. Keygap for Approve from Email (required to mask the primary appโ€™s access key)

Supporting Documentation:

Embedding Forms and Buttons: HTML input tag
HTML โ†’ JSON Forms: W3C HTML JSON form submission

Similar Solutions:
@LeventK Executing a DeepLink action from an Email Silently
@Fabian Executing a DeepLink action from an Email Silently - #26 by Fabian

Summary

Currently there is no default AppSheet solution available to generate emails where an individual can execute AppSheet actions directly from the email itself. Typically they must click on a link to open the app and then click on an action within the app. In this example, a simple app was created that allows users to submit new requests into an app and email these requests to an approver. This solution solves the problem of needing to open the app to approve or reject a request allowing users to execute the Approve or Reject action directly from the email body.

Why are there 2 apps?

There is a limitation with AppSheet in that in order to receive API calls you need to use a static app access key. Normally this is not a problem when accomplishing machine to machine calls, but in this case the access key needs to be embedded in the emailโ€™s html code. This exposes a security vulnerability and creates an opportunity for someone who receives the email to copy the appโ€™s key and send calls to update the app through the and bypass any of the appโ€™s security filters that may be in place.

The second AppSheet app (Keygap for Approve from Email) acts as a security gap and it is this appโ€™s access key that is sent in the email body. This is done so you only expose an app that does only one thingโ€ฆ send calls for the desired email actions you are wanting to create. This creates additional security because even if a user finds the keygap access key by reading the html code of an email, they would only be able to act on requests that are in the email action queue and would need to know the primary key of the records to execute the action.

Tables

There are 2 tables in this example, requests and keygap.

The requests table is where all new requests are logged and tracked to approval or rejection. This follows a typical approval workflow setup using appsheet. This only appears in the primary app.

The keygap table is used by both apps. where all pending requests are queued for the keygap app to act on when the keygap app receives a call from an email. This also has the benefit of shrinking the size of a potential attack surface to only specific pending records in this table. Records are then deleted by the keygap app once the action is executed.

Potential Security Concerns

As highlighted above the purpose of the keygap app and separate keygap table is to shrink the attack surface to only requests that are currently pending. However this does not remove all risk. If the email itself is forwarded to other individuals they will have the ability to approve/reject the request even if they cannot approve the request in the app. If the risk is a high enough concern for an organization, one could add a pin number system to the app and capture a pin number in the emailโ€™s post form as an additional verification that the approver is the person clicking the approve or reject button.

How the App Works

  1. The main app sends a formatted email via Notify approver workflow to an email address. The email body contains html form tags that generate the approve or reject actions with the reference to the primary key of the record to be updated. This makes use of the Invoking the AppSheet API service.
  2. The main app also adds the request to the keygap table with a pending status.
  3. The approver receives an email that summarizes the request and has 2 options to approve or reject.
  4. When Approve/rejected button is clicked an post call is sent to the keygap app to update the respective record in the keygap table with the approvers intent.
  5. When the record is updated with the approvers intent in the keygap table, a workflow called Update Record is triggered that sends a post call to the Main app to trigger either Approve or Disapprove for specific record
  6. This update in the main app triggers a workflow called Approved or Rejected that sends an email to the approver to notify them that the request was successfully approved or rejected.
25 14 2,918
14 REPLIES 14

Thanks you Rich, for sharing awosome knowledge. I put this into our library.
Will dig in deeper, as it may take a bit of time to learn all the detail of this trick.

I have a impression that probably we can use the button element on email body for other purpose, for instance simply open up that app etc.

Wondering if we can pull the cdn with tab in emai body? to use the css liberary etc to make our life easier to decorate the email body?

Yes you are right, there are probably plenty ideas that can be created as well. I hope to see many great ideas from the community! I added some supporting documents to the post that describe how to construct html tags that send a JSON Post call and how to translate JSON body structure to html structure needed for an email form.

I m on a feel now that we are able to create MailChimp kinda of clone (not a clone but html email module) inside Appsheet app.
I just did a quick test to generate html email body but simple tag seems to be ignored.
And other html tag such as was not work neither, so overall, there is some restrictions to generate fancy html output for now.
To make the html decoration easier, it would be easier to use Bootstrap or other css framework using element , but it seems to be impossible for the moment.

Thank you very much @Rich
This reminds me of @LeventKโ€™s tip.

โ€ฆ and mine

But I like your solution, because it does not open a site in the browser, which is taking some seconds.
Your solution seems to be faster to the user.

Thanks @Fabian for pointing those posts out too. Ill reference them in the above post as well. @LeventK

When you click on the โ€œKeygap for Approver from Emailโ€ itโ€™s redirecting to Simple Inventory Manager.

sorry about that, I had temporarily disabled it as a sample app. It should be viewable now.

hcquadros
Participant IV

Great solution! I put it to use right away!

Is there a way to avoid other users triggering the action if the e-mail containing the button is copied or forwarded to someone thatโ€™s not supposed to trigger it? Perhaps capturing the e-mail of who clicked it?

You could add a pin number to the process when submitting the form. You can have it so users can setup a pin in the app itself or some other thing they the approver โ€œknowsโ€ and then require it when clicking approve.

Rifad
Participant V

This is amazing! Is there a way we can return the email metadata like the Message ID back using any work around ?

I donโ€™t think you can do this without writing code and creating a gmail add on.

Hi @Rich thank you for this amazing TIPS.

No you canโ€™t do that.

Since I posted this message have you checked out the new Dynamic email feature for Gmail orgs? This is an easier way to do the same as the above. However it is only currently supported for workspace orgs at this time.

Is it possible to style this page and display the styled content as soon as the user response!

Top Labels in this Space