Skip to main content

Hermes Agent platform plugin: chat with your agent over Pingram SMS and Email.

Project description

Pingram Gateway for Hermes

Chat with your Hermes agent over SMS and Email, routed through Pingram. Text or email your Pingram number/address and the agent replies on the same channel — including inbound MMS images.

This is a self-contained Hermes platform plugin: one plugin.yaml + one adapter.py. It registers a single pingram platform that serves both channels (Pingram uses one API key for both). Inbound messages are received by polling Pingram's logs API on a timer — there's no public endpoint or webhook to set up. It requires zero changes to Hermes core.

flowchart LR
  human["Human"] -->|"SMS / Email"| pingram["Pingram"]
  pingram -->|"logs.getLogs (polled every N seconds)"| adapter["PingramAdapter"]
  adapter -->|"MessageEvent"| agent["Hermes agent session"]
  agent -->|"reply"| send["PingramAdapter.send()"]
  send -->|"Pingram Python SDK"| pingram
  pingram -->|"SMS / Email"| human

The channel is encoded in the Hermes chat_id prefix: sms:{phone} and email:{thread}.

Requirements

  • A running Hermes agent (hermes gateway).
  • A Pingram account with an API key (pingram_sk_...). Sender identity is optional — Pingram provides a default SMS number and email sender, so you can start without provisioning your own.
  • Python packages pingram-python (the Pingram SDK) and aiohttp available to the gateway — installed automatically with the pip install method below.
  • No public host, tunnel, or webhook registration is required — the adapter polls Pingram for new messages.

Install

Option 1: pip (recommended)

Install from PyPI into the same environment as your Hermes agent. This pulls in the Pingram SDK and aiohttp for you, and registers the plugin via its hermes_agent.plugins entry point — the gateway discovers it automatically.

pip install hermes-pingram-gateway

hermes-pingram-gateway is the plugin. It depends on pingram-python, the Pingram SDK (imported as pingram); the two are separate packages.

Option 2: hermes plugins install (from source)

hermes plugins install pingram-io/hermes-gateway
pip install pingram-python aiohttp

hermes plugins install git-clones this repo into ~/.hermes/plugins/pingram/ and the gateway auto-discovers it on next start. Because it doesn't install Python dependencies, you install the SDK and aiohttp yourself.

Configure

You can configure Pingram two ways — a guided wizard (recommended) or by editing env vars directly.

Option A: Guided setup (recommended)

First enable the plugin so it shows up in the gateway setup menu, then run the wizard:

hermes plugins enable pingram
hermes setup gateway

Select Pingram from the messaging-platforms list and answer the prompts. The wizard asks for your region and API key, then which channel(s) to enable (SMS, Email, or both). Sender details are optional — for SMS you can use your Pingram account's default number or pin a specific one; for Email you can set a display name and address or leave them blank for Pingram's defaults. It also asks how often to poll for new messages (default every 15s). It writes everything to ~/.hermes/.env for you — then just start the gateway.

Option B: Manual env vars

Set these in your Hermes env (~/.hermes/.env) — see .env.example for the full list. At minimum you need the API key, region, and channel(s).

# Required:
PINGRAM_API_KEY=pingram_sk_...
PINGRAM_REGION=us                        # us | eu | ca — must match your Pingram account's region
PINGRAM_CHANNELS=sms,email               # which channels to enable: sms, email, or both

# Senders are OPTIONAL — leave them unset to use Pingram's account defaults.
#PINGRAM_FROM_SMS=+15551234567           # pin a specific verified Pingram number
#PINGRAM_FROM_EMAIL=agent@yourdomain.com # sender address on a verified domain
#PINGRAM_FROM_NAME=My Bot                # email sender display name

# Inbound polling cadence (optional):
#PINGRAM_POLL_INTERVAL=15                # seconds between polls (default 15)
#PINGRAM_POLL_LIMIT=50                   # max messages fetched per poll page

# Everything below is optional (defaults shown / commented out):
#PINGRAM_ALLOWED_USERS=+15559876543,you@yourdomain.com
#PINGRAM_ALLOW_ALL_USERS=false           # dev only

Set PINGRAM_REGION to the region your Pingram account lives in (us, eu, or ca). It selects the API endpoint — the wrong value will fail to send.

Enable the platform in your gateway config (~/.hermes/config.yaml):

plugins:
  enabled: true
gateway:
  platforms:
    pingram:
      enabled: true

Start (or restart) the gateway:

hermes gateway restart

How inbound messages are received

The adapter polls Pingram's logs API (logs.getLogs) every PINGRAM_POLL_INTERVAL seconds (default 15). Each cycle it fetches the newest messages, keeps the ones that arrived since the last poll, and dispatches the inbound SMS/Email to your agent. A startup watermark means only messages that arrive after the gateway starts are delivered (history isn't replayed), and per-message tracking-id deduplication guards against reprocessing.

This means there's nothing to expose to the internet — no public host, tunnel, or webhook registration. Just start the gateway and text/email your Pingram number/address.

Trade-offs versus a push webhook:

  • Latency: delivery is delayed by up to one poll interval (lower the interval for snappier replies, at the cost of more API calls).
  • Email attachments: inbound email attachments are not downloaded — Pingram's logs API returns attachment metadata only, not content. Inbound SMS/MMS images are fetched and passed to the agent for vision. Outbound file replies (the agent attaching files to an email) still work.

SMS quickstart

  1. Set PINGRAM_API_KEY, PINGRAM_REGION, and PINGRAM_CHANNELS=sms. Optionally pin PINGRAM_FROM_SMS; otherwise Pingram uses your default number.
  2. Add your phone to PINGRAM_ALLOWED_USERS.
  3. Start the gateway.
  4. Text your Pingram number — the agent replies by SMS within a poll interval. Inbound MMS images are passed to the agent for vision.

Email quickstart

  1. Set PINGRAM_API_KEY, PINGRAM_REGION, and PINGRAM_CHANNELS=email. Optionally set PINGRAM_FROM_EMAIL / PINGRAM_FROM_NAME; otherwise Pingram uses its default sender.
  2. Add your email to PINGRAM_ALLOWED_USERS.
  3. Start the gateway.
  4. Email your Pingram address — the agent replies in-thread (Re: subject) within a poll interval. The agent's file replies are sent back as email attachments. (Inbound email attachments are not downloaded when polling.)

Security

The logs API is account-scoped and authenticated by PINGRAM_API_KEY, so there's no inbound endpoint to authenticate. Defense-in-depth still applies to who the agent will talk to:

  • User allowlist — an inbound message's from must be in PINGRAM_ALLOWED_USERS unless PINGRAM_ALLOW_ALL_USERS=true. With no allowlist and false, inbound messages are ignored.
  • Deduplication — each message is processed once (keyed on its Pingram tracking id), even if it appears across consecutive polls.
  • Message bodies and secrets are never logged; phone numbers/emails are redacted.

Configuration reference

Env var Required Default Description
PINGRAM_API_KEY yes Pingram API key (pingram_sk_...).
PINGRAM_REGION yes us us | eu | ca. Must match your account's region — selects the API endpoint.
PINGRAM_CHANNELS yes* inferred Channels to enable: sms, email, or sms,email. *Optional only if a sender is set (legacy inference).
PINGRAM_FROM_SMS no Pingram default Pin a specific verified SMS sender number (E.164). Blank → account default.
PINGRAM_FROM_EMAIL no noreply@pingram.io Email sender address (verified domain). Blank → Pingram default.
PINGRAM_FROM_NAME no Pingram default Email sender display name (e.g. My Bot).
PINGRAM_POLL_INTERVAL no 15 Seconds between polls for new inbound messages.
PINGRAM_POLL_LIMIT no 50 Max messages fetched per poll page.
PINGRAM_ALLOWED_USERS no Allowed phones/emails (CSV).
PINGRAM_ALLOW_ALL_USERS no false Allow everyone (dev only).
PINGRAM_NOTIFICATION_TYPE no hermes_agent_reply Pingram notification type.

Known limitations (V1)

  • Inbound email attachments: not downloaded. Polling Pingram's logs API returns attachment metadata only, not content. Inbound SMS/MMS images and outbound email file replies work fully.
  • Latency: inbound delivery is delayed by up to one PINGRAM_POLL_INTERVAL.
  • Outbound SMS MMS: the Pingram send API has no SMS media field, so the agent can't attach locally-generated images to an SMS. If a public image URL is available it's appended to the message text; otherwise a short note is added.

License

MIT — see LICENSE if present, otherwise this plugin is provided under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hermes_pingram_gateway-1.0.0.tar.gz (19.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hermes_pingram_gateway-1.0.0-py3-none-any.whl (17.1 kB view details)

Uploaded Python 3

File details

Details for the file hermes_pingram_gateway-1.0.0.tar.gz.

File metadata

  • Download URL: hermes_pingram_gateway-1.0.0.tar.gz
  • Upload date:
  • Size: 19.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for hermes_pingram_gateway-1.0.0.tar.gz
Algorithm Hash digest
SHA256 2536278c68cc81442bb07f4873bd94fe24ff963c10bbbf5e6fb74c7aaaa72722
MD5 c1de521c9d743917e56a06384319c5bf
BLAKE2b-256 a4e40f45c7825441a54ad17b4afce6d068aa9ec3337c55d90df84e3a665bef0f

See more details on using hashes here.

Provenance

The following attestation bundles were made for hermes_pingram_gateway-1.0.0.tar.gz:

Publisher: deploy.yml on pingram-io/hermes-gateway

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hermes_pingram_gateway-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for hermes_pingram_gateway-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bfba86f466c2f691cb01e0f8198a93810995b9b07189a87b99515586a8bd2baf
MD5 7e7cf7395d4135f29842276d043aa043
BLAKE2b-256 74285c768377d2b984eda9e063e5cc7d067a26fe4d5f6acb24f65b021593465d

See more details on using hashes here.

Provenance

The following attestation bundles were made for hermes_pingram_gateway-1.0.0-py3-none-any.whl:

Publisher: deploy.yml on pingram-io/hermes-gateway

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page