How to Call an API from an Email

joshmoody241 pts0 comments

How to Call an API from an Email · Redo Engineering

Emails can’t do much. They’re built from the same core technologies as webpages,<br>HTML and CSS, but they can’t run JavaScript. This limits interactivity. You<br>can’t do much in an email besides click links.1

The last thing the world needs is a cross-site scripting vulnerability in<br>Outlook.

That’s what Big Email wants you to think.

Turns out emails can do a lot if you know a few tricks. For example, shopping<br>carts require math, state management, and network requests. No problem:

Redo sends millions of emails like this. No JavaScript. 70% email client<br>support.

Odds are you’re writhing on the floor in shock. How? Short answer: dozens of<br>obscure tricks. Too many for one post. I’ll focus on my second favorite: how<br>to call an API without leaving the email.

Let’s use Redo’s subscription manager as an example:

Clicking that button notifies a subscription service to delay the next shipment.<br>No JavaScript nor redirect. It works by combining two unrelated technologies:<br>AMP Email and CSS crimes .

AMP Email

The most mainstream technique for interactive emails is a Google framework<br>called AMP Email. AMP provides a limited set of<br>tools like for submitting data to a server without redirecting. It<br>works in Gmail and Yahoo.2

AMP also works in AOL, FairEmail, and<br>Mail.ru

AMP seems straightforward at first glance, but using it is pretty annoying.<br>Allow me to vent a year of grievances:

AMP has limited HTML/CSS support

In most email clients, HTML and CSS support is stuck in the 90’s. AMP emails are<br>stuck in 2015. An improvement, sure, but that’s still a lot of features you<br>can’t use, like dark mode<br>and the :has selector.3

AMP Email supported<br>CSS.<br>Notable omissions include:<br>!important<br>prefers-color-scheme<br>:has<br>user-select<br>clip-path<br>pointer-events<br>@keyframes<br>::before and ::after

Additionally, AMP emails are extremely strict. If an email uses any unsupported<br>feature, it won’t just ignore it; it will refuse to render the email. A few are<br>easy to stumble into by accident:

More than one element

elements4

http:// urls instead of https://

elements

Selectors targeting AMP internal features<br>i-amphtml5

Any web feature released in the last ten years

Ask me how I know.

You’re supposed to use instead, which Google calls a “powerful replacement”<br>that “may choose to delay or prioritize resource loading based on the viewport position.”<br>What this really means is, “the image will show a loading spinner for way longer<br>than a normal image.”<br>I’ve also run into a weird bug where elements with an off-screen 3D<br>transform never stop showing a loading spinner, even if the image later enters<br>the viewport. Considering AMP devs have never done anything about my other bug<br>reports, I’ve never bothered to document this until now.

This is to prevent working around AMP’s rendering framework, but sometimes it causes weird issues with absolute positioning.<br>Amusingly, their validator isn’t robust enough to catch everything. Here is some<br>actual code I’ve used to fix a rendering bug:<br>// AMP plays dirty by not allowing us to use the string "i-amphtml" in CSS, but they don't check for *="amphtml"<br>const ampPositioningOverrides = `.${sectionId} amp-list {<br>position: unset;<br>.${sectionId} [class*="amphtml-replaced-content"] {<br>position: unset;<br>}`;

On that note, AMP is just weirdly opinionated about some things. For example,<br>dynamic content in an AMP email must either know its height or aspect ratio up<br>front:

amp-list<br>layout="responsive"<br>width="300"<br>height="200"<br>src="https://amp.dev/static/samples/json/examples.json"<br>template type="amp-mustache"> div>{{title}}div> template><br>amp-list><br>This prevents annoying layout shifts where content in the email gets pushed down<br>as content loads. Sure, that is good for the user experience, but it’s also<br>severely limiting in certain situations. The whole point of AMP email is showing<br>dynamic content. Sometimes you don’t know in advance how tall dynamic content is<br>going to be. AMP refuses to budge on this.6

However, at the very least, AMP lets you set the height of dynamic content<br>differently on mobile versus desktop via heights:<br>amp-list<br>layout="responsive"<br>width="300"<br>height="200"<br>heights="(min-width:500px) 100px, 800px"<br>src="..."<br>>amp-list>Useful feature, right? Yeah, it sure would be useful if it were real! The docs<br>claimed this was possible for a long time, but it was never actually supported.<br>The AMP developers removed heights from the docs when I pointed it out.<br>I don’t blame the core AMP devs for this, though.<br>Gmail ghosted me when I submitted a bug report.

AMP is basically abandonware

AMP Email is a subset of a larger initiative from Google called The AMP Project,<br>intended to speed up websites. The AMP framework was universally hated and is<br>rarely used today.7

AMP Email is annoying for all the same reasons that AMP is. It hasn’t had a<br>significant update in years, so I think it’s likely to end up on<br>Killed by Google at some point, although I have<br>no insider...

email content emails from list know

Related Articles