The moment it happens
Turn a document into a blog post you approve by email
Send a PDF to your trigger link and a WordPress draft is written from it; reply "approve" to the email and the post goes live.
- Runs
- The moment it happens
- Apps
- Gmail, WordPress
- AI
- Yes, uses the built-in AI allowance
- Access
- WordPress write; Gmail gmail.send + gmail.readonly
Send this to your assistant
Create a ClickRuntime automation: when I send a PDF to my trigger link, write a blog post from it, save it as a WordPress draft, email me the link, and publish it when I reply "approve".
First time? Adding ClickRuntime to your assistant takes about two minutes.
Why use it
Why teams use this automation
A charity's programme team writes detailed reports on each project, and the communications lead wants every report to become a blog post for supporters. Turning a twelve-page PDF into an article, then chasing a director for sign-off, means most reports never make it onto the website.
This automation handles both steps. A PDF sent to the trigger link is turned into a draft post by AI and saved in WordPress, and an email with the preview link goes to the approver. When they reply "approve" in the same thread, the post is published, with no need to log in.
What you get out of it
Reports reach supporters
Work already written up for internal use becomes public content. Supporters see what their donations achieve.
Sign-off by reply
Approvers only need to reply to an email. Directors who never log in to WordPress can still approve posts quickly.
A clear approval trail
The approval lives in an email thread, so it is easy to show who approved what and when.
Nothing published without a yes
Posts stay as drafts until the approver replies. Edits can be made in WordPress before approving.
How it works
What happens, step by step
When a PDF arrives at the automation's trigger link, ClickRuntime reads its text and AI writes a blog post from it.
The post is saved as a WordPress draft, and an email with the preview link is sent to the approver.
Every 10 minutes, ClickRuntime checks that email thread for a reply.
When the approver replies "approve", the draft is published and they get a confirmation with the live link.
Before it runs live
- Connect Google through your own Google app (a one-time, 10-minute setup), so it works with your own Gmail
- Connect WordPress
- Paste your automation's link into the other app's webhook settings
What you get
Build your own
Need it to work differently?
Your own rules
Conditions, thresholds, filters and exceptions, written the way you'd explain them to a colleague.
Any number of apps
One automation can read from one app and update several others. Over 248 apps are ready, and anything with an API works too.
AI where it helps
Summaries, classification, extraction and drafts use ClickRuntime's built-in AI, with no extra key.
On a schedule or on each event
Runs as often as every 5 minutes, or the moment an app sends an event, and keeps track of what it already handled.
Changes you can ask for
- Act only on the items that match your own rules, and skip the rest
- Change what the AI looks for, or how it writes the result
- Add another app, for example also send it to Slack
- Combine it with other Gmail and WordPress steps into one automation
Under the hood
The code that runs this automation
import base64, io
from email.mime.text import MIMEText
from pypdf import PdfReader
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from clickruntime import on_event, on_trigger, credentials, http, state, ai
APPROVER = "director@example.org"
SCHEMA = {"type": "object", "properties": {k: {"type": "string"} for k in ["title", "excerpt", "body_html"]}, "required": ["title", "excerpt", "body_html"]}
WP = "https://blog.example.com/wp-json/wp/v2"
def wp(method, path, **kw):
r = http.request(method, f"{WP}/{path}", auth=(credentials.secret("WP_USER"), credentials.secret("WP_APP_PASSWORD")), **kw)
r.raise_for_status()
return r.json()
def send_email(to, subject, text, thread_id=None, reply_to=None):
mime = MIMEText(text)
mime["to"], mime["subject"] = to, subject
if reply_to:
mime["In-Reply-To"] = reply_to
body = {"raw": base64.urlsafe_b64encode(mime.as_bytes()).decode(), **({"threadId": thread_id} if thread_id else {})}
return build("gmail", "v1", credentials=Credentials(credentials.connection("google", "work")), cache_discovery=False).users().messages().send(userId="me", body=body).execute()
@on_event
def handle(event):
text = " ".join(p.extract_text() or "" for p in PdfReader(io.BytesIO(event.body.encode("latin-1"))).pages)[:20000]
art = ai.generate(f"Turn this report into a 900-word blog post for supporters (HTML body):\n{text}", json_schema=SCHEMA, max_output_tokens=2048).json
post = wp("POST", "posts", json={"title": art["title"], "excerpt": art["excerpt"], "content": art["body_html"], "status": "draft"})
sent = send_email(APPROVER, f"Approve post: {art['title']}", f"Preview: {post['link']}&preview=true\n\nReply 'approve' to publish.")
state.set("waiting", (state.get("waiting") or []) + [{"thread": sent["threadId"], "post": post["id"]}])
return {"draft": post["id"]}
@on_trigger
def check_replies(event):
gmail, waiting = build("gmail", "v1", credentials=Credentials(credentials.connection("google", "work")), cache_discovery=False).users(), state.get("waiting") or []
for w in list(waiting):
msgs = gmail.threads().get(userId="me", id=w["thread"], format="full").execute()["messages"][1:]
if any(m.get("snippet", "").lower().startswith("approve") for m in msgs):
link = wp("POST", f"posts/{w['post']}", json={"status": "publish"})["link"]
send_email(APPROVER, "Published", link, thread_id=w["thread"])
waiting.remove(w)
state.set("waiting", waiting)
return {"waiting": len(waiting)}FAQ
Common questions
How do I send the PDF?
What counts as approval?
How quickly is it published after I reply?
What permissions does it need?
Does it need AI?
How many runs does it use?
Can I change how it works?
Related
You might also like
Draft a weekly SEO blog post and get the link by email
Each week the next keyword on your list becomes a WordPress draft, and an email with the edit link arrives in your inbox for review.
See how it worksDraft WordPress posts from new feed articles with an email summary
New articles from your feeds become WordPress drafts written in your own words, and you get an email listing the drafts that were added.
See how it worksGet error alerts with a plain-English explanation
When one of your jobs or systems fails, #ops gets the error and a one-line guess at the cause, without the same error twice in an hour.
See how it worksKeep exploring
Set up “Turn a document into a blog post you approve by email” from your assistant
Copy the prompt above, or connect your assistant first. Free plan, no credit card.