Zum Inhalt springen
An email turning into structured tasks with check marks — as a glowing low-poly illustration.
All posts
·AIAutomationLaravel

Mail In, Task Out

How an internal tool summarizes incoming project mail with Claude, derives tasks and prepares them as Redmine tickets — without anyone having to learn a new tool.

Incoming project mail turns into a summary and a task — and the control panel is the mailbox that's already open.

At TopRed Media there's a small internal tool: a kind of mini-CRM with customers, projects, meeting notes, time tracking. But the most-used feature isn't the CRM masks. It's the inbox. Every project mail lands there, and the question behind it is always the same: what's in it, and what do I have to do now?

Two manual steps that cost time every day — read the mail, derive the tasks from it. That's exactly where the AI comes in. Not as a chatbot you have to talk to, but as a step in a pipeline that runs in the background. The mail comes in, gets summarized, tasks are derived, and they sit as suggestions next to the note. I confirm, and a Redmine ticket is created. The interface is the inbox I use anyway.

This post describes how it's built, which decisions matter — and why the AI doesn't create the ticket itself.


The Problem: The Inbox Is Manual Labor

Up front, because it's only honest: email isn't the medium you'd pick for structured project communication. Threads with no discernible start, subject lines that stopped matching the content three weeks ago, the actual to-do buried in the second-to-last paragraph below the signature. Everything runs over it anyway — because email has one advantage no nicer solution can beat: it's already there. Everyone has it, everyone uses it, nobody needs convincing. "Established" reliably beats "better".

So I take the inbox as it is. Every mail wants to be read, assigned to a customer or project and checked for to-dos — and the result has to end up in the task tool, not in someone's head. With one project that's done in passing. With a dozen it becomes administrative work.

It's the kind of work that's boring but not unimportant: a task missed in a mail is a missed task. That costs more later than the two minutes the reading would have saved.


How It Works

The backend is a Laravel application, the frontend a Nuxt project. The path of a mail to a task is a chain of small, individually traceable steps:

projekte+114-002@…
  │  subaddress → customer 114, project 002
  ▼  triage:   sort into INBOX/114-002
  ▼  process:  mail → meeting note (MeetingNote)
  ▼  Job 1:    summary       (Claude, tool use)
  ▼  Job 2:    derive tasks  (Claude, tool use)
  ▼  wait:     suggestions sit as "pending" on the note
  ▼  click:    confirm → Redmine ticket

It starts with a triage run over IMAP: based on the subaddress projekte+XXX-YYY@…, every mail is matched to a real customer and project and moved into the matching folder. Anything that can't be assigned unambiguously lands in INBOX/Manuell-klaeren — no guessing, just a clearly marked pile for the hand.

A second run turns every sorted mail into a meeting note. From there two background jobs hang off the note: first the summary, then the task detection. Both call Claude via the Anthropic API — not with a request for prose, but via tool use with a fixed JSON schema. The model gets no "answer nicely", but a tool with precisely defined fields it has to fill:

'tools' => [[
    'name' => 'aufgaben_vorschlaege',
    'input_schema' => [
        'type' => 'object',
        'properties' => [
            'tasks' => [
                'type' => 'array',
                'items' => [/* title (required), description (optional) */],
            ],
        ],
        'required' => ['tasks'],
    ],
]],
'tool_choice' => ['type' => 'tool', 'name' => 'aufgaben_vorschlaege'],

The difference isn't cosmetic. Ask the AI for prose and parse it afterwards, and you've built yourself a source of errors. Give it a schema, and you get structured data back that goes straight into the database without an intermediate step. The summary delivers two fields the same way — a short line for the overview and a detailed Markdown version for the people involved.


Why the AI Doesn't Create the Ticket Itself

A task suggestion that only becomes a ticket after a human approval, while a discarded path fades out — as a glowing low-poly illustration.

The obvious next step would be to write the detected tasks directly to Redmine. The system deliberately doesn't do that.

The AI is good at suggesting tasks from a text. It is not good at deciding which of them become binding. So the last step stays with the human: the suggestions sit as pending on the note, I see them next to the summary, and one click turns them into a ticket — or I discard them. A wrongly created ticket costs more cleanup than a click ever saves.

So the AI doesn't suggest the same things over and over on every run, it gets context about what's already been done or deliberately discarded:

--- Already created as a task (do NOT suggest again) ---
- Draft offer for phase 2

--- Previously discarded (only again if the content clearly warrants it) ---
- Appointment with tax advisor

Plus a few hard limits in the prompt: at most six suggestions, action-oriented titles, and — importantly — an empty list when nothing concrete can be derived. Better two good tasks than six vague ones. An AI that always finds something will eventually find nonsense.

On confirmation the ticket goes out via the Redmine REST API: subject, description, assignee, attachments. The target project follows from the customer/project assignment that was already fixed during triage — if a customer isn't yet linked to Redmine, the system refuses to create the ticket rather than landing it in the wrong project.


What Remains

The same runs not just for mail. A meeting note can just as well come from a phone call, a Teams call or an on-site appointment — the summary and the task detection hang off the note, not off the inbox. The inbox is just the most convenient entry point, because the mail arrives there anyway.

The AI isn't the product here. It's a step in a chain that, without it, consisted of two manual moves per mail. The gain isn't "we use AI now", but that an annoying yet important manual step disappears — without anyone having to learn a new tool. The tool is the inbox.


Conclusion

The interesting question with AI in daily work is rarely "which model". It's: where in the existing process is the step that can be automated without anyone having to change their behavior? Here it was the path from mail to task. Structured output instead of guessed prose, the human as the final authority, clear limits in the prompt — there's no more magic to it than that. But it does the job.


Call to Action

This tool is internal, but the pattern transfers: anywhere a manual step sits between an incoming piece of information and a structured system, there's usually something to save — cleanly, traceably, and with the human in the right place.

If you have such a step in your own operation and wonder whether AI really helps there or is just a buzzword, feel free to reach out. As a backend and solution architect, I build these chains so they're still traceable next year — and so they can be trusted, precisely because the AI doesn't get the last word.