heinzel-zoom
Read the meetings you held on Zoom, and what was decided in them, from the meeting-summary emails Zoom sends: the
meetings capability (ADR 0028), a first-party
Heinzelmännchen plugin. It reads those emails through whichever adapter serves mail, so it needs
no Zoom API access and no Zoom credentials. It is independently released and installed explicitly:
hz system plugin add zoom --confirm # a compatible plugin release; run it again to upgrade
hz system plugin remove heinzel-zoom
Set up
-
Have Zoom mail you its summaries. In the Zoom web portal, go to Settings > AI Companion > Meeting summary with AI Companion. Switch it on and share summaries by email with yourself: as the host, or as an invitee when the host shares them. An account admin may have to allow this first. Zoom sends the summary when the meeting ends.
-
Bind a mail adapter that reads the mailbox the summaries arrive in, for example the Google Workspace plugin's, or your company's own. Then bind this plugin to
meetings. Use your user configuration, never a projecthz.toml, which Heinzelmännchen ignores for bindings:hz system config set capabilities.mail <a mail adapter> hz system config set capabilities.meetings zoom
hz system doctor checks both bindings and says where summaries are switched on. It reads no mail and contacts
nothing.
Is it connected?
Bound automatically to meetings while it is the only installed adapter, ADR
0055. It has
no sign-in of its own: hz system connector test zoom lists the last day's summary emails through the bound mail
adapter (no message is opened), and only when you run it.
Use
Workflows ask for meetings, never for Zoom:
from datetime import datetime
from heinzel import Meetings, Module, Transcript, Window
module = Module("prep", "One-on-one preparation.", requires=["meetings:read"])
@module.operation
def decided(meetings: Meetings, since: datetime, until: datetime) -> list[Transcript]:
"""What this week's meetings decided."""
return meetings.transcripts(Window(since=since, until=until))
| Method | What it reads |
|---|---|
ended(window) |
mail.messages(zoom.query, window), keeping messages whose subject is a Zoom summary, then each one with mail.read |
transcripts(window) |
the same messages, each summary that has sections as a transcript |
transcript(meeting) |
mail.read(meeting), refused unless it matches zoom.query and is a Zoom summary |
What a meeting holds:
Meeting.id: the summary email's id.title: taken from the subject,Meeting summary for <title> (<date>)orMeeting assets for <title> are ready!.conference_id: the meeting number, fromMeeting ID:in the body, so a calendar event can be matched to it.ended_atandstarted_at: the meeting ended when the summary arrived. It started that long before if the summary states aDuration:; otherwise both times are when the summary arrived.participants: names only, and only when the summary lists them.
A transcript here is the summary, not a verbatim record, because Zoom's summary emails contain no transcript. It has
one segment per section (Quick recap, Next steps, and each topic under Summary), without a speaker, at offset 0.
Replies and forwards (Re:, Fwd:) are someone's mail about a summary, not Zoom's, so they are skipped. The
summary's content ends at Zoom's footer. Links keep no query or fragment, which could carry an address or a token.
Mail stays private:
- Every string passes
clean_text. - A name that is an email address is dropped.
- An address in the summary's text becomes
[address]. - Senders' addresses never reach a workflow's agent, because the packet builder drops them.
Limits: a message longer than 200,000 characters is no Zoom summary, so a window skips it and transcript refuses
it. A window with more than 500 summaries or more than 2,000,000 characters of them fails and says to ask for a
shorter one. The mail adapter applies its own limits too. Each summary is read with its own mail.read, one after the
other.
hz zoom info # this plugin, its version and the mail query it uses
hz system capability list # who reads what, through which adapter and hosts
hz system doctor # bindings and where summaries are switched on; reads no mail
Settings
[zoom]
query = "from:zoom.us" # the mail query that finds Zoom's summaries; ignored in a project hz.toml
query uses the mail capability's syntax: from:, subject: and label:, for example
from:zoom.us label:Meetings for summaries a mail filter files under a label. Messages whose subject isn't a Zoom
summary are skipped. The plugin itself sends nothing anywhere: hz system capability list shows no hosts for it, and
the mail adapter's own hosts for mail.
Development and release commands: repository guide.
Migration provenance: heinzel, before the 0.9 plugin-boundary migration.
Metadata
Release files for heinzel-zoom 0.9.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| heinzel_zoom-0.9.1.tar.gz | 96.4 kB | Without provenance | Details for heinzel_zoom-0.9.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| heinzel_zoom-0.9.1-py3-none-any.whl | Python 3 | none | any | Details for heinzel_zoom-0.9.1-py3-none-any.whl |
Total release size: 111.6 kB
Release files / heinzel_zoom-0.9.1.tar.gz
| Download URL | heinzel_zoom-0.9.1.tar.gz |
|---|---|
| Size | 96.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
665c558299250ba872ce26bf0bc230b485a4553c5ed518e355c68337a8fb459c
|
|
BLAKE2b-256 checksum How to use checksums |
9eec1b321c128012230dde5b526220f092241647f0372d5a9ba58c19ef3e163a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / heinzel_zoom-0.9.1-py3-none-any.whl
| Download URL | heinzel_zoom-0.9.1-py3-none-any.whl |
|---|---|
| Size | 15.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
867ee2c1581a98a4a2b6bb130681ecb27495a2afb1c446c504b274712bffe5c2
|
|
BLAKE2b-256 checksum How to use checksums |
ecde2ccf6f28c49e407fe68b0c1b94bac6f06414c925d7b7ca24529f24f5de9b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.6 {"installer":{"name":"uv","version":"0.13.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for heinzel-zoom 0.9.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.