Noise

Noise is a Signal Messenger client in Elisp for Emacs powered by https://github.com/AsamK/signal-cli

Its ultimate goal is to provide a fast and efficient user interface for Signal chats.

Tech stack

The tech stack is Elisp and SQLite (for storing conversations)

Setup

The project assumes a working installation of signal-cli and interfaces with that via JSON-RPC. Noise uses Server-Sent Events (SSE) to receive messages in real-time.

Dependencies

For SQLite access we use this library - https://github.com/pekingduck/emacs-sqlite3-api

We communicate with signal-cli via JSON-RPC over HTTP on localhost port 8080 by default but this can be configured by specifying noise-signal-cli-address

User Experience

We follow Emacs conventions for keybindings with the addition of evil support out of the box. When evil compatibility is enabled then we provide a modal interface for searching conversations/contacts, creating conversations, sending messages, etc.

User Interface

See the file signal-emacs-ui.html for user interface mockups we're targeting.

Installation

signal-cli

Install signal-cli and start the daemon in JSON-RPC mode:

  # Install signal-cli (example using the official tarball)
  wget https://github.com/AsamK/signal-cli/releases/latest/download/signal-cli.tar.gz
  tar xf signal-cli.tar.gz

  # Register or link your device
  signal-cli link -n "emacs-noise"

  # Start the daemon on default port 9128
  signal-cli daemon --receive-mode=manual

emacs-sqlite3-api

Noise requires the emacs-sqlite3-api library for SQLite access. Install it with your package manager of choice, then set up Noise itself.

Noise Package

Below are recipes for several popular Emacs package managers.

elpaca
  (use-package noise
    :ensure (noise
             :host github
             :repo "git.roo.lol/jbrechtel/noise"
             :protocol https)
    :config
    ;; Optional: set a custom signal-cli address
    ;; (setq noise-signal-cli-address "http://localhost:8080")

    ;; Required when signal-cli has multiple accounts registered:
    ;; (setq noise-account "+15551234567")

    ;; Start Noise automatically
    (noise-mode 1))

Or, if you prefer the elpaca recipe directly without use-package:

  (elpaca (noise :host github
                 :repo "git.roo.lol/jbrechtel/noise"
                 :protocol https))

  (require 'noise)
  (noise-mode 1)
straight.el
  (straight-use-package
   '(noise :type git :host github
           :repo "git.roo.lol/jbrechtel/noise"
           :protocol https))

  (require 'noise)
  (noise-mode 1)
Quelpa
  (quelpa
   '(noise :fetcher github
           :repo "git.roo.lol/jbrechtel/noise"))

  (require 'noise)
  (noise-mode 1)
Manual / package-vc-install (Emacs 29+)
  (package-vc-install "https://git.roo.lol/jbrechtel/noise")

  (require 'noise)
  (noise-mode 1)
Manual clone
  git clone https://git.roo.lol/jbrechtel/noise ~/.emacs.d/manual-packages/noise

Then in your init file:

  (add-to-list 'load-path "~/.emacs.d/manual-packages/noise")
  (require 'noise)
  (noise-mode 1)

Usage

Once signal-cli is running and Noise is installed:

  • M-x noise-mode — toggle the Noise client (opens the chat list)
  • M-x noise-check-connection — test connectivity to signal-cli
  • M-x noise-select-account — pick which registered signal-cli account to use (sets noise-account)
  • M-x noise-new-chat — start a new conversation by searching contacts
  • M-x noise-new-chat-sync-contacts — re-sync contacts from signal-cli
  • M-x noise-receive — fetch new messages from signal-cli once

While noise-mode is enabled, Noise connects to signal-cli's SSE endpoint at /api/v1/events for real-time message reception. Incoming messages, delivery/read receipts, typing indicators, and messages sent from your other linked devices are all stored locally and reflected in open buffers automatically.

The SSE connection automatically reconnects with exponential backoff if the connection is lost. You can configure the maximum reconnect delay via noise-sse-max-reconnect-delay (default 60 seconds).

If signal-cli has more than one account registered, set noise-account to the phone number you want to use (E.164 format), or run M-x noise-select-account to choose interactively. With a single account it can stay nil.

Keybindings

Chat list (signal buffer)
Key Action
n Next chat
p Previous chat
RET Open selected chat
c New chat (search contacts)
m Mark chat as read
g Refresh chat list
/ Filter chats
q Quit chat list window
C-x b Switch conversation (minibuffer)
Conversation buffer (signal:NAME)

Compose inline at the > prompt at the bottom of the buffer. Message history above the prompt is read-only.

Key Action
RET Send the composed message
M-RET Insert a newline (multi-line)
C-c C-g Refresh conversation from store

Sent messages show a once sent and ✓✓ once delivered or read. When the contact is typing, the modeline shows NAME is typing….

Minibuffer switcher

M-x noise-switcher (or C-x b from the chat list) opens a fuzzy completion interface showing all conversations and contacts. Start typing to narrow, then press RET to open the selected conversation.

S
Description
A Signal Messenger client in Elisp for Emacs
Readme 170 KiB
Languages
Emacs Lisp 89.4%
HTML 10.6%