惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

K
Kaspersky official blog
T
Threat Research - Cisco Blogs
N
News and Events Feed by Topic
Hacker News: Ask HN
Hacker News: Ask HN
Project Zero
Project Zero
Application and Cybersecurity Blog
Application and Cybersecurity Blog
博客园 - 叶小钗
Security Latest
Security Latest
Spread Privacy
Spread Privacy
aimingoo的专栏
aimingoo的专栏
N
News and Events Feed by Topic
Webroot Blog
Webroot Blog
U
Unit 42
Cyberwarzone
Cyberwarzone
小众软件
小众软件
Scott Helme
Scott Helme
Engineering at Meta
Engineering at Meta
Microsoft Security Blog
Microsoft Security Blog
T
The Blog of Author Tim Ferriss
A
About on SuperTechFans
爱范儿
爱范儿
S
Schneier on Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Schneier on Security
Schneier on Security
Latest news
Latest news
GbyAI
GbyAI
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
The Register - Security
The Register - Security
WordPress大学
WordPress大学
博客园_首页
Blog — PlanetScale
Blog — PlanetScale
PCI Perspectives
PCI Perspectives
Jina AI
Jina AI
AI
AI
NISL@THU
NISL@THU
I
Intezer
G
GRAHAM CLULEY
B
Blog
S
Secure Thoughts
IT之家
IT之家
宝玉的分享
宝玉的分享
Recent Announcements
Recent Announcements
Y
Y Combinator Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
酷 壳 – CoolShell
酷 壳 – CoolShell
有赞技术团队
有赞技术团队
V2EX - 技术
V2EX - 技术
Recorded Future
Recorded Future
Hacker News - Newest:
Hacker News - Newest: "LLM"

Buttondown's blog

Email could have been X.400 times better The physicists who convinced Fermilab to send Brazil's emails Better in-app previews Analytics 3.0 Subscriber ID variables Comments! Send latest premium action Automation filtering Free API subscribers Surveys in automations Reply to replies Labels for RSS feeds How Jeremy Singer-Vine curates curious datasets for readers 2023 (and what's next) Email vs web content Sort by engagement Better gift subscriptions How Andy Dehnart built a career reviewing television New email template Email-based automations Opt-in reply tracking Automatic alt text More social network integrations Sort by metadata Overlarge image warnings Automation tag actions Pause emails mid-flight Search tags and automations Gift via automations Subscriber-driving emails Programmatic webhooks Email page views Tag statistics Discord webhook formatting Automatic subscriber cleanup RSS subscriber count Weekly subscriber reports More list columns Customizable list views How Max Voltar turned a side gig into a trusted keyboard resource How Nick Disabato runs two newsletters from one design consultancy Made-for-you share images Automation improvements End-of-email surveys Filter by date Survey-triggered automations More automation functionality New webhooks How France Insider built a news service with paid subscribers Email as primary key How John Willshire unites two businesses in one newsletter Confirmation reminders Email churned subscribers Email-to-draft Subscriber metadata columns ChatGPT integration Faster web archives Referral program Better search results TikTok embeds Subscriber timeline Spotify embeds Improved RSS-to-email Subscribe page OG image New analytics page Google Tag Manager Even more subscriber types Integrating Duda with Buttondown Linktree integration guide Advanced and enterprise plans Framer integration guide API requests page Team collaboration In-email surveys Better CSS settings Better RSS automation fetching! Editor toolbar improvements Smart filters Faster emails page RSS automations Faster email analytics Zapier error codes Image accessibility checks Tags vs newsletters OG image picker Image editor improvements API bulk actions Improved OpenAPI spec Mastodon support Better subscriber filtering Better subscriber validation Hotkey support! Programmatic access to analytics Stronger bulk actions Faster archive page Custom canonical URLs Email slug and metadata Improved writing interface Generating a Typescript router in Django Filter emails by source
Automatic image upload with Buttondown + Typora
Jon Sully · 2023-05-03 · via Buttondown's blog

Introduction

If you're a fan of writing content in Markdown there's a high chance you've heard of the absolutely fantastic editor / real-time Markdown rendering genius, Typora. Aside from being simplistic while still having an absolute boat-load of features that we don't have time to get into, suffice it to say that Markdown + Typora is my favorite way to write. The Newsprint Theme is where it's at:

