tommy

command module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 6, 2026 License: MIT Imports: 1 Imported by: 0

README

tommy

tommy stands in for the services an application talks to but which are awkward to run locally — mail providers, SMS gateways, file transfer, chat webhooks, and more to come — and shows you exactly what your code sent. It answers the fake vendor APIs the way the real ones do, so official SDKs work against it unmodified, and it gives you a UI, a JSON API and an SSE stream to inspect every message as it arrives.

Point your application's mail, SMS, file-transfer or chat client at tommy instead of Mailjet, SendGrid, Twilio, a real SMTP/FTP/SFTP server or a Slack/ Teams webhook; nothing is ever delivered anywhere, and every message it captured is one API call or one browser tab away.

30-second quickstart

Nothing to build and no Go toolchain — one line is the whole of the setup:

docker run --rm -p 8811:8811 -p 8822:8822 can3p/tommy

That publishes the two ports everything HTTP needs: the UI and the API on 8811, the fake vendor ingress on 8822. Anything that speaks a protocol of its own — SMTP, FTP, SFTP, TFTP, NFS, MLLP, SNMP traps — has a listener to publish as well, and FTP additionally needs to be told an address it can hand back to a client. docker-compose.yml is that stack already wired up, and docs/docker.md is the reference for both: every port, the /data volume, and how to narrow the image down to one plugin with a mounted config.

A binary you installed or built yourself is the same server:

tommy serve
tommy is running
  ui       http://127.0.0.1:8811/ui/
  api      http://127.0.0.1:8811/api/v1
  ingress  http://127.0.0.1:8822
  plugin   mail ([mailjet resend sendgrid smtp])
  plugin   sms ([twilio])
  plugin   files ([ftp sftp tftp nfs])
  plugin   chat ([slack msteams])
  plugin   hl7 ([mllp])
  plugin   snmp ([trap])
  plugin   push ([fcm apns])
  plugin   as2 ([http])
run `tommy providers` for copy-paste examples

In another terminal, send it something:

curl -s http://127.0.0.1:8822/v3.1/send \
  -u "any-key:any-secret" -H 'Content-Type: application/json' -d '{
  "Messages":[{"From":{"Email":"a@example.com","Name":"Alice"},"To":[{"Email":"b@example.com"}],
  "Subject":"Hello from tommy","TextPart":"It works."}]}'

Then open http://127.0.0.1:8811/ui/ to see it in the inbox, or:

curl -s "http://127.0.0.1:8811/api/v1/events?plugin=mail"

You do not have to go looking for it, though. Every response tommy sends names what it captured, so the link is already in your application's log:

curl -si http://127.0.0.1:8822/v3.1/send -u any:any \
  -H 'Content-Type: application/json' -d '{"Messages":[{"From":{"Email":"a@example.com"},
  "To":[{"Email":"b@example.com"}],"Subject":"Open me","TextPart":"It works."}]}' | grep -i x-tommy
# X-Tommy-Event-Url: http://127.0.0.1:8811/ui/events/01a07138320d00019f31cb1b

That URL is the mail on a page of its own — the rendered body, the headers, the raw request. Every event the API returns carries the same link in its url field, on /api/v1/events, on the SSE stream and on each plugin's own read-back API, so a test that just sent something can print where to look at it.

tommy providers prints every enabled plugin and provider, its endpoints and a ready-to-run snippet for each one, rendered against whatever ports your configuration actually bound — useful before you've sent anything at all.

What ships today

Plugin Providers What it fakes
mail mailjet, sendgrid, resend, smtp The vendor HTTP send APIs, plus a real SMTP listener
sms twilio The Programmable Messaging REST API (create, list, fetch)
files ftp, sftp, tftp, nfs Real FTP, SFTP, TFTP and NFSv3 servers, backed by one shared virtual filesystem
push fcm, apns Firebase Cloud Messaging's HTTP v1 send API and Apple's HTTP/2 provider API, shown as lock-screen cards
hl7 mllp A real MLLP listener that parses HL7 v2 and answers with a mechanical ACK
chat slack, msteams Slack incoming webhooks + chat.postMessage, and both generations of Teams incoming webhook
snmp trap A real UDP trap receiver: v1/v2c traps and informs, every varbind decoded by its wire type
as2 http RFC 4130 EDIINT over HTTP: unwraps signed/encrypted/compressed messages and answers with a real MDN receipt

