You have an idea worth sharing, but it needs somewhere to go. A community email needs enough context for somebody who missed the conversation. A short post needs a clear point and a link. Copying the same paragraph into both usually leaves one of them doing a poor job.
This build prepares a small queue from one reviewed source. It keeps the facts together and makes the next writing task visible, while leaving the wording and publication decision with a person. You can try the basic version with a JSON file and Python, then connect a workflow tool if the queue proves useful.
Give the idea enough substance to travel
Start with a source record that says what happened or what you want to explain. Give it an ID, a working title, the central point and a link to the source material. If there is no evidence behind a claim, keep it as a question or remove it. Repeating a claim in several formats does not make it better supported.
Imagine a build note explaining why a motion light kept switching off while someone stood still. The useful point is the difference between detecting movement and knowing a room is occupied. That gives you something concrete to explain in an email or a post. 'Smart homes are changing everything' gives the workflow very little to work with.
Separate the source's facts from your proposed angle. You might want to talk about making a house easier to use, while the source only establishes what a particular sensor detects. A reviewer needs to see where you have made that connection. Keep the original link close enough that checking it is not another research project.
Give the source a revision number. If you correct a fact later, the drafts based on the old version should be recognisable. A stable title is not enough: two records can have the same title and disagree about the detail that matters.
Choose two destinations you will actually use
Begin with a community email and a short post, or another pair you already write. Describe the reader and the job of each piece. For the email, you might need a short explanation and a reason to follow the source link. For the post, you might want one observation and a specific question that people can answer from experience.
Do not add five platforms because the automation tool has connectors for them. Every extra destination creates another draft to review, and the work grows even if creating the rows is instant. Two useful outputs tell you more than a full queue nobody has time to read.
Store the destination as a field, not just a heading embedded in the copy. That lets you filter the queue later and avoids somebody pasting the longer email version into the short-post slot. Keep a separate status for each destination as well: approving one draft should not silently approve the other.
The smallest queue can be a spreadsheet with source ID, revision, destination, draft copy, reviewer and status. You do not need to build a content-management product to try this. Use something another person can open and understand without a tour.
Prepare draft rows without pretending they are finished
Create idea.json in a test folder. Give it id, title, point, source_url, revision and approved fields. Use your own sample text and a source you can check. The approved flag here means the source record has been reviewed; it does not mean the channel copy is ready to publish.
Save the following script as make_queue.py and run it with Python 3. It reads the source and prints two JSON rows. The copy is deliberately simple: a starting structure assembled from the supplied fields, not a claim to have rewritten the idea perfectly for either audience.
Every output starts as needs_review, and each ID combines the source, revision and destination. Repeating the same input produces the same IDs. If you save the output in a queue, use those IDs to update or reject duplicate rows rather than appending another set on every run.
import json
from pathlib import Path
source = json.loads(Path("idea.json").read_text(encoding="utf-8"))
if source.get("approved") is not True:
raise ValueError("Review the source before preparing drafts")
for name in ["id", "title", "point", "source_url"]:
if not isinstance(source.get(name), str) or not source[name].strip():
raise ValueError("Missing " + name)
revision = source.get("revision")
if type(revision) is not int or revision < 1:
raise ValueError("Use a positive revision number")
formats = {
"community_email": source["title"] + "\n\n" + source["point"],
"short_post": source["point"] + "\n\n" + source["source_url"],
}
queue = [{
"id": f"{source['id']}:{revision}:{channel}",
"channel": channel,
"source_revision": revision,
"source_url": source["source_url"],
"status": "needs_review",
"copy": copy,
} for channel, copy in formats.items()]
print(json.dumps(queue, ensure_ascii=False, indent=2))Sources: Python: JSON encoding and decoding.
Use automation for the movement between writing steps
Once the local version is useful, n8n can connect the source, queue and document destination. A new reviewed source can trigger preparation of the draft rows. A later reviewer action can move one row to approved. Keep these as separate events, with enough information to see which source revision produced the draft.
If you include an LLM step, give it the source text, the intended audience and the destination's job. Tell it to keep unsupported details out and leave missing facts unresolved. Then read the output against the source. A model's assurance that it followed instructions is not the review.
You can leave that step out entirely. The example script uses no model, and a human can write the short post from the prepared row. That may be the better fit when the idea depends on personal experience, local context or a particular turn of phrase you do not want flattened into generic copy.
Keep service credentials in the workflow's credential store and out of the content record. The person editing a paragraph should not need to see an API key. In the first version, stop at creating drafts; connect live publishing only after the review and retry behaviour are understood.
Sources: n8n: Code node, n8n: credentials.
Review the meaning, not just the spelling
Put the source and draft beside one another. Check names, dates and numbers first, then the strength of the claim. A source saying a sensor can help with a particular routine should not become a promise that it makes every home safer. This kind of drift can survive a perfectly clean grammar check.
Read the piece as the intended audience. Does somebody need the background that was obvious in the original conversation? Does the proposed question make sense without the picture? Is the link taking them to evidence, a useful explanation or an unrelated landing page? Edit the draft for those decisions before changing its status.
Keep the reviewer and approval time with the row. When the source changes, flag the affected drafts for another look. If someone has already edited a draft carefully, do not overwrite their work with a fresh generated version. Save a new candidate or ask them to resolve the change.
A queue also needs a way to say no. Archived or rejected rows should stay out of the publishing list without disappearing from the history. Sometimes the correct result is deciding that an idea only needed one article, not several smaller posts.
Know what happened after approval
Approval is permission to attempt the next step. It is not proof that the destination received anything. If you add publishing later, keep the provider's post ID or message reference and distinguish accepted, confirmed and failed outcomes. A timeout needs investigation before another attempt creates a duplicate.
For a no-send test, leave publishing disconnected and run the same source twice. Confirm the row IDs match. Change the revision and check that the new rows still need review. Remove the point or unset approval and make sure the script refuses to produce an apparently usable queue.
Try a source containing quotation marks, line breaks and a literal piece of HTML. JSON encoding should preserve it as text. The destination that renders it later must also treat untrusted copy as text or escape it correctly. The Python example prints data; it is not an HTML sanitiser.
The demo worth bringing to a community night is the source, the two drafts and the edit you made before approving one. That shows where automation helped and where your judgement mattered. If the queue saves someone from repeatedly gathering the same material, it has done a useful job.
Sources: n8n: error handling.
Sources and further reading
- Python: JSON encoding and decoding. The local example uses the standard library to preserve structured text.
- n8n: Code node. A JavaScript or Python processing step can fit inside a larger workflow.
- n8n: credentials. Store service access separately from content records.
- n8n: error handling. Keep failed operations visible before retrying.