Typora's 'Newsprint' theme

And writing content intended to be sent in Buttondown couldn't be easier. Just write everything up how you like, hit Cmd+/ to switch to source code mode and copy the raw markdown text, then paste it into Buttondown and send! Except... images.

Images are tricky. Typora is more than happy to render your images inline as you write a new document, which is really nice:

image-20230502070736404

But if you're using local images in your document (as you likely would be) you might run into trouble when copying that document over to Buttondown. And 'local' is the keyword here. When Typora renders those local images inline, all it's doing is reading the image content from your filesystem:

image-20230502070822228

Failing email images ahead

And there in-lies the problem. If you were to copy that document over to Buttondown and send it out, that image wouldn't load for anyone!

image-20230502071207221

The source of the generated HTML would still be looking for an image on that local file path, which isn't going to exist on your recipients' machines (or be accessible by their mail clients anyway). Worse still, if you send a draft email to yourself beforehand and open it in your own local email client, since you'd be looking at that draft from the same machine where that image file-path does exist, you may well have the experience of "everything working" and not realize that your images will fail when sending to anybody else.

Upload magic!

Good news, though. Typora has a neat, extensible system built in to automatically upload images to a third-party web service instead of just rendering local images inline. And Buttondown exposes their image upload functionality through their API! Together, with a small chunk of glue-script, we get an experience like this:

trimmed

Any time we paste or drag an image into Typora, it automatically uploads that image to Buttondown's image hosting service and injects the resulting URL into the Markdown for you. Now our image is publicly hosted on the cloud! Even better, once we finish writing our document, we can have confidence that copying it over to Buttondown for sending will bring portable (publicly accessible) image URLs that are safe and ready to be sent in emails!

image-20230502072617589

We've essentially cloned Buttondown's "drag an image into the editor for auto-upload" into Typora 😎

But... how do I do that?

It's actually pretty easy! As Typora notes in their "custom" image upload docs, we just need to provide a script into the Settings -> Image -> Image Uploader: Custom field and set When Insert... to "Upload Image".

image-20230502072821391

We're going to use an inline one-liner bash script to do the uploads for us. This one took some time to craft just right, but does exactly what we need it to. <u>Make sure to grab your API key from Buttondown and add it to this script before pasting into Typora</u>:

API_TOKEN="YOUR_API_KEY" && upload() { for file_path in "$@"; do response=$(curl -s -X POST -H "Authorization: Token $API_TOKEN" -H "Content-Type: multipart/form-data" -F "image=@$file_path" "https://api.buttondown.com/v1/images"); echo $(echo $response | sed 's/.*"image": "\([^"]*\)".*/\1/'); done; return; }; upload

And be careful to copy and paste that code as a single line. It is not a multi-line script.

image-20230502072943868

So what does it do? Let's break it down into multiple lines for readability and we'll see it's not too complicated:

API_TOKEN="YOUR_API_KEY" &&
upload() {
	for file_path in "$@";
	do
	  response=$(curl -s -X POST -H "Authorization: Token $API_TOKEN" -H "Content-Type: multipart/form-data" -F "image=@$file_path" "https://api.buttondown.com/v1/images");
		echo $(echo $response | sed 's/.*"image": "\([^"]*\)".*/\1/');
  done;
  return;
};
upload

Essentially we setup the "upload" routine to iterate over all arguments given to it ($@) and for each, POST it to https://api.buttondown.com/v1/images, Buttondown's image API. We pull the "image" key out of the JSON response with sed and output it to StdOut (which is what Typora wants) — specifically avoiding more eloquent JSON tools like jq since not all Typora users will have that tool installed (or globally available). Once we've gotten through all the arguments, we return!

We're setting this up as a method then ending the command with a call to the method because of how Typora invokes the command. Typora essentially invokes COMMAND "file/path_1.jpg" "file/path_2.jpg" — it just adds the local file-paths as strings immediately after the command. Since we're setting up upload as a routine and ending the command with a call to upload, those appended strings actually get regarded as arguments to upload, exactly what we want.

As always, once you paste in the one-liner, <u>make sure you hit the "Test Uploader" button and get a green, "Successfully get uploaded image url" message</u>.

image-20230502070434529

That's it! Automatic image-upload and ultimate Markdown portability. Enjoy writing your future Buttondown content in Typora!