feat(mailtrap): add Mailtrap email, contacts, and email logs integration - #7564
feat(mailtrap): add Mailtrap email, contacts, and email logs integration#7564dr-3lo wants to merge 2 commits into
Conversation
|
@dr-3lo is attempting to deploy a commit to the Sim Team on Vercel. A member of the Team first needs to authorize it. |
Greptile SummaryThe PR adds a complete Mailtrap integration for sending email, managing contacts and contact lists, and querying email logs. The latest changes address prior review feedback by:
Confidence Score: 5/5The PR appears safe to merge; the latest changes fully address the reviewed recipient-parsing and malformed-response concerns without introducing a new actionable defect. Recipient tokenization now rejects unmatched delimiters and validates complete bare addresses, while response transforms require each endpoint’s defining nested payload or identifier before reporting success. All previous findings are resolved, and no new repository-rule violation or blocking behavior remains.
|
| Filename | Overview |
|---|---|
| apps/sim/tools/mailtrap/utils.ts | Adds balanced-delimiter checks, stricter address validation, and endpoint payload assertion helpers; the reviewed changes correctly address the prior parser and malformed-response concerns. |
| apps/sim/tools/mailtrap/mailtrap.test.ts | Adds focused regressions for unbalanced recipient syntax and missing defining response payloads. |
| apps/sim/tools/mailtrap/get_email_log.ts | Requires a non-empty message identifier before returning a successful normalized email-log result. |
| apps/sim/tools/mailtrap/list_email_logs.ts | Requires the response’s messages slice to be an array before mapping paginated email logs. |
| apps/sim/tools/mailtrap/create_contact.ts | Requires the nested contact payload to exist before mapping a successful create response. |
| apps/sim/tools/mailtrap/update_contact.ts | Requires the nested contact payload to exist before mapping a successful update response. |
| apps/sim/tools/mailtrap/get_contact.ts | Requires the nested contact payload to exist before mapping a successful lookup response. |
| apps/sim/tools/mailtrap/create_contact_list.ts | Validates that successful single-list responses include a numeric list identifier. |
| apps/sim/tools/mailtrap/get_contact_list.ts | Validates that retrieved contact-list responses include their defining numeric identifier. |
| apps/sim/tools/mailtrap/update_contact_list.ts | Validates the defining list identifier before returning an updated contact list. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
W[Sim workflow] --> B[Mailtrap block]
B --> S[Send email]
B --> C[Contacts]
B --> L[Contact lists]
B --> E[Email logs]
S --> T[Transactional API]
S --> U[Bulk API]
S --> X[Sandbox API]
C --> A[Mailtrap account API]
L --> A
E --> A
T --> V[Validated response mapping]
U --> V
X --> V
A --> V
V --> O[Structured tool output]
Reviews (3): Last reviewed commit: "fix(mailtrap): validate nested payloads ..." | Re-trigger Greptile
Add Mailtrap alongside the existing email integrations (agentmail, mailgun,
resend, sendgrid, smtp, gmail).
Tools (apps/sim/tools/mailtrap/, 12):
- send_email — transactional, bulk, or sandbox stream; text/HTML/template
body, cc/bcc/reply-to, category, custom variables, custom headers
- create_contact / get_contact / update_contact / delete_contact
- list_contact_lists / create_contact_list / get_contact_list /
update_contact_list / delete_contact_list
- list_email_logs / get_email_log — curated filter set with fixed operators
(subject match contain/equal/empty; status/category/stream accept a
comma-separated any-of list); negation, event, open/click count, and
IP/domain filters are intentionally not exposed yet
All tools call the Mailtrap API directly over the shared tool transport,
token-scoped Bearer auth. Shared response mappers and output schemas live
in types.ts / utils.ts. A mailtrap-errors extractor normalizes the
sending API ({success,errors[]}) and account API ({error}/{errors})
error envelopes.
Block, icon, and catalog:
- MailtrapBlock + MailtrapBlockMeta (blocks/blocks/mailtrap.ts), registered
in blocks/registry-maps.ts
- theme-aware MailtrapIcon (components/icons.tsx)
- regenerated tools/generated/{tool-ids,tool-metadata,tool-outputs}.ts
- generated docs page (apps/docs) + synced icon maps, meta.json, and
packages/deployment-config integrations.json
Tests: apps/sim/tools/mailtrap/mailtrap.test.ts covering address
parsing, stream routing, filter query building, response normalization,
the error extractor, and a transformResponse cohort invariant.
70aa23e to
46c62f8
Compare
|
@greptileai the fixes force-pushed: amended the single commit with the review fixes.
|
…ters
Response payloads (utils.ts + read transforms):
- add expectRecord / expectArray / expectContactList / expectSendingMessage
- get/create/update_contact require the `data` object; the contact-list
transforms require a numeric `id`; get_email_log requires a `message_id`;
list_email_logs requires a `messages` array
- a well-formed 2xx body that is missing its defining slice ({} on
get_contact, { "messages": "bad" } on list_email_logs) now fails instead
of producing a fabricated empty result
- the list transforms keep the lenient per-row mappers, so one bad row
does not drop the whole page
Recipient tokenizer (utils.ts):
- splitAddressEntries throws on an unbalanced quote or angle bracket
instead of running to the end of the string and absorbing every
following recipient into one entry
- each address is checked against a bare-address pattern
(/^[^\s"<>,@]+@[^\s"<>,@]+$/) rather than a bare "contains @" test, so a
value carrying spaces, commas, or brackets is rejected
|
Made changes to address your concerns: Response payloads (utils.ts + read transforms):
Recipient tokenizer (utils.ts):
|
Summary
Adds a Mailtrap integration alongside the existing email integrations (agentmail, mailgun, resend, sendgrid, smtp, gmail).
Tools (
apps/sim/tools/mailtrap/, 12):send_email— transactional / bulk / sandbox stream; text, HTML or template body;cc/bcc/reply-to, category, custom variables, custom headers
create_contact,get_contact,update_contact,delete_contactlist_contact_lists,create_contact_list,get_contact_list,update_contact_list,delete_contact_listlist_email_logs,get_email_log— curated filter set with fixedoperators (subject match contain/equal/empty; status/category/stream take a
comma-separated any-of list). Negation, event, open/click-count and IP/domain
filters are intentionally out of scope for the first version.
All tools call the Mailtrap API directly over the shared tool transport with token-scoped Bearer auth. Shared response mappers and output schemas live in
types.ts/utils.ts. Amailtrap-errorsextractor normalizes both the sendingAPI (
{success, errors[]}) and the account API ({error}/{errors}) envelopes.Block / icon / catalog:
MailtrapBlock+MailtrapBlockMeta, theme-awareMailtrapIcon, regenerated tool metadata and docs, synced integration catalog.Type of Change
Testing
Automated —
apps/sim/tools/mailtrap/mailtrap.test.ts, 61 cases:"Name <email>", comma lists, quotes), id-list and JSON-record parsingsend_emailstream routing (transactional/bulk/sandbox host + sandbox-id path), invalid stream / missing sandbox id / empty subject / missing body guards, template-only send, recipient parsing across to/cc/bccsubjectMatchcontain/equal/empty, comma-separated status/category sent asvalue[], empty-CSV drop, URL encodingmailtrap-errorsextractor across its three envelope shapestransformResponsecohort invariant asserting all 12 tools tolerate an empty and a non-JSON 200 bodyRun:
cd apps/sim && bunx vitest run tools/mailtrap/mailtrap.test.tsRepo checks (green):
type-check,biome,tool-metadata:check,docs:check,check:canvas-sentences,check:tool-request-boundary,check:api-validation,check:bare-icons.Manual — against a real Mailtrap account on a local instance:
Reviewer focus:
apps/sim/tools/error-extractors.tstypes.ts(pattern mirrorstools/harmonic/types.ts)Checklist
Screenshots/Videos