Every plugin and provider describes itself: Description(), the endpoints it mounts, and at least one runnable snippet, surfaced identically in the UI's "How to test" panel, GET /api/v1/plugins and tommy providers. The snippets below are exactly those, and every one has been run against a live tommy serve while writing this document.

mailjet — POST /v3.1/send
curl -s http://127.0.0.1:8822/v3.1/send \
  -u "any-key:any-secret" -H 'Content-Type: application/json' -d '{
  "Messages":[{"From":{"Email":"a@example.com","Name":"Alice"},"To":[{"Email":"b@example.com"}],
  "Subject":"Hello from tommy","TextPart":"It works."}]}'

Any Basic-auth credentials are accepted and recorded by default; pin api_key/secret_key in [plugins.mail.providers.mailjet] to make a mismatch return Mailjet's real 401.

sendgrid — POST /v3/mail/send
curl -si http://127.0.0.1:8822/v3/mail/send \
  -H 'Authorization: Bearer SG.fake-key' \
  -H 'Content-Type: application/json' -d '{
  "personalizations": [{"to": [{"email": "bob@example.com", "name": "Bob"}], "subject": "Hello from tommy"}],
  "from": {"email": "alice@example.com", "name": "Alice"},
  "content": [
    {"type": "text/plain", "value": "It works."},
    {"type": "text/html", "value": "<p>It <b>works</b>.</p>"}
  ]
}'

Answers 202 with an empty body and an X-Message-Id header, exactly like the real API.

smtp — a real SMTP listener on :1025
curl -s smtp://127.0.0.1:1025 \
  --mail-from alice@example.com --mail-rcpt bob@example.com -T - <<'MSGEOF'
From: Alice <alice@example.com>
To: Bob <bob@example.com>
Subject: Hello from tommy

It works.
MSGEOF

No AUTH is required; if a client offers one it is recorded, never checked, unless username/password are pinned in config.

twilio — POST /2010-04-01/Accounts/{sid}/Messages.json
curl -s -u ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:authtokenxxxxxxxxxxxxxxxxxxxxxxxx \
  http://127.0.0.1:8822/2010-04-01/Accounts/ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/Messages.json \
  --data-urlencode 'To=+15558675310' \
  --data-urlencode 'From=+15557122661' \
  --data-urlencode 'Body=It works.'

Returns the full Twilio message resource (sid, status: "queued", num_segments, ...), with matching GET list and fetch endpoints served from the same store — an SDK that creates and then lists a message sees its own write.

Pointing an official SDK at tommy is its own topic: see clienthelp/ and docs/clients.md for the per-SDK story, including Twilio's, whose client libraries need a custom *http.Client rather than a base-URL override.

trap — a real SNMP trap receiver on :1162
snmptrap -v 2c -c public 127.0.0.1:1162 '' 1.3.6.1.6.3.1.1.5.3 \
  1.3.6.1.2.1.1.5.0 s "host01"

Accepts v1 traps, v2c traps and v2c informs, decoding every varbind by its real wire type (integers, OIDs, counters, gauges, timeticks, IP addresses, octet strings — hex-dumped when not printable text) rather than flattening everything to one string. An inform gets a GetResponse back, echoing its request id and varbinds; a trap, v1 or v2c, gets none — SNMP defines it as unconfirmed. Any community string is accepted and recorded, never checked. There is no bespoke tab: the generic event view's JSON payload panel already shows every varbind, deliberately — see plugins/snmp/README.md.

http (as2) — POST /as2, GET /as2/certificate
curl -s -o tommy.pem http://127.0.0.1:8822/as2/certificate

printf 'ISA*00*          *00*          *ZZ*PARTNER        *ZZ*TOMMY          *260903*1200*U*00401*000000001*0*P*>~SE*1*0001~IEA*1*000000001~' |
curl -s -D - --data-binary @- \
  -H 'AS2-From: PARTNER' -H 'AS2-To: TOMMY' -H 'AS2-Version: 1.1' \
  -H 'Message-ID: <1@partner.example>' \
  -H 'Content-Type: application/edi-x12' \
  -H 'Disposition-Notification-To: as2@partner.example' \
  http://127.0.0.1:8822/as2

Signed, encrypted and compressed messages are unwrapped layer by layer and answered synchronously with a real MDN; anything that cannot be opened is still captured and reported honestly in the MDN's disposition rather than refused. See plugins/as2/README.md for a full sign-and-encrypt walkthrough with OpenSSL.

Configuration: CLI flags or TOML, never two code paths

tommy serve runs every plugin and provider compiled into the binary, filtered by config:

tommy serve --config tommy.toml
tommy serve --ui-port 8811 --api-port 8811 --ingress-port 8822 --bind 127.0.0.1 --host localhost
tommy serve --h2c=false   # the ingress serves cleartext HTTP/2 alongside HTTP/1.1 by default

The repo root ships tommy.toml, a complete example with every section commented and every value equal to the built-in default — copy it and change the two lines you care about. TOML and CLI flags build the exact same config.Config struct and hand it to the exact same bootstrap (core/server); nothing about the runtime behaves differently depending on which one you used.

When you only care about one content type, skip the config file entirely:

tommy mail  --ui-port 8811 --in-port 8822 --enabled-providers mailjet,sendgrid
tommy sms   --ui-port 8811 --in-port 8822 --enabled-providers twilio
tommy files --ui-port 8811 --in-port 8822 --ftp-port 2121 --sftp-port 2222
tommy chat  --ui-port 8811 --in-port 8822 --enabled-providers slack
tommy hl7   --ui-port 8811 --in-port 8822 --mllp-port 2575
tommy push  --ui-port 8811 --in-port 8822 --enabled-providers fcm
tommy snmp  --ui-port 8811 --in-port 8822 --trap-port 1162
tommy as2   --ui-port 8811 --in-port 8822

tommy mail, tommy sms, tommy files, tommy chat, tommy hl7, tommy snmp and tommy as2 are shortcuts that build a Config with every other plugin switched off in memory, then run through that identical bootstrap — there is no second, lighter-weight server. --enabled-providers narrows which of that plugin's providers run; leave it off and every provider the plugin ships is enabled. An unknown provider name is rejected up front, naming the valid ones:

$ tommy mail --enabled-providers bogus
Error: unknown mail provider "bogus": valid providers are mailjet, resend, sendgrid, smtp

Every subcommand mirrors serve's flags where they apply: --ui-port, --api-port, --in-port (the shared ingress port), --bind, --host and --log-level.

Every provider also gets its own flags for whatever credentials it takes, named --<provider>-<option> so two providers of one plugin never collide. Pinning a vendor credential — Mailjet's api_key, Twilio's auth_token, SMTP's AUTH password — is the same error-path test either way: unset it and anything is accepted, set it and a mismatch gets that vendor's real error response:

Provider Flags
mailjet (tommy mail) --mailjet-api-key, --mailjet-secret-key
sendgrid (tommy mail) --sendgrid-api-key
smtp (tommy mail) --smtp-port, --smtp-username, --smtp-password
twilio (tommy sms) --twilio-account-sid, --twilio-auth-token
tftp (tommy files) --tftp-port
nfs (tommy files) --nfs-port
mllp (tommy hl7) --mllp-port
fcm (tommy push) --fcm-bearer-token
apns (tommy push) --apns-topic, --apns-key-id
trap (tommy snmp) --trap-port
ftp (tommy files) --ftp-port, --ftp-passive-host, --ftp-passive-ports, --ftp-username, --ftp-password
sftp (tommy files) --sftp-port, --sftp-host-key, --sftp-authorized-keys, --sftp-username, --sftp-password
http (tommy as2) --as2-cert-file, --as2-key-file, --as2-partner-cert-file, --as2-cert-dir, --as2-common-name, --as2-in-memory, --as2-to, --as2-max-body

slack and msteams take no provider-specific flags at all: neither reads any option beyond enabled.

Only the real protocol servers get a --<provider>-port, because only they have a listener of their own: smtp, ftp, sftp, tftp, nfs, mllp and trap. Every HTTP provider — mailjet, sendgrid, twilio, slack, msteams, fcm, apns and as2's http — shares the one --in-port / [ingress] listener and is told apart by path. There is no per-provider listener for an HTTP provider (that would be real core work, not this shortcut), so none of them gets a --<provider>-port flag.

An unset flag never overrides a provider's own default, and setting one for a provider --enabled-providers excludes is a clear error rather than a flag that silently does nothing:

$ tommy files --enabled-providers ftp --sftp-port 2200
Error: files: flags were given for provider "sftp", but --enabled-providers only enables ftp

Everything else settable in a provider's tommy.toml section — smtp's, ftp's and sftp's own bind, and tuning knobs like timeouts, message/recipient limits and connection caps — is deliberately config-file-only; see the comments next to each key in tommy.toml for why.

Every subcommand rejects a stray positional argument rather than silently starting a server with it ignored — tommy mail serve and tommy files oops are both errors, not a running server you have to notice and kill by hand.

API surface

Everything lives under /api/v1, shared by every plugin:

Route Notes
GET /health status, uptime, enabled plugins, event count, version
GET /plugins descriptions, endpoints and snippets, rendered against the live ports
GET /events ?plugin=&provider=&type=&search=&since=&limit=&offset=
GET /events/{id} the full event, including the raw request
GET /events/stream Server-Sent Events, same filters — what the UI itself consumes
DELETE /events ?plugin= to scope the clear, otherwise clears everything
DELETE /events/{id} remove one event
GET /blobs/{id} stream an attachment or uploaded file, with range support
GET /openapi.json the OpenAPI 3.1 description of the events API, generated from its routes
GET /<plugin>/openapi.json that plugin's own read-back API, described the same way
GET /mail/messages, /mail/messages/{id}, .../html, .../text, .../raw, .../attachments/{idx} mail read-back
GET /sms/messages, /sms/messages/{id}, .../media/{idx} sms read-back

Every event in those responses carries a url naming its own page, GET /ui/events/{id} — one event, rendered by the plugin that captured it.

The events API — the five routes above that list, fetch, stream and delete events, plus the blob download — has an OpenAPI 3.1 description, generated from the server's own route table rather than written by hand: docs/openapi.json, or GET /api/v1/openapi.json from a running tommy. Generate a client from it and a test can assert on what your code sent without knowing anything about the vendor it thought it was talking to. tommy openapi prints it, make openapi regenerates the checked-in copy, and a test fails if the two ever disagree.

Each plugin's read-back API — /api/v1/mail/messages and its kin, which filter by the things that only make sense for that content type — has a description of its own: docs/openapi-mail.json, GET /api/v1/mail/openapi.json, or tommy openapi mail. One document per surface, so the events description stays the small one everybody reads.

The fake vendor endpoints are deliberately described nowhere — those are the vendors' own specifications; tommy providers prints what tommy mounts for them.

tommy providers [plugin[/provider]] [--json] prints the same information GET /api/v1/plugins returns, for scripting or a quick look before you've sent anything.

Learn more

  • docs/plan.md — the original design brief.
  • docs/implementation-plan.md — what is planned next, wave by wave. Forward-looking only; finished waves move to the history.
  • docs/contracts.md — the contracts as actually implemented, including the small deviations from the plan.
  • Every plugin and provider directory carries its own README.md with the same description and snippets tommy providers prints.

Installation

Three routes, and they all give you the same binary. The Docker image is the only one that needs nothing installed first.

Docker
docker run --rm -p 8811:8811 -p 8822:8822 can3p/tommy

Published on Docker Hub as can3p/tommy and on GHCR as ghcr.io/can3p/tommy, multi-architecture, one static binary on a distroless base. docs/docker.md covers publishing the protocol listeners as well, the /data volume, and narrowing tommy to one plugin with a mounted configuration.

go install
go install github.com/can3p/tommy@latest
Install Script

Download tommy and install into a local bin directory.

MacOS, Linux, WSL

Latest version:

curl -L https://raw.githubusercontent.com/can3p/tommy/main/generated/install.sh | sh

Specific version:

curl -L https://raw.githubusercontent.com/can3p/tommy/main/generated/install.sh | sh -s 0.0.4

The script will install the binary into $HOME/bin folder by default, you can override this by setting $CUSTOM_INSTALL environment variable

Manual download

Get the archive that fits your system from the Releases page and extract the binary into a folder that is mentioned in your $PATH variable.

Notes

The project has been scaffolded with the help of kleiner

License

tommy is released under the MIT license; see LICENSE for the full text.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
Package clienthelp gives official vendor SDKs a way to talk to tommy even when the SDK itself refuses to.
Package clienthelp gives official vendor SDKs a way to talk to tommy even when the SDK itself refuses to.
cmd/as2.go is the as2 half of the single-plugin shortcuts described in cmd/mail.go's package comment.
cmd/as2.go is the as2 half of the single-plugin shortcuts described in cmd/mail.go's package comment.
core
blob
Package blob stores the bytes that must never live inside an Event.
Package blob stores the bytes that must never live inside an Event.
blob/memory
Package memory implements a size-capped in-memory blob.BlobStore.
Package memory implements a size-capped in-memory blob.BlobStore.
config
Package config holds tommy's configuration.
Package config holds tommy's configuration.
event
Package event defines the transport-agnostic envelope every tommy plugin produces.
Package event defines the transport-agnostic envelope every tommy plugin produces.
plugin
Package plugin defines what a tommy plugin and provider are.
Package plugin defines what a tommy plugin and provider are.
plugin/plugintest
Package plugintest holds the conformance checks every plugin and provider must pass.
Package plugintest holds the conformance checks every plugin and provider must pass.
server
Package server boots tommy: it wires the store, the registry, the ingress mux and the HTTP listeners together, starts every listener provider, and shuts the lot down gracefully.
Package server boots tommy: it wires the store, the registry, the ingress mux and the HTTP listeners together, starts every listener provider, and shuts the lot down gracefully.
server/api
Package api serves the generic /api/v1 surface: health, discovery, events and the event stream.
Package api serves the generic /api/v1 surface: health, discovery, events and the event stream.
server/ingress
Package ingress is the shared, path-routed HTTP surface the fake vendor APIs are mounted on.
Package ingress is the shared, path-routed HTTP surface the fake vendor APIs are mounted on.
server/sse
Package sse writes the server-sent-events stream shared by the API and the UI.
Package sse writes the server-sent-events stream shared by the API and the UI.
server/ui
Package ui serves tommy's web shell: the tab bar built from the plugin registry, one SSE connection per page, the "How to test" panel, and the generic event view any plugin gets for free.
Package ui serves tommy's web shell: the tab bar built from the plugin registry, one SSE connection per page, the "How to test" panel, and the generic event view any plugin gets for free.
server/ui/components
Package components is the shared template library every plugin tab composes from: page chrome, master-detail and stream layouts, a JSON inspector, a hex viewer for binary bodies, tables, badges, copy buttons - and the generic event view any plugin gets for free.
Package components is the shared template library every plugin tab composes from: page chrome, master-detail and stream layouts, a JSON inspector, a hex viewer for binary bodies, tables, badges, copy buttons - and the generic event view any plugin gets for free.
store
Package store defines the event log every plugin writes to and every read surface (API, UI, SSE) reads from.
Package store defines the event log every plugin writes to and every read surface (API, UI, SSE) reads from.
store/memory
Package memory implements store.Store as a per-plugin ring buffer with pub/sub fan-out.
Package memory implements store.Store as a per-plugin ring buffer with pub/sub fan-out.
testutil
Package testutil boots a whole tommy in-process on ephemeral ports, so tests exercise the real bootstrap instead of a hand-assembled subset.
Package testutil boots a whole tommy in-process on ephemeral ports, so tests exercise the real bootstrap instead of a hand-assembled subset.
testutil/fakeplugin
Package fakeplugin is a complete, self-contained plugin used to exercise the core: registry validation, ingress routing, listener supervision, the generic event view, SSE delivery and plugintest.Conformance.
Package fakeplugin is a complete, self-contained plugin used to exercise the core: registry validation, ingress routing, listener supervision, the generic event view, SSE delivery and plugintest.Conformance.
generated
plugins
all
Package all is the single shared wiring point: it names every plugin this binary ships, and every provider inside it.
Package all is the single shared wiring point: it names every plugin this binary ships, and every provider inside it.
as2
Package as2 is tommy's AS2 content type: the canonical Message every AS2 provider converts into, the S/MIME and MIME processing that produces it, the MDN receipt that goes back, the read-back API under /api/v1/as2/ and the tab under /ui/as2/.
Package as2 is tommy's AS2 content type: the canonical Message every AS2 provider converts into, the S/MIME and MIME processing that produces it, the MDN receipt that goes back, the read-back API under /api/v1/as2/ and the tab under /ui/as2/.
as2/providers/http
Package http is the AS2-over-HTTP binding of RFC 4130: the route a trading partner POSTs an EDIINT message to, and the certificate endpoint that lets it find out what to encrypt to.
Package http is the AS2-over-HTTP binding of RFC 4130: the route a trading partner POSTs an EDIINT message to, and the certificate endpoint that lets it find out what to encrypt to.
chat
Package chat is tommy's chat content type: the canonical Message every chat provider converts into, the read-back API under /api/v1/chat/ and the channel-and-stream tab under /ui/chat/.
Package chat is tommy's chat content type: the canonical Message every chat provider converts into, the read-back API under /api/v1/chat/ and the channel-and-stream tab under /ui/chat/.
chat/providers/msteams
Package msteams imitates the two generations of Microsoft Teams incoming webhook that are actually in use: the (retired but still widely deployed) Office 365 / Microsoft 365 connector webhook, whose payload is a MessageCard, and the current Power-Automate-backed "Post to a channel when a webhook request is received" workflow trigger, whose payload is an Adaptive Card wrapped in a Bot-Framework-shaped envelope.
Package msteams imitates the two generations of Microsoft Teams incoming webhook that are actually in use: the (retired but still widely deployed) Office 365 / Microsoft 365 connector webhook, whose payload is a MessageCard, and the current Power-Automate-backed "Post to a channel when a webhook request is received" workflow trigger, whose payload is an Adaptive Card wrapped in a Bot-Framework-shaped envelope.
chat/providers/slack
Package slack imitates two Slack posting surfaces well enough that a real Slack SDK, or any HTTP client pointed at tommy's ingress, can post a message and have it show up in the chat tab exactly the way it would land in Slack:
Package slack imitates two Slack posting surfaces well enough that a real Slack SDK, or any HTTP client pointed at tommy's ingress, can post a message and have it show up in the chat tab exactly the way it would land in Slack:
chat/ui/blocks
Package blocks is the card-rendering seam for the chat plugin: it turns a Slack Block Kit array, a Slack legacy attachments array, a Teams MessageCard or a Teams Adaptive Card into HTML that looks like the real thing, so a card does not fall back to only its plain-text preview plus a raw JSON inspector.
Package blocks is the card-rendering seam for the chat plugin: it turns a Slack Block Kit array, a Slack legacy attachments array, a Teams MessageCard or a Teams Adaptive Card into HTML that looks like the real thing, so a card does not fall back to only its plain-text preview plus a raw JSON inspector.
files
Package files is tommy's file-transfer content type: one in-memory virtual filesystem every provider shares, a read-back API, and a file-browser tab.
Package files is tommy's file-transfer content type: one in-memory virtual filesystem every provider shares, a read-back API, and a file-browser tab.
files/providers/ftp
Package ftp is tommy's FTP listener: a files provider that owns a real FTP port and reads and writes the plugin's shared virtual filesystem over the wire protocol every FTP client and library already speaks.
Package ftp is tommy's FTP listener: a files provider that owns a real FTP port and reads and writes the plugin's shared virtual filesystem over the wire protocol every FTP client and library already speaks.
files/providers/nfs
Package nfs is tommy's NFSv3 listener: a files provider that owns a real TCP port and serves the plugin's shared virtual filesystem over the protocol every operating system can mount natively, so a file written by `cp` into a mounted directory lands in the same tree - and the same event log - that ftp, sftp and tftp write into.
Package nfs is tommy's NFSv3 listener: a files provider that owns a real TCP port and serves the plugin's shared virtual filesystem over the protocol every operating system can mount natively, so a file written by `cp` into a mounted directory lands in the same tree - and the same event log - that ftp, sftp and tftp write into.
files/providers/sftp
Package sftp is tommy's SFTP listener: a files provider that owns a real SSH port and writes everything uploaded to it into the plugin's shared virtual filesystem.
Package sftp is tommy's SFTP listener: a files provider that owns a real SSH port and writes everything uploaded to it into the plugin's shared virtual filesystem.
files/providers/tftp
Package tftp is tommy's TFTP listener: a files provider that owns a real UDP port and reads and writes the plugin's shared virtual filesystem for every RRQ (download) and WRQ (upload) it receives.
Package tftp is tommy's TFTP listener: a files provider that owns a real UDP port and reads and writes the plugin's shared virtual filesystem for every RRQ (download) and WRQ (upload) it receives.
hl7
Package hl7 is tommy's HL7 v2 content type: the canonical Message every HL7 provider converts into, the read-back API under /api/v1/hl7/ and the segment tree tab under /ui/hl7/.
Package hl7 is tommy's HL7 v2 content type: the canonical Message every HL7 provider converts into, the read-back API under /api/v1/hl7/ and the segment tree tab under /ui/hl7/.
hl7/providers/mllp
Package mllp is tommy's HL7 listener: a real TCP server speaking MLLP (Minimal Lower Layer Protocol), the framing almost every HL7 v2 integration engine uses on the wire.
Package mllp is tommy's HL7 listener: a real TCP server speaking MLLP (Minimal Lower Layer Protocol), the framing almost every HL7 v2 integration engine uses on the wire.
mail
Package mail is tommy's mail content type: one canonical Message every provider converts into, a read-back API, and an inbox tab.
Package mail is tommy's mail content type: one canonical Message every provider converts into, a read-back API, and an inbox tab.
mail/mailtest
Package mailtest is a test-only mail provider.
Package mailtest is a test-only mail provider.
mail/providers/mailjet
Package mailjet imitates Mailjet's transactional Send API v3.1.
Package mailjet imitates Mailjet's transactional Send API v3.1.
mail/providers/resend
Package resend imitates the Resend Email API (https://api.resend.com), the three endpoints an application actually sends mail through:
Package resend imitates the Resend Email API (https://api.resend.com), the three endpoints an application actually sends mail through:
mail/providers/sendgrid
Package sendgrid imitates the Twilio SendGrid v3 Mail Send API (https://www.twilio.com/docs/sendgrid/api-reference/mail-send/mail-send).
Package sendgrid imitates the Twilio SendGrid v3 Mail Send API (https://www.twilio.com/docs/sendgrid/api-reference/mail-send/mail-send).
mail/providers/smtp
Package smtp is tommy's SMTP listener: a mail provider that owns a real SMTP port and turns everything delivered to it into canonical mail messages.
Package smtp is tommy's SMTP listener: a mail provider that owns a real SMTP port and turns everything delivered to it into canonical mail messages.
push
Package push is tommy's push-notification content type: the canonical Message every push provider converts into, the read-back API under /api/v1/push/ and the lock-screen tab under /ui/push/.
Package push is tommy's push-notification content type: the canonical Message every push provider converts into, the read-back API under /api/v1/push/ and the lock-screen tab under /ui/push/.
push/providers/apns
Package apns imitates the Apple Push Notification service provider API - POST /3/device/{deviceToken} - well enough that sideshow/apns2, or any HTTP/2 client pointed at tommy's ingress, sends a push and gets back the response it expects.
Package apns imitates the Apple Push Notification service provider API - POST /3/device/{deviceToken} - well enough that sideshow/apns2, or any HTTP/2 client pointed at tommy's ingress, sends a push and gets back the response it expects.
push/providers/fcm
Package fcm imitates Firebase Cloud Messaging's HTTP v1 send API well enough that the Firebase Admin SDKs, or any HTTP client pointed at tommy's ingress, can send a push and get back the response shape they expect.
Package fcm imitates Firebase Cloud Messaging's HTTP v1 send API well enough that the Firebase Admin SDKs, or any HTTP client pointed at tommy's ingress, can send a push and get back the response shape they expect.
sms
Package sms is tommy's SMS/MMS content type.
Package sms is tommy's SMS/MMS content type.
sms/providers/twilio
Package twilio imitates Twilio's Programmable Messaging REST API well enough that the twilio-go SDK, or any HTTP client pointed at tommy's ingress, can send a message and read it back exactly the way it would against the real api.twilio.com.
Package twilio imitates Twilio's Programmable Messaging REST API well enough that the twilio-go SDK, or any HTTP client pointed at tommy's ingress, can send a message and read it back exactly the way it would against the real api.twilio.com.
snmp
Package snmp is tommy's SNMP trap content type: the canonical Trap every provider converts into, and the plugin wiring around it.
Package snmp is tommy's SNMP trap content type: the canonical Trap every provider converts into, and the plugin wiring around it.
snmp/providers/trap
Package trap is tommy's SNMP trap receiver: a real UDP listener that accepts v1 traps, v2c traps and v2c informs, decodes every varbind and records it as an snmp.Trap.
Package trap is tommy's SNMP trap receiver: a real UDP listener that accepts v1 traps, v2c traps and v2c informs, decodes every varbind and records it as an snmp.Trap.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL