gmailctl

repository·master·Indexed 24 days ago

https://github.com/mbrt/gmailctl

A utility for managing Gmail filters declaratively using Jsonnet. It allows users to treat email filtering logic as code, providing maintainability and composability with automated updates via the Gmail API. Features include support for native and standard Gmail operators, label management, unit testing for filters, and the ability to simulate if-else logic using chainFilters.

Tokens
12.1K
Snippets
27
Records
73
Agent score
79%

What's inside gmailctl

  1. Define complex filters using Jsonnet nesting

    master

    You can create sophisticated Gmail filters by nesting logical operators like and, or, and not within your Jsonnet configuration. This allows you to combine multiple criteria (such as from, to, subject, or has) into a single rule. Note that while Jsonnet provides structure, the underlying logic ultimately maps to Gmail search expressions.

    local me = 'pippo@gmail.com';
    local spam = {
      or: [
        { from: 'foo@gmail.com' },
        { from: 'bar@hotmail.com' },
        { subject: 'buy this' },
        { subject: 'buy that' },
      ],
    };
    {
      version: 'v1alpha3',
      rules: [
        {
          filter: {
            and: [
              { to: me },
              { from: 'friend@mail.com' },
              { not: spam },
            ],
          },
          actions: { delete: true },
        },
      ],
    }
  2. Configure gmailctl using Jsonnet

    master

    The gmailctl configuration is written in Jsonnet, a powerful configuration language derived from JSON. It supports variables, functions, conditionals, and imports.

    Important: The current stable configuration format is v1alpha3. Do not use v1alpha1 or v1alpha2 as they are deprecated.

    A standard configuration includes a version (mandatory), optional author metadata, and a list of rules. Each rule consists of a filter and a set of actions.

    // Local variables help reuse config fragments
    local me = {
      or: [
        { to: 'pippo@gmail.com' },
        { to: 'pippo@hotmail.com' },
      ],
    };
    
    // The exported configuration starts here
    {
      version: 'v1alpha3',
      author: {
        name: 'Pippo Pluto',
        email: 'pippo@gmail.com'
      },
      rules: [
        {
          filter: {
            and: [
              { list: 'geeks@newsletter.com' },
              { not: me },
            ],
          },
          actions: {
            archive: true,
            labels: ['news'],
          },
        },
      ],
    }
  3. Define and reuse named filters

    master

    In the v1alpha2 YAML format, you can define reusable filters in a top-level filters section and reference them in rules using the name key. This prevents repetition.

    Note: Filters can only reference filters defined previously in the file to avoid cyclic dependencies. In Jsonnet, this functionality is unnecessary as you can use native variables.

    Example (YAML):

    version: v1alpha2
    filters:
      - name: toMe
        query:
          or:
            - to: myself@gmail.com
            - to: myself@yahoo.com
    
    rules:
      - filter:
          name: toMe
        actions:
          labels:
            - directed
  4. Combine filters with logic operators

    master

    Since a filter can only contain one expression, use logic operators to combine multiple conditions within a rule:

    • and: True only if all sub-expressions are true.
    • or: True if one or more sub-expressions are true.
    • not: True if the sub-expression is false.

    Example (YAML):

    rules:
      - filter:
          or:
            - from: foo
            - and:
                - list: bar
                - not:
                    to: baz
        actions:
          markImportant: true
  5. Understand rule evaluation in Config v1alpha1

    master

    In the v1alpha1 configuration format, rules are evaluated using a specific hierarchy of logic:

    1. Rules (OR): Every rule in the rules list is evaluated independently. If any rule matches, its actions are applied. If multiple rules match, the actions from all matching rules are applied.
    2. Filters within a rule (AND): For a single rule to match, all filters defined within that rule must match.
    3. Values within a filter (OR): Within a specific filter (e.g., from), the listed values are treated as an OR condition. The filter matches if the email satisfies any one of the listed values.

    Example logic structure:

    - filters: # Rule 1 (Matches if filterA AND filterB match)
        filterA:
          - valueA
          - valueB
        filterB:
          - valueC
      actions: ...
    
    - filters: # Rule 2 (Matches if filterC matches valueD OR valueE)
        filterC:
          - valueD
          - valueE
      actions: ...
    - filters:
        filterA:
          - valueA
          - valueB
        filterB:
          - valueC
      # omitted actions
    
    - filters:
        filterC:
          - valueD
          - valueE
      # omitted actions
  6. Locate the gmailctl configuration directory

    master

    Configuration files and credentials are stored in one of the following locations:

    1. <XDG_BASE_DIR>/gmailctl (typically ~/.config/gmailctl on Linux).
    2. ~/.gmailctl (legacy location, maintained for backward compatibility).
    3. A custom location specified via the --config argument.
  7. Manage Gmail labels in configuration

    master

    You can manage labels directly in your config by adding a labels section. If this section is present, gmailctl takes over label management.

    Important Notes:

    • Permissions: Your OAuth credentials must include the https://www.googleapis.com/auth/gmail.labels scope. If you encounter errors, run gmailctl init --reset then gmailctl init to refresh credentials.
    • Renaming: Renaming labels is not supported because it is indistinguishable from deleting and recreating a label (which would strip labels from existing messages). To rename, use the Gmail web UI first, then update your config.
    • Colors: You can optionally specify label colors using background and text hex codes. If omitted, existing colors are preserved.

    To import your existing Gmail labels into your config, use:

    $ gmailctl download > /tmp/cfg.jsonnet
    $ gmailctl edit
    {
      version: 'v1alpha3',
      labels: [
        {
          name: 'family',
          color: {
            background: "#fad165",
            text: "#000000",
          },
        },
      ],
      rules: [ /* ... */ ],
    }
  8. Manage multiple Gmail accounts using config flags

    master

    You can manage multiple Gmail accounts by specifying different configuration files using the --config flag. A common pattern is to set up bash aliases for each account:

    alias gmailctlu1='gmailctl --config=$HOME/.gmailctlu1'
    alias gmailctlu2='gmailctl --config=$HOME/.gmailctlu2'
  9. Import variables from .libjsonnet files

    master

    To keep your configuration modular and reusable, you can define common filter components in separate .libjsonnet files and import them into your main config.jsonnet.

    // spam.libjsonnet
    {
      or: [
        { from: 'foo@gmail.com' },
        { from: 'bar@hotmail.com' },
        { subject: 'buy this' },
        { subject: 'buy that' },
      ],
    }
    
    // config.jsonnet
    local spam_filter = import 'spam.libjsonnet';
    {
      version: 'v1alpha3',
      rules: [
        {
          filter: spam_filter,
          actions: { delete: true },
        },
      ],
    }
  10. Configure your text editor for gmailctl

    master

    Since gmailctl uses your system editor to modify configuration files, you should set the EDITOR environment variable.

    Linux (using xdg-mime for snap users)

    If using the snap version, configure your preferred editor (e.g., vim):

    xdg-mime default vim.desktop text/x-csrc

    Windows

    Set the EDITOR variable using cmd or powershell:

    Command Prompt:

    set "EDITOR=code --wait"

    PowerShell:

    setx EDITOR "code --wait"
    xdg-mime default vim.desktop text/x-csrc
  11. Install gmailctl

    master

    You can install gmailctl using several methods depending on your platform:

    From Source (Go)

    If you have Go installed, use go install:

    go install github.com/mbrt/gmailctl/cmd/gmailctl@latest

    macOS

    Using Homebrew:

    brew install gmailctl

    Using Macports:

    sudo port install gmailctl

    Linux

    On Fedora:

    sudo dnf install gmailctl

    Using Snap:

    sudo snap install gmailctl

    Windows

    Download pre-built binaries from the GitHub releases page.

    go install github.com/mbrt/gmailctl/cmd/gmailctl@latest