Uploading Medium Articles with AWS Lambda
Medium itself does not support editing code blocks, and while the reason behind this is unclear (perhaps engineers are not the primary audience), one way to highlight code is by directly pasting images, or by posting it on Gist and then embedding it into the article.
While using images to showcase code can achieve the highlighting effect, it is quite unfriendly for engineers, as they cannot test the code through copy and paste, nor can they edit the article without manually editing the images, which can be quite cumbersome.
However, using Gist also comes with several issues:
- The mobile version cannot display it, and instead shows a link rather than the embedded content.
- Posting code to Gist can be too tedious. (However, using extensions like those for VSCode or Sublime to upload to Gist is a nice alternative.)
To enable highlighted code blocks on Medium, I ultimately decided to use AWS Lambda to address this issue.
AWS Lambda
For readers unfamiliar with Lambda, there are plenty of resources available online, so I won’t dwell on that here. Lambda allows you to have AWS execute the functions you desire without needing to set up an actual server (though there is still a server behind the scenes). This way, you don’t need to deploy a function to a machine or maintain it; you simply execute it.
Github Issue
To connect to the Lambda endpoint, I decided to trigger it via a GitHub webhook. GitHub allows you to write Markdown in issues, upload images (hosted by GitHub), preview, and use code blocks, which is quite convenient. When you’re ready to publish an article, you can close the issue to trigger the webhook, which in turn uploads the code block to Gist via Lambda, and finally calls the Medium API to create the article.
Medium API
The Medium API is concise and lightweight, yet very user-friendly. First, go to your personal page’s settings > Integration tokens to generate a token, then use that token to call the API for creating articles.
Gist API
The Gist API operates similarly. To keep your Gist organized, it’s advisable to create a separate account specifically for storing code used in articles. Go to settings > developer settings > personal access token > generate token to create a token, making sure to check the Gist permission.
Connecting to Lambda
Once you’ve completed the preliminary work, you can start integrating with Lambda.
First, place the created Lambda endpoint into the GitHub webhook, and then find a package that can convert Markdown to HTML (I used marked). Combine these components, and you’re good to go!
A simple implementation can be found here. Although it may seem a bit tedious, it’s actually quite convenient. I wonder when Medium will finally support code blocks. QQ.
Related Posts
- When Measurement Becomes the Goal: From Window Tax to PR Counts I once wrote a small tool to count how many PRs I had contributed in a quarter, how many reviews I had left, and how many tickets I had closed, hoping to use the numbers to prove my output to my manager. My manager simply said performance is not judged by output alone. Only years later did I understand—when measurement becomes the goal, it is no longer a good measure. From Britain’s window tax and the Hanoi rat bounty to evaluating developers by PR count today, the mechanism is exactly the same.
- Using Cloudflare Images for Image Storage and Transformation Putting an image on a web page is the easiest thing in frontend. But doing it properly — resizing, generating every format, holding up under traffic — turns into a whole solution of its own. I ended up handing all of it to Cloudflare Images and keeping just one original.
- Stop Using Access Keys Already Access Keys are an easily overlooked security risk on AWS. Use OIDC with IAM Roles so GitHub Actions can securely access AWS resources without any secrets.
- Database Primary Keys: AUTO_INCREMENT, UUID, and UUIDv7 Backend developers often have to decide on a primary key: auto increment or UUID? What about collisions? How much faster is UUIDv7 compared with created_at + index? After benchmarking 20 million rows and looking at the design trade-offs, this post gives you the answer.