One keyword, one email, one new calendar event. You want the first matching email, and you want its snippet to become the event title. How do you find the first matching item in a list without iterating twice?
A generator expression inside next()? Like next((m for m in messages if keyword in m['snippet']), None) — or is there something simpler?
That's the sharp version. next() on a generator stops at the first match and takes a default if nothing matches — no full-list scan, no IndexError:
match = next(
(m for m in messages if keyword.lower() in m.get("snippet", "").lower()),
None,
)And if match is None I early-return — otherwise I use its snippet as the event title?
Exactly the chain. Guard, extract, write — same skeleton as Day 17 with a filter on the read side:
def schedule_followup_from_email(keyword: str) -> str:
emails = toolset.execute_action(Action.GMAIL_FETCH_EMAILS, {"max_results": 10})
messages = emails.get("messages", [])
match = next((m for m in messages if keyword.lower() in m.get("snippet", "").lower()), None)
if match is None:
return ""
title = match.get("snippet", "")
toolset.execute_action(Action.GOOGLECALENDAR_CREATE_EVENT, {"summary": f"Follow up: {title}"})
return titleThe event has no time — is that OK? Don't calendar events need a start and end?
The Composio create_event accepts just a summary and the API defaults the time to a reasonable slot — usually a short block today or tomorrow. If you need exact timing, add start and end params; for a "follow up later" nudge, summary-only is the most common call.
So one keyword walks my inbox and a calendar event gets born — that is the shape of every "turn an email into an action" script?
Filter, pick, write. This pattern works whether the target is a task, an event, a document, or a Slack message. Swap the write enum; the rest is cut-paste.
TL;DR: next(generator, None) gives you the first match with a safe default — no crash on miss.
next()if match is None: return ""summary=f"Follow up: {title}"| Goal | Use |
|---|---|
| First matching item | next(gen, None) |
| All matching items | [x for x in xs if ...] |
| Does any match | any(... for x in xs) |
next() short-circuits on the first hit. Use it whenever you only need one result.
One keyword, one email, one new calendar event. You want the first matching email, and you want its snippet to become the event title. How do you find the first matching item in a list without iterating twice?
A generator expression inside next()? Like next((m for m in messages if keyword in m['snippet']), None) — or is there something simpler?
That's the sharp version. next() on a generator stops at the first match and takes a default if nothing matches — no full-list scan, no IndexError:
match = next(
(m for m in messages if keyword.lower() in m.get("snippet", "").lower()),
None,
)And if match is None I early-return — otherwise I use its snippet as the event title?
Exactly the chain. Guard, extract, write — same skeleton as Day 17 with a filter on the read side:
def schedule_followup_from_email(keyword: str) -> str:
emails = toolset.execute_action(Action.GMAIL_FETCH_EMAILS, {"max_results": 10})
messages = emails.get("messages", [])
match = next((m for m in messages if keyword.lower() in m.get("snippet", "").lower()), None)
if match is None:
return ""
title = match.get("snippet", "")
toolset.execute_action(Action.GOOGLECALENDAR_CREATE_EVENT, {"summary": f"Follow up: {title}"})
return titleThe event has no time — is that OK? Don't calendar events need a start and end?
The Composio create_event accepts just a summary and the API defaults the time to a reasonable slot — usually a short block today or tomorrow. If you need exact timing, add start and end params; for a "follow up later" nudge, summary-only is the most common call.
So one keyword walks my inbox and a calendar event gets born — that is the shape of every "turn an email into an action" script?
Filter, pick, write. This pattern works whether the target is a task, an event, a document, or a Slack message. Swap the write enum; the rest is cut-paste.
TL;DR: next(generator, None) gives you the first match with a safe default — no crash on miss.
next()if match is None: return ""summary=f"Follow up: {title}"| Goal | Use |
|---|---|
| First matching item | next(gen, None) |
| All matching items | [x for x in xs if ...] |
| Does any match | any(... for x in xs) |
next() short-circuits on the first hit. Use it whenever you only need one result.
Create a free account to get started. Paid plans unlock all tracks.