Michael Freno 3e9edc2ae1
Some checks are pending
CI / build (1.23.x) (push) Waiting to run
CI / security-scan (push) Waiting to run
Fix Go version matrix and coverage calculation portability
P0: Update Go version matrix from [1.21.x, 1.22.x] to [1.23.x] to match go.mod (go 1.23.0)
P0: Update security-scan Go version from 1.21.x to 1.23.x
P1: Replace grep -oP with portable awk for coverage threshold calculation

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-14 00:40:43 -04:00
2026-04-29 16:30:29 -04:00
2026-04-27 19:13:03 -04:00
2026-04-27 19:13:03 -04:00

pop

A ProtonMail CLI tool written in Go, similar to gog.

Features

  • Authentication: Interactive login/logout with 2FA support and masked password prompts
  • Session Management: Secure token storage in ~/.config/pop/
  • ProtonMail API Client: REST client with rate limiting and error handling
  • PGP Encryption: Full support for ProtonMail's PGP encryption via gopenpgp v2
  • Multi-Account Support: Named account profiles for managing multiple ProtonMail accounts
  • Webhook Management: Real-time notifications via webhook subscriptions
  • External PGP Key Management: Import, export, encrypt, decrypt, sign, and verify with external PGP keys
  • CLI Plugin System: Extend Pop functionality with external plugins
  • Email Threading: View and reply to conversation threads
  • Bulk Operations: Delete, trash, star, and mark read/unread multiple messages at once
  • Export/Import: Export messages to JSON, MBOX, or EML format; import from JSON
  • Draft Auto-Save: Automatic draft saving with configurable interval and email templates

Installation

# Build from source
git clone https://github.com/frenocorp/pop.git
cd pop
make build

# Install
make install

Usage

Authentication

# Initialize login (interactive mode with masked password prompt)
pop login

# Check current session
pop session

# Logout
pop logout

Multi-Account Support

# List all accounts
pop accounts list

# Add a new account
pop accounts add work --email work@example.com --default

# Add with custom API URL
pop accounts add personal --email personal@protonmail.ch --api-url https://api.protonmail.ch

# Switch default account
pop accounts default work

# View account details
pop accounts show work

# Remove an account
pop accounts remove old-account

Webhook Management

# List all webhooks
pop webhook list

# Add a webhook
pop webhook add notifications --url https://example.com/webhook --events mail.received,mail.sent

# Verify webhook signatures
pop webhook verify

# Remove a webhook
pop webhook remove wh_1234567890

PGP Key Management

# List all imported keys
pop pgp list

# Import a key from file
pop pgp import key.asc --trust full

# Export a key
pop pgp export ABCD1234 --output mykey.asc

# Encrypt data
pop pgp encrypt ABCD1234 --plaintext "Secret message"

# Decrypt data
pop pgp decrypt ABCD1234 --encrypted "-----BEGIN PGP MESSAGE-----..."

# Sign data
pop pgp sign ABCD1234 --plaintext "Message to sign" --passphrase "my passphrase"

# Verify a signature
pop pgp verify ABCD1234 --message "Original message" --signature "-----BEGIN PGP SIGNATURE-----..."

# Remove a key
pop pgp remove ABCD1234

Plugin Management

# List all plugins
pop plugin list

# Enable a plugin
pop plugin enable myplugin

# Disable a plugin
pop plugin disable myplugin

Email Threading

# List conversation threads
pop thread list

# View a full conversation thread
pop thread show <conversation-id>

# Reply to a conversation
pop thread reply <conversation-id> --body "Your reply here"
pop thread reply <conversation-id> --body-file reply.txt

Bulk Operations

# Delete multiple messages
pop bulk delete --ids "id1,id2,id3"
pop bulk delete --ids-file ids.txt

# Move multiple messages to trash
pop bulk trash --ids "id1,id2,id3"

# Star multiple messages
pop bulk star --ids "id1,id2,id3"
pop bulk unstar --ids "id1,id2,id3"

# Mark messages as read/unread
pop bulk mark-read --ids "id1,id2,id3"
pop bulk mark-unread --ids "id1,id2,id3"

Export and Import

# Export specific messages
pop export messages --ids "id1,id2,id3" --output messages.json
pop export messages --ids-file ids.txt --output messages.json

# Export messages by search
pop export messages --search "important" --output search-results.json

# Export all messages from a folder
pop export folder --folder inbox --output inbox-backup.json
pop export folder --folder sent --format mbox --output sent.mbox

# Export a conversation
pop export conversation <conversation-id> --output conversation.json

# Import messages from JSON
pop import --file messages.json

Draft Auto-Save

# Enable auto-save with default 30-second interval
pop draft autosave enable

# Enable with custom interval
pop draft autosave enable --interval 60

# Disable auto-save
pop draft autosave disable

# Check auto-save status
pop draft autosave status

# Manually trigger auto-save
pop draft autosave run

# Manage email templates
pop draft template save newsletter --subject "Monthly Update" --body "Hello..."
pop draft template list
pop draft template use newsletter --to recipient@example.com
pop draft template delete newsletter

Project Structure

pop/
├── cmd/
│   ├── root.go       # CLI root command
│   ├── auth.go       # Authentication commands
│   ├── mail.go       # Email management
│   ├── draft.go      # Draft management
│   ├── contact.go    # Contact management
│   ├── attachment.go # Attachment handling
│   ├── folder.go     # Folder management
│   ├── label.go      # Label management
│   ├── accounts.go   # Multi-account support
│   ├── webhook.go    # Webhook management
│   ├── pgp.go        # PGP key management
│   ├── plugin.go       # Plugin management
│   ├── thread.go       # Conversation threading
│   ├── bulk.go         # Bulk operations
│   ├── export.go       # Export/import functionality
│   └── draft_autosave.go # Draft auto-save and templates
├── internal/
│   ├── auth/         # Session management
│   │   └── session.go
│   ├── config/       # Configuration handling
│   │   └── config.go
│   ├── api/          # ProtonMail API client
│   │   └── client.go
│   ├── mail/         # Mail-related functionality
│   │   └── mail.go
│   ├── contact/      # Contact management
│   │   └── contact.go
│   ├── attachment/   # Attachment handling
│   │   └── attachment.go
│   ├── labels/       # Label management
│   │   └── labels.go
│   ├── accounts/     # Multi-account support
│   │   └── accounts.go
│   ├── webhook/      # Webhook management
│   │   └── webhook.go
│   ├── pgp/          # PGP key management
│   │   └── pgp.go
│   └── plugin/       # Plugin system
│       └── plugin.go
├── .github/
│   └── workflows/
│       └── ci.yml    # CI/CD pipeline
├── go.mod
├── go.sum
├── main.go
├── Makefile
└── README.md

Configuration

Configuration is stored in ~/.config/pop/config.json:

{
  "api_base_url": "https://api.protonmail.ch",
  "timeout_sec": 30,
  "rate_limit_requests": 100,
  "rate_limit_window_sec": 60
}

Session data is stored in ~/.config/pop/session.json:

{
  "uid": "user-uid",
  "access_token": "token",
  "refresh_token": "refresh",
  "expires_at": 0,
  "two_factor_enabled": false
}

Multi-Account Configuration

Accounts are stored in ~/.config/pop/accounts.json:

[
  {
    "name": "work",
    "email": "work@example.com",
    "api_base_url": "https://api.protonmail.ch",
    "default": true,
    "created_at": "2024-01-01T00:00:00Z"
  }
]

Webhook Configuration

Webhooks are stored in ~/.config/pop/webhooks.json:

[
  {
    "id": "wh_1234567890",
    "name": "notifications",
    "url": "https://example.com/webhook",
    "events": ["mail.received", "mail.sent"],
    "secret": "abc123...",
    "active": true,
    "created_at": "2024-01-01T00:00:00Z"
  }
]

PGP Key Configuration

PGP keys are stored in ~/.config/pop/pgp_keys.json with key files in ~/.config/pop/pgp_keys/:

[
  {
    "key_id": "ABCD1234",
    "fingerprint": "ABCD1234567890ABCD1234567890ABCD1234",
    "emails": ["user@example.com"],
    "trust_level": "full",
    "can_encrypt": true,
    "can_sign": true,
    "armor_file": "/home/user/.config/pop/pgp_keys/ABCD1234.asc"
  }
]

Plugin Configuration

Plugins are stored in ~/.config/pop/plugins.json with binaries in ~/.config/pop/plugins/:

[
  {
    "name": "myplugin",
    "version": "1.0.0",
    "description": "My custom plugin",
    "binary": "/home/user/.config/pop/plugins/pop-myplugin",
    "enabled": true,
    "commands": [
      {
        "name": "mycommand",
        "description": "My custom command"
      }
    ]
  }
]

Development

# Build
make build

# Run tests
make test

# Format code
make fmt

# Lint
make lint

# Clean build artifacts
make clean

Dependencies

License

MIT

Description
No description provided
Readme 245 KiB
Languages
Go 99.9%
Makefile 0.1%