Cobalt Documentation

repository·master·Indexed 21 days ago

https://github.com/auties00/cobalt

A standalone, unofficial, and fully-featured WhatsApp API for JVM languages requiring Java 25. Cobalt provides two client types: a 'Linked' client that reimplements WhatsApp Web, Desktop, and Mobile via a private protocol, and a 'Cloud' client that interfaces with the official Meta WhatsApp Cloud API. It features a unified message model, support for rich content, and an MCP server for AI agent interaction.

Tokens
9.4K
Snippets
26
Records
49
Agent score
74%

What's inside Cobalt

  1. Extract WhatsApp protobuf messages and enums with Proto Extractor

    master

    The Proto Extractor is a tool that extracts every protobuf message and enum definition from WhatsApp Web and emits them into a single .proto file.

    It works by using Playwright to launch a headed Chromium instance, loading web.whatsapp.com, and capturing all .js resources served. It then uses Acorn to parse these chunks, identifying modules that declare an internalSpec. The parser resolves cross-module references, enum bodies, oneof groups, and nested types to generate a proto2 source file.

  2. How WhatsAppClient and its transports work

    master

    The WhatsAppClient is a sealed interface with two primary implementations, acting as the entry point for different connection types:

    • .linkedApi(): Uses a reverse-engineered transport to act as a companion device (Web) or a standalone phone (Mobile).
    • .cloudApi(): Uses the official WhatsApp Cloud API for Business Platform numbers.

    Because operations like connect(), sendMessage(), and event listeners are defined on the shared WhatsAppClient type, code written against this interface is portable between both transports.

  3. Protocol Observability and A/B Prop Control

    master

    Cobalt MCP allows for real-time inspection and manipulation of the WhatsApp runtime environment:

    • Protocol Observability: Capture, query, and inject XML stanzas, WAM (WhatsApp Analytics/Metrics) events, and WebSocket/HTTP network traffic.
    • A/B Testing Control: Full read/write access to A/B testing flags. You can query flags, inspect their schemas (name, code, type, defaults), and mutate them to set or reset specific flags.
  4. Subscribe to WhatsApp events with listeners

    master

    Cobalt exposes WhatsApp events through two subscription patterns:

    1. Chainable Registrars: Use specific methods for individual events, such as addLoggedInListener, addNewMessageListener, addCallListener, and addDisconnectedListener.
    2. Listener Interface: Implement the LinkedWhatsAppClientListener interface, which provides no-op default methods for all events, and register it once using addListener(...).

    Note: Each listener runs on its own virtual thread. This ensures that a slow listener does not block the main connection. Every listener lambda receives the api (the client instance) as an argument.

  5. Understand the Message model: Info, Key, and Container

    master

    When handling messages, Cobalt uses three distinct types to represent the data:

    • MessageInfo: The message as it exists in a chat, containing content and metadata (sender, timestamp, status).
    • MessageKey: The unique identity of a message. It includes the parentJid() (the chat), senderJid() (the author), the message ID, and fromMe() (boolean). Use the key to perform actions like react, edit, delete, star, or pin.
    • MessageContainer: The actual content of the message (a 'one-of' type containing text, images, polls, etc.).

    To identify a recipient or sender, use a Jid. You can create one via Jid.of("15551234567"). Most methods accept a JidProvider, which is implemented by Jid, Chat, Contact, GroupMetadata, and Newsletter.

  6. What are the Cobalt client types?

    master

    Cobalt provides two distinct ways to interact with WhatsApp, unified under a single message model:

    1. The Linked client: A clean-room reimplementation of WhatsApp Web, Desktop, and Mobile apps. It does not use a browser, Selenium, or a bridge process, but instead talks directly to WhatsApp's private protocol.
    2. The Cloud client: An interface for Meta's official WhatsApp Cloud API that operates over HTTPS and includes a built-in webhook server for handling inbound traffic.

    Note: Cobalt is currently in pre-1.0 status, so expect breaking changes between releases.

  7. Manage connections and sessions

    master

    A connection represents a single registered session. You can manage them during the builder stage:

    • createConnection(): Starts a fresh, unregistered session.
    • loadLatestConnection(), loadConnection(uuid), or loadConnection(phoneNumber): Reopens a previously persisted session.
    • createConnection(sixParts): Imports credentials from a portable six-part key string.

    Once connected, you can control the lifecycle using:

    • disconnect(): Closes the connection (session remains valid).
    • reconnect(): Tears down and reconnects in one call.
    • logout(): Closes the connection and invalidates the session.
  8. Configure Linked Client flavors with .webClient()

    master

    The .webClient() method determines how the Linked client behaves and where the session (the 'Store') is kept:

    • webClient(): Pairs as a companion device (like WhatsApp Web). By default, the session is in-memory. To persist it, pass a WhatsAppStoreFactory.
    • mobileClient(): Registers as a standalone phone (iOS or Android).
    • customClient(): Allows you to provide your own custom store implementation.

    The Store is the single source of truth for signal keys, identity, contacts, chats, messages, and sync state. You can query it using typed sub-stores, for example: client.store().chatStore().findChatByJid(someJid).

    Optional<Chat> chat = client.store().chatStore().findChatByJid(someJid);
  9. How Cobalt MCP works: Reverse Engineering WhatsApp

    master

    Cobalt MCP is a graph-first Model Context Protocol (MCP) server designed for reverse engineering WhatsApp across multiple platforms (Web, Desktop, iOS, Android).

    It functions by:

    1. Extracting and Indexing: It parses JavaScript module bundles into a rich AST index and performs structural analysis on WebAssembly (WASM) modules.
    2. Knowledge Graph Construction: It exposes these modules as a structured knowledge graph, allowing for dependency traversal, symbol resolution, and cross-module call edge detection.
    3. Live Inspection: It can attach to running instances (via CDP for Web/Desktop) to inspect protocol traffic (stanzas), manipulate A/B testing flags, and use a full JavaScript/WASM debugger.
    4. WASM Deep Analysis: It provides a pipeline for analyzing WASM, including C++ vtable recovery, call graph generation, and decompilation via Ghidra.
  10. WASM Analysis Features in Cobalt MCP

    master

    Cobalt MCP provides an extensive suite of tools for reverse engineering WebAssembly (WASM) modules:

    • Structural Analysis: Inspect imports, exports, function signatures, and memory/table/global declarations.
    • Symbol & String Recovery: Extracts C string constants and maps them to the functions that load them.
    • Call Graph & Vtables: Generates call graphs (including call_indirect resolution) and recovers C++ vtables via Itanium RTTI (_ZTS/_ZTI/_ZTV).
    • Decompilation: Provides WAT disassembly and optional C pseudocode via Ghidra.
    • Binary Manipulation: Supports reading base64 binary slices and applying length-preserving byte patches.
    • Integration: WASM targets can be used with standard graph tools like find_references, search_code, and trace_dependencies.
  11. Quickstart: Log in with a QR code (Linked API)

    master

    To use Cobalt as a companion device (like WhatsApp Web), use the .linkedApi() and .webClient() methods. You can authenticate by scanning a QR code printed to your terminal using QrCode.toTerminal().

    This method creates an in-memory session that is lost when the application exits. To persist the session to disk, pass a WhatsAppStoreFactory to .webClient().

    import com.github.auties00.cobalt.client.WhatsAppClient;
    import com.github.auties00.cobalt.client.linked.LinkedWhatsAppClientVerificationHandler.Web.QrCode;
    import com.github.auties00.cobalt.model.message.MessageContainer;
    
    void main() throws Exception {
        WhatsAppClient.builder()
                .linkedApi()
                .webClient()                               // in-memory session
                .createConnection()                        // a fresh connection
                .name("Cobalt Bot")                        // the linked-device name shown in WhatsApp
                .unregistered(QrCode.toTerminal())         // print the QR to scan
                .addLoggedInListener(api -> System.out.println("Connected"))
                .addNewMessageListener((api, message) -> {
                    if (!message.key().fromMe()) {
                        message.key()
                                .parentJid()
                                .ifPresent(chat -> api.sendMessage(chat, MessageContainer.of("Got your message")));
                    }
                })
                .connect()                                 // returns once the socket is live
                .waitForDisconnection();                   // park this thread for the session
    }
  12. Quickstart: Use the Cloud API

    master

    For WhatsApp Business Platform numbers, use the .cloudApi() method. Cobalt will run a built-in webhook server to handle inbound traffic and verify Meta's webhook signatures.

    You must provide a system-user token and a phone number ID via .loadConnection(...), and an app secret via .appSecret(...) to verify incoming webhook signatures.

    import com.github.auties00.cobalt.client.WhatsAppClient;
    import com.github.auties00.cobalt.model.message.MessageContainer;
    
    void main() {
        WhatsAppClient.builder()
                .cloudApi()
                .loadConnection("EAAB...", "123456789")    // system-user token + phone number id (required)
                .appSecret("...")                          // verifies inbound webhook signatures
                .webhook("my-verify-token", 8080)          // start the webhook server on :8080
                .build()
                .addLoggedInListener(api -> System.out.println("Connected"))
                .addNewMessageListener((api, message) -> {
                    message.key()
                            .parentJid()
                            .ifPresent(chat -> api.sendMessage(chat, MessageContainer.of("Got your message")));
                })
                .connect()                                 // validates the token, starts the webhook
                .waitForDisconnection();                   // park this thread for the session
    }