A CLI tool that reads JSON from stdin, transforms it using expressions, and sends HTTP requests.
go install github.com/octoberswimmer/pub@latestOr build from source:
go build -o pubpub [flags] <URL expression>--transform <expression>- Transform the input JSON before sending--header <expression>- Add HTTP headers (can be used multiple times)--request <method>- HTTP method (default: POST)--dry-run- Print requests without sending them
All expressions have access to:
input- The current JSON line being processedenv- Environment variables (including those from.envfile)
Send JSON as-is to an endpoint:
echo '{"message": "hello"}' | pub "http://localhost:8080/webhook"Wrap input in a data field:
echo '{"id": 123}' | pub --transform '{data: input}' "http://localhost:8080/api"Use input fields in the URL:
echo '{"queue": "urgent", "id": 123}' | pub '"http://localhost:8080/publish?queue=" + input.queue'Add authorization header from environment:
echo '{"data": "test"}' | pub \
--header '"Authorization: Bearer " + env.API_TOKEN' \
"http://api.example.com/endpoint"echo '{"data": "test"}' | pub \
--header '"Authorization: Bearer " + env.TOKEN' \
--header '"X-Request-ID: " + input.id' \
--request PUT \
"http://api.example.com/resource"See what would be sent without making requests:
echo '{"test": "data"}' | pub --dry-run \
--transform '{wrapped: input}' \
--header '"Content-Type: application/json"' \
"http://localhost:8080/test"Process Salesforce platform events:
force pubsub subscribe /event/My_Event__e | pub \
--transform '{data: input}' \
--header '"Authorization: Bearer " + env.EVENTS_PUBLISH_TOKEN' \
--request POST \
'"http://localhost:8080/publish?queue=" + input.Queue_Name__c'Create a .env file in your working directory:
API_TOKEN=your-secret-token
API_ENDPOINT=https://api.example.comThese will be automatically loaded and available as env.API_TOKEN and env.API_ENDPOINT in expressions.
The tool processes JSON line by line, making a separate HTTP request for each valid JSON line:
# Process multiple events
cat events.jsonl | pub --transform '{event: input}' "http://localhost:8080/ingest"Empty lines are skipped. Invalid JSON lines will log an error and continue processing.
- HTTP errors (status >= 400) are logged but processing continues
- JSON parsing errors are logged per line
- Expression evaluation errors are logged with details
- The tool exits with status 1 if stdin reading fails