← Back to the Machine Shop The Machine Shop

If it's repetitive, I automate it.

None of these were requested by an engineering roadmap — they came from noticing a repetitive task in my own workflow or my team's, and deciding it didn't need a human doing it manually anymore. Built with Power Apps and Google Apps Script, because those were the right-sized tools for the job, not because they're impressive.

📲 Push notification tool 📇 Outreach tracker ✉️ Email response tool
📲
Power Apps push notification tool
0Engineering tickets needed
100%Cross-platform delivery, iOS + Android
Self-serveMarketing team owns it

The problem

Sending a one-off push notification — a time-sensitive promo, a service alert — meant filing a request with engineering and waiting in their queue. For anything urgent, that delay could mean the moment had passed by the time it went out.

What I actually built

A Canvas App in Power Apps that lets anyone on the marketing team compose a segmented, rich push notification — title, message, image, target segment, deep link — and send it straight from their phone, no desktop required. Power Automate sits behind it, taking those inputs and firing a direct HTTP call into the MoEngage Campaigns API.

The iOS payload black hole

The front end and the automation logic came together fast. What didn't come together fast was cross-platform delivery: Android rendered the push perfectly every time — image, deep link, all of it — while iOS devices stayed completely silent. MoEngage still returned a clean HTTP 200, so from the outside it looked like it worked; Apple devices were just quietly swallowing the payload.

That took an overnight debugging sprint to run down. The real issue was how the aps dictionary — the Apple-specific push block — was getting nested and escaped inside Power Automate's dynamic content. I isolated the android_payload and ios_payload blocks separately, made iOS's mandatory keys (alert strings, badge counts, sound flags) explicit instead of implicit, and wrote clean string-escaping expressions so a marketer typing spaces or special characters into the app could never break the JSON going out. Once notifications started landing, deep links still opened the app to the wrong screen — fixed by aligning the MoEngage payload's key-value pairs with the Param() logic running on the app's OnStart.

The decisions that mattered

I scoped this tightly on purpose. It would have been easy to over-engineer a full campaign-management tool; instead I built exactly enough to solve the actual complaint (the wait time), kept it zero-middleware by using Power Automate's native HTTP actions instead of a third-party layer, and didn't call it done until Android and iOS were both actually confirmed working.

A 200 response isn't proof it worked. iOS taught me to trust the device, not the status code.
📇
Automated outreach tracker
RESEARCH → REVIEW → READYStatus workflow
dailyRun()Scheduled Apps Script trigger

The problem

Personal cold-outreach — pitching my own writing and projects to outlets — kept falling through the cracks. There was no system tracking who I'd already contacted, what pitch I'd sent, or what stage each lead was at. Good targets got forgotten; some got pitched twice.

What I actually built

A Google Sheet became the single source of truth, moved through a deliberate RESEARCH → REVIEW → READY pipeline: a row starts as a researched lead, gets reviewed and drafted (with dedicated Subject and Preview-text columns so the pitch is fully written before it ever sends), and once marked READY, a scheduled dailyRun() Apps Script function picks it up and sends it automatically on the next run. I used this for real outreach — pitches to outlets like AfricanWriter.com and Brittle Paper went out through this exact pipeline.

The decisions that mattered

The status-column workflow is the whole trick — it turns a spreadsheet into a lightweight CRM without needing an actual CRM. Separating "researched" from "ready to send" forced me to actually finish writing a pitch before it could go out, which cut down on rushed, generic outreach.

What's next

Adding a REPLIED / FOLLOWED-UP status pair so the same sheet tracks the back half of the pipeline, not just the send.

Nothing here is a "prompt trick" — it's a real scheduled trigger, moving real leads through a real pipeline, with actual sent pitches behind it.
✉️
Email response tool
Hours/weekReclaimed
Judgment calls onlyWhat I still handle by hand

The problem

A handful of email types show up on a predictable cadence and need close to the same response every time. Answering each one individually, every day, is time that should go to the emails that actually need a person thinking about them.

What I actually built

An Apps Script tool layered on top of Gmail that recognizes recurring, predictable email patterns and drafts (or sends) the appropriate response automatically. It's deliberately conservative about what it auto-handles — anything ambiguous or emotionally loaded gets flagged for me instead of answered on its behalf.

The decisions that mattered

The scope boundary was the important design call: automate the genuinely repetitive, low-risk categories, and route everything else to a human, every time. That's what makes it safe to run unattended — it's not trying to be clever about ambiguous messages, it's only confident about the ones it's actually seen a hundred times before.

Automation isn't "replace all the judgment," it's "free up the judgment for where it's actually needed."
Want to see this reasoning applied to your workflow?

Run a fit check with April.

Go to Fit Check →
AprilFaith's assistant

Visual interview with AI Faith

This is a recorded, consent-first conversation with an AI clone of Faith. By continuing, you agree the session may be recorded so the real Faith can review it and follow up personally.