All Projects → Auties00 → WhatsappWeb4j

Auties00 / WhatsappWeb4j

Licence: MIT license
Standalone fully-featured Whatsapp Multi Device Web API for Java and Kotlin

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to WhatsappWeb4j

whatsapp-http-api
WhatsApp HTTP API that you can configure in a click!
Stars: ✭ 229 (+15.66%)
Mutual labels:  whatsapp-web, whatsapp-bot, whatsapp-api, whatsapp-chat, whatsapp-web-api
Whatsapp Web.js
A WhatsApp client library for NodeJS that connects through the WhatsApp Web browser app
Stars: ✭ 4,103 (+1972.22%)
Mutual labels:  whatsapp-web, whatsapp-bot, whatsapp-api, whatsapp-web-api
tithiwa
Automate Web WhatsApp with selenium in python.
Stars: ✭ 17 (-91.41%)
Mutual labels:  whatsapp-web, whatsapp-bot, whatsapp-api
wppconnect-server
Wppconnect Server is a ready-to-use API, just download, install, and start using, simple as that.
Stars: ✭ 290 (+46.46%)
Mutual labels:  whatsapp-web, whatsapp-bot, whatsapp-api
whatsapp-api-client
This library helps you easily create a javascript application with Whatsapp support
Stars: ✭ 39 (-80.3%)
Mutual labels:  whatsapp-bot, whatsapp-api, whatsapp-chat
ShiraoriBOT-Md
Base bot WhatsApp using library baileys multi device
Stars: ✭ 54 (-72.73%)
Mutual labels:  whatsapp-web, whatsapp-bot
PedeWhats
Projeto "Pede Whats", para solicitação de diversos tipos de comidas através do Whatsapp diretamente para o restaurante!
Stars: ✭ 18 (-90.91%)
Mutual labels:  whatsapp-web, whatsapp-api
wappdriver
Wondering how to send WhatsApp messages using Python using only 3 lines of code? You have come to the right place!
Stars: ✭ 40 (-79.8%)
Mutual labels:  whatsapp-web, whatsapp-bot
WhiteDevil
🌀Quick Response Whatsapp Bot🌀
Stars: ✭ 45 (-77.27%)
Mutual labels:  whatsapp-web, whatsapp-bot
HisokaBOT-Whatsapp-Bot
Whatsapp Bot - Node Js.
Stars: ✭ 75 (-62.12%)
Mutual labels:  whatsapp-bot, whatsapp-api
automato
🎉🎉 ( v2 ) Web Application to automate sending Whatsapp, SMS & Email* campaigns
Stars: ✭ 92 (-53.54%)
Mutual labels:  whatsapp-web, whatsapp-bot
fn-whatsapp-bot
This script is made for public bots, so use a second account to scan the qr and main account to command.
Stars: ✭ 20 (-89.9%)
Mutual labels:  whatsapp-web, whatsapp-bot
whatsapp-bot
This is a Node.js console app containing Whatsapp handler using reactive methods to response messages as chatbot. Simple but useful project to start developing a complex NON-OFFICIAL Whatsapp chatbots.
Stars: ✭ 33 (-83.33%)
Mutual labels:  whatsapp-web, whatsapp-bot
whatsapp-bot
whatsapp bot build with nodejs
Stars: ✭ 62 (-68.69%)
Mutual labels:  whatsapp-web, whatsapp-bot
python-automated-bulk-whatsapp-messages
It is a python script to send automated bulk WhatsApp messages to multiple recipients from an excel sheet at once.
Stars: ✭ 56 (-71.72%)
Mutual labels:  whatsapp-web, whatsapp-bot
whatsie
Qt Based WhatsApp Client
Stars: ✭ 437 (+120.71%)
Mutual labels:  whatsapp-web, whatsapp-chat
whatsapp-chatbot-1c-example
Внешняя обработка для программы 1С:Предприятие, которая демонстрирует реализацию простого чат-бота для мессенджера WhatsApp.
Stars: ✭ 13 (-93.43%)
Mutual labels:  whatsapp-bot, whatsapp-api
waio
Is a pretty simple and fully asynchronous framework for WhatsApp Business API written in Python 3.7 with asyncio and aiohttp.
Stars: ✭ 18 (-90.91%)
Mutual labels:  whatsapp-bot, whatsapp-api
Venom
Venom is the most complete javascript library for Whatsapp, 100% Open Source.
Stars: ✭ 3,457 (+1645.96%)
Mutual labels:  whatsapp-bot, whatsapp-api
whatsapp-bot
Piyobot adalah whatsapp bot pintar
Stars: ✭ 124 (-37.37%)
Mutual labels:  whatsapp-web, whatsapp-bot

WhatsappWeb4j

What is WhatsappWeb4j

WhatsappWeb4j is a standalone library built to interact with WhatsappWeb. This means that no browser, application or any additional software is necessary to use this library. This library was built for Java 17, the latest LTS, with preview features enabled.

Does this library support multi device?

Yes, the master branch now fully supports the multi device feature. Considering that support for legacy WhatsappWeb has been dropped by Whatsapp, this library has also dropped support for the latter. If, for whatever reason, you'd like to use a version that supports the legacy version, use any release before 3.0.

How to install

Maven

<dependency>
    <groupId>com.github.auties00</groupId>
    <artifactId>whatsappweb4j</artifactId>
    <version>3.0-RC18</version>
</dependency>

Gradle

  1. Groovy DSL

    implementation 'com.github.auties00:whatsappweb4j:3.0-RC18'
  2. Kotlin DSL

    implementation("com.github.auties00:whatsappweb4j:3.0-RC18")

Examples

If you need some examples to get started, check the examples' directory in this project. There are several easy and documented projects and more will come. Any contribution is welcomed!

Javadocs

Javadocs for WhatsappWeb4j are available here. Any contribution is welcomed!

How to contribute

As of today, no additional configuration or artifact building is needed to edit this project. I recommend using the latest version of IntelliJ, though any other IDE should work. If you are not familiar with git, follow these short tutorials in order:

  1. Fork this project
  2. Clone the new repo
  3. Create a new branch
  4. Once you have implemented the new feature, create a new merge request

If you are trying to implement a feature that is present on WhatsappWeb's WebClient, for example audio or video calls, consider using WhatsappWeb4jRequestAnalyzer, a tool I built for this exact purpose.

How to create a connection

The most important class of this API is Whatsapp, an interface between your application and WhatsappWeb's socket.

There are numerous named constructors that can be used to initiate a connection:

  1. New simple connection

    var api = Whatsapp.newConnection();
  2. Configurable new connection

    var configuration = WhatsappOptions.newOptions() // Implement only the options that you need!
            .id(ThreadLocalRandom.current().nextInt()) // A random unique ID associated with the session
            .autodetectListeners(true) // Marks whether listeners marked with @RegisterListener should be automatically registered
            .defaultSerialization(true) // Whether the default serialization mechanism should be used
            .automaticTextPreview(true) // Whether link previews should automatically be generated for texts containing links
            .version(new Version(2,2212,7)) // The default version of this client
            .url("wss://web.whatsapp.com/ws") // The URL of WhatsappWeb's Socket
            .description("WhatsappWeb4j") // The name of the service that is displayed in Whatsapp's devices tab
            .historyLength(HistoryLength.THREE_MONTHS) // The amount of chat history that Whatsapp sends to the client on the first scan
            .errorHandler(ErrorHandler.toTerminal()) // Socket errrors handler
            .qrHandler(QrHandler.toTerminal()) // Qr code handler
            .build(); // Creates an instance of WhatsappOptions
    var api = Whatsapp.newConnection(options);
  3. Last known connection chronologically

     var api = Whatsapp.lastConnection();

    IMPORTANT: If no previous session exists, a new one will be created silently

  4. First known connection chronologically

    var api = Whatsapp.firstConnection();

    IMPORTANT: If no previous session exists, a new one will be created silently

How to open a connection

Once you have created a new connection, you probably want to open it and wait until the operation succeeds:

api.connect().join();

IMPORTANT: Remember that this library heavily depends on async operations using the CompletableFuture construct. As a matter of fact, the connect method returns a CompletableFuture that is resolved only when the connection is successfully created. If you forget to call the get() method, or to handle this construct in any way, your application may terminate as there is no active work on the main thread. For the same reason, remember to also await for the connection to be closed if the logic of your application is based on listeners:

api.await();

How to close a connection

There are three ways to close a connection:

  1. Disconnect

    api.disconnect().join();

    IMPORTANT: The session remains valid for future uses

  2. Reconnect

    api.reconnect().join();

    IMPORTANT: The session remains valid for future uses

  3. Log out

    api.logout().join();

    IMPORTANT: The session doesn't remain valid for future uses

What is a listener and how to register it

Listeners are crucial to handle events related to Whatsapp and implement logic for your application. Listeners can be used either as:

  1. Standalone concrete implementation

    If your application is complex enough, it's preferable to divide your listeners' logic across multiple specialized classes. To create a new concrete listener, declare a class or record that implements the Listener interface:

    import it.auties.whatsapp.listener.Listener;
    
    public class MyListener implements Listener {
     @Override
     public void onLoggedIn() {
         System.out.println("Hello :)");
     }
    }

    Remember to manually register this listener:

    api.addListener(new MyListener());

    Or to register it automatically using the @RegisterListener annotation:

    import it.auties.whatsapp.listener.RegisterListener;
    import it.auties.whatsapp.listener.Listener;
    
    @RegisterListener // Automatically registers this listener
    public class MyListener implements Listener {
     @Override
     public void onLoggedIn() {
         System.out.println("Hello :)");
     }
    }

    Listeners often need access to the Whatsapp instance that registered them to, for example, send messages. If your listener is marked with @RegisterListener and a single argument constructor that takes a Whatsapp instance as a parameter exists, the latter can be injected automatically, regardless of if your implementation uses a class or a record. Records, though, are usually more elegant:

    import it.auties.whatsapp.listener.RegisterListener;
    import it.auties.whatsapp.api.Whatsapp;
    import it.auties.whatsapp.listener.Listener;
    
    @RegisterListener // Automatically registers this listener
    public record MyListener(Whatsapp api) implements Listener { // A non-null whatsapp instance is injected
     @Override
     public void onLoggedIn() {
         System.out.println("Hello :)");
     }
    }

    IMPORTANT: Only non-abstract classes that provide a no arguments constructor or a single parameter constructor of type Whatsapp can be registered automatically

  2. Functional interface

    If your application is very simple or only requires this library in small operations, it's preferable to add a listener using a lambda instead of using full-fledged classes. To declare a new functional listener, call the method add followed by the name of the listener that you want to implement without the on suffix:

    api.addLoggedInListener(() -> System.out.println("Hello :)"));

    Functional listeners can also access the instance of Whatsapp that registered them:

    api.addLoggedInListener(whatsapp -> System.out.println("Someone sent a new message!"));

    This is extremely useful if you want to implement a functionality for your application in a compact manner:

     Whatsapp.newConnection()
                 .addLoggedInListener(() -> System.out.println("Connected"))
                 .addNewMessageListener((whatsapp, info) -> whatsapp.sendMessage(info.chatJid(), "Automatic answer", info))
                 .connect()
                 .join()
                 .await();

How to handle serialization

In the original version of WhatsappWeb, chats, contacts and messages could be queried at any from Whatsapp's servers. The multi-device implementation, instead, sends all of this information progressively when the connection is initialized for the first time and doesn't allow any subsequent queries to access the latter. In practice, this means that this data needs to be serialized somewhere.

By default, this library serializes data regarding a session at $HOME/.whatsappweb4j/<session_id> in two different files, respectively for the store(chats, contacts and messages) and keys(cryptographic data). The latter is serialized every time a modification occurs to the model, while the store is serialized everytime a ping is sent by the socket to the server. Both are serialized when the socket is closed. Here is the default implementation:

public class DefaultControllerSerializer implements ControllerSerializer {
    @Override
    public void serialize(Controller<?> controller) {
        controller.preferences()
                .writeJson(controller, true);
    }
}

If your application needs to serialize data in a different way, for example in a database:

  1. Disable the default serialization mechanism (optional)

    var options = Options.defaultOptions() // Use the default options
            .withDefaultSerialization(false); // Disables default serialization
    var api = Whatsapp.newConnection(options); // Any named constructor can be used
  2. Create a custom serializer

    public class CustomSerializer implements ControllerSerializer {
        @Override
        public void serialize(Controller<?> controller) {
            // Your logic
        }
    }
  3. Register the custom serializer in the manifest

    • Create a directory called services inside the META-INF.
    • Inside the folder that was just created, create a file called it.auties.whatsapp.controller.ControllerSerializer.
    • Finally, inside the file that was just created write the fully qualified name of your implementation, for example com.example.CustomSerializer.

How to delete a session

To delete a particular session, call the delete method on a Whatsapp instance:

api.delete();

Instead, if you want to delete all sessions use:

Whatsapp.deleteSessions();

How to handle session disconnects

When the session is closed, the onDisconnect method in any listener is invoked. There are three types of reasons for which this can happen:

  1. DISCONNECTED

    A normal disconnection. This doesn't indicate any error being thrown.

  2. RECONNECT

    The client is being disconnected but only to reopen the connection. This always happens when the QR is first scanned for example.

  3. LOGGED_OUT

    The client was logged out by itself or by its companion. When this happens the connection is terminated and becomes expired. By default, no error is thrown if this happens, though this behaviour can be changed easily:

    import it.auties.whatsapp.api.DisconnectReason;
    import it.auties.whatsapp.listener.Listener;
    
    class ThrowOnLogOut implements Listener {
        @Override
        public void onDisconnected(DisconnectReason reason) {
            if (reason != SocketEvent.LOGGED_OUT) {
                return;
            }
    
            throw new RuntimeException("Hey, I was logged off :/");
        }
    }

How to query chats, contacts, messages and status

Access the store associated with a connection by calling the store method:

var store = api.store();

IMPORTANT: When your program first starts up, these fields will be empty. For each type of data, an event is fired and listenable using a WhatsappListener

You can access all the chats that are in memory:

var chats = store.chats();

Or the contacts:

var contacts = store.contacts();

Or even the media status:

var status = store.status();

Data can also be easily queried by using these methods:

  • Chats
    • Query a chat by its jid
      var chat = store.findChatByJid(jid);
    • Query a chat by its name
      var chat = store.findChatByName(name);
    • Query a chat by a message inside it
      var chat = store.findChatByMessage(message);
    • Query all chats that match a name
      var chats = store.findChatsByName(name);
  • Contacts
    • Query a contact by its jid
      var chat = store.findContactByJid(jid);
    • Query a contact by its name
      var contact = store.findContactByName(name);
    • Query all contacts that match a name
      var contacts = store.findContactsByName(name);
  • Media status
    • Query status by sender
      var chat = store.findStatusBySender(contact);

How to access companion and cryptographic data

Access keys store associated with a connection by calling the keys method:

var keys = api.keys();

There are several methods to access and query cryptographic data, but as it's only necessary for advanced users, please check the javadocs if this is what you need.

To access information about the companion device:

var companion = keys.companion();

This object is a jid like any other, but it has the device field filled to distinguish it from the main one. Instead, if you only need the phone number:

var phoneNumber = "+%s".formatted(keys.companion().user());

How to send messages

To send a message, start by finding the chat where the message should be sent. Here is an example:

var chat = api.store()
        .findChatByName("My Awesome Friend")
        .orElseThrow(() -> new NoSuchElementException("Hey, you don't exist"));

All types of messages supported by Whatsapp are supported by this library:

  • Text

    api.sendMessage(chat,  "This is a text message!");
  • Complex text

    var message = TextMessage.newTextMessageBuilder() // Create a new text message
            .text("Check this video out: https://www.youtube.com/watch?v=dQw4w9WgXcQ") // Set the text of the message
            .canonicalUrl("https://www.youtube.com/watch?v=dQw4w9WgXcQ") // Set the url of the message
            .matchedText("https://www.youtube.com/watch?v=dQw4w9WgXcQ") // Set the matched text for the url in the message
            .title("A nice suprise") // Set the title of the url
            .description("Check me out") // Set the description of the url
            .build(); // Create the message
    api.sendMessage(chat,  message); 
  • Location

    var location = LocationMessage.newLocationMessageBuilder() // Create a new location message
            .caption("Look at this!") // Set the caption of the message, that is the text below the file
            .latitude(38.9193) // Set the longitude of the location to share
            .longitude(1183.1389) // Set the latitude of the location to share
            .build(); // Create the message
    api.sendMessage(chat, location);
  • Live location

    var location = LiveLocationMessage.newLiveLocationMessageBuilder() // Create a new live location message
            .caption("Look at this!") // Set the caption of the message, that is the text below the file. Not available if this message is live
            .latitude(38.9193) // Set the longitude of the location to share
            .longitude(1183.1389) // Set the latitude of the location to share
            .accuracy(10) // Set the accuracy of the location in meters
            .speed(12) // Set the speed of the device sharing the location in meter per endTimeStamp
            .build(); // Create the message
    api.sendMessage(chat, location);

    IMPORTANT: Updating the position of a live location message is not supported as of now out of the box. The tools to do so, though, are in the API.

  • Group invite

    var group = api.store()
            .findChatByName("Programmers")
            .filter(Chat::isGroup)
            .orElseThrow(() -> new NoSuchElementException("Hey, you don't exist"));
    var inviteCode = api.queryInviteCode(group).join();
    var groupInvite = GroupInviteMessage.newGroupInviteMessageBuilder() // Create a new group invite message
            .caption("Come join my group of fellow programmers") // Set the caption of this message
            .name(group.name()) // Set the name of the group
            .groupJid(group.jid())) // Set the jid of the group
            .inviteExpiration(ZonedDateTime.now().plusDays(3).toEpochSecond()) // Set the expiration of this invite
            .inviteCode(inviteCode) // Set the code of the group
            .build(); // Create the message
    api.sendMessage(chat, groupInvite); 
  • Contact

     var vcard = ContactCard.newContactCardBuilder() // Create a new vcard
            .name("A nice friend") // Set the name of the contact
            .phoneNumber(contact) // Set the phone number of the contact
            .build(); // Create the vcard
    var contactMessage = ContactMessage.newContactMessageBuilder()  // Create a new contact message
            .name("A nice friend") // Set the display name of the contact
            .vcard(vcard) // Set the vcard(https://en.wikipedia.org/wiki/VCard) of the contact
            .build(); // Create the message
    api.sendMessage(chat, contactMessage);
  • Contact array

    var contactsMessage = ContactsArrayMessage.newContactsArrayMessageBuilder()  // Create a new contacts array message
            .name("A nice friend") // Set the display name of the first contact that this message contains
            .contacts(List.of(jack,lucy,jeff)) // Set a list of contact messages that this message wraps
            .build(); // Create the message
    api.sendMessage(chat, contactsMessage);
  • Button

    To create any number of messages to attach to a buttons message use the Button class:

    var button = Button.newTextResponseButton("A nice button!"); // Create a button
    var anotherButton = Button.newTextResponseButton("Another button :)"); // Create another button with different text

    There are many types of buttons:

    • Response button

      • Empty header

        var buttons = ButtonsMessage.newButtonsWithoutHeaderMessageBuilder() // Create a new button message builder
             .body("A nice body") // Set the body
             .footer("A nice footer") // Set the footer
             .buttons(List.of(button, anotherButton)) // Set the buttons
             .build(); // Create the message
        api.sendMessage(contact, emptyButtons);
      • Text header

        var buttons = ButtonsMessage.newButtonsWithTextHeaderMessageBuilder() // Create a new button message builder
             .header("A nice header :)") // Set the header
             .body("A nice body") // Set the body
             .footer("A nice footer") // Set the footer
             .buttons(List.of(button, anotherButton)) // Set the buttons
             .build(); // Create the message
        api.sendMessage(contact, buttons);
      • Document header

        var buttons = ButtonsMessage.newButtonsWithDocumentHeaderMessageBuilder() // Create a new button message builder
             .header(documentMessage) // Set the header
             .body("A nice body") // Set the body
             .footer("A nice footer") // Set the footer
             .buttons(List.of(button, anotherButton)) // Set the buttons
             .build(); // Create the message
        api.sendMessage(contact, buttons);
      • Image header

        var buttons = ButtonsMessage.newButtonsWithImageHeaderMessageBuilder() // Create a new button message builder
             .header(imageMessage) // Set the header
             .body("A nice body") // Set the body
             .footer("A nice footer") // Set the footer
             .buttons(List.of(button, anotherButton)) // Set the buttons
             .build(); // Create the message
        api.sendMessage(contact, buttons);
      • Video header

        var buttons = ButtonsMessage.newButtonsWithVideoHeaderMessageBuilder() // Create a new button message builder
             .header(videoMessage) // Set the header
             .body("A nice body") // Set the body
             .footer("A nice footer") // Set the footer
             .buttons(List.of(button, anotherButton)) // Set the buttons
             .build(); // Create the message
        api.sendMessage(contact, buttons);
      • Location header

        var buttons = ButtonsMessage.newButtonsWithLocationHeaderMessageBuilder() // Create a new button message builder
             .header(locationMessage) // Set the header
             .body("A nice body") // Set the body
             .footer("A nice footer") // Set the footer
             .buttons(List.of(button, anotherButton)) // Set the buttons
             .build(); // Create the message
        api.sendMessage(contact, buttons);
    • Native flow button

      IMPORTANT: There is no documentation for this type of button. Contributions are welcomed.

    • Interactive button

      IMPORTANT: This type of message is currently not supported by mobile Whatsapp(still in beta).

    • List message

      var buttons = List.of(ButtonRow.of("First option", "A nice description"),
            ButtonRow.of("Second option", "A nice description"),
            ButtonRow.of("Third option", "A nice description")); // Create some buttons
      var section = ButtonSection.of("First section", buttons); // Create a section from those buttons
      var otherButtons = List.of(ButtonRow.of("First option", "A nice description"),
            ButtonRow.of("Second option", "A nice description"),
            ButtonRow.of("Third option", "A nice description")); // Create some other buttons
      var anotherSection = ButtonSection.of("First section", otherButtons); // Create another section from those buttons
      var listMessage = ListMessage.newListMessageBuilder() // Create a list message builder
            .sections(List.of(section, anotherSection)) // Set the sections
            .button("Click me") // Set the button name that opens the menu
            .title("A nice title") // Set the title of the message
            .description("A nice description") // Set the description of the message
            .footer("A nice footer") // Set the footer of the message
            .type(ListMessage.Type.SINGLE_SELECT) // Set the type of the message
            .build(); // Create a list message
      api.sendMessage(contact, listMessage);
    • Template button (NOT RECOMMENDED, use list message instead)

      var quickReplyButton = HydratedButtonTemplate.of(1, HydratedQuickReplyButton.of("Click me!", "random")); // Create a quick reply button
      var urlButton = HydratedButtonTemplate.of(2, HydratedURLButton.of("Search it", "https://google.com")); // Create an url button
      var callButton = HydratedButtonTemplate.of(3, HydratedCallButton.of("Call me", "some_phone_number")); // Create a call button
      var fourRowTemplate = HydratedFourRowTemplate.newHydratedFourRowTemplateWithTextTitleBuilder() // Create a new template builder
            .title("A nice title") // Set the title
            .body("A nice body") // Set the body
            .buttons(List.of(quickReplyButton, urlButton, callButton)) // Set the buttons
            .build(); // Create the template
      var templateMessage = TemplateMessage.newHydratedTemplateMessage(fourRowTemplate); // Create a template message
      api.sendMessage(contact, templateMessage);
  • Media

    To send a media, start by reading the content inside a byte array. You might want to read it from a file:

    var media = Files.readAllBytes(Path.of("somewhere"));

    Or from a URL:

    var media = new URL(url).openStream().readAllBytes();

    All medias supported by Whatsapp are supported by this library:

    • Image

      var image = ImageMessage.newImageMessageBuilder() // Create a new image message builder
            .mediaConnection(api.store().mediaConnection()) // The media connection to use for the upload
            .media(media) // Set the image of this message
            .caption("A nice image") // Set the caption of this message
            .build(); // Create the message
      api.sendMessage(chat,  image);
    • Audio or voice

       var audio = AudioMessage.newAudioMessageBuilder() // Create a new audio message builder
             .mediaConnection(api.store().mediaConnection()) // The media connection to use for the upload
             .media(urlMedia) // Set the audio of this message
             .voiceMessage(false) // Set whether this message is a voice message
             .build(); // Create the message
       api.sendMessage(chat,  audio);
    • Video

      var video = VideoMessage.newVideoMessageBuilder() // Create a new video message builder
            .mediaConnection(api.store().mediaConnection()) // The media connection to use for the upload
            .media(urlMedia) // Set the video of this message
            .caption("A nice video") // Set the caption of this message
            .width(100) // Set the width of the video
            .height(100) // Set the height of the video
            .build(); // Create the message
      api.sendMessage(chat,  video); 
    • GIF(Video)

      var gif = VideoMessage.newGifMessageBuilder() // Create a new gif message builder
            .mediaConnection(api.store().mediaConnection()) // The media connection to use for the upload
            .media(urlMedia) // Set the gif of this message
            .caption("A nice video") // Set the caption of this message
            .gifAttribution(VideoMessageAttribution.TENOR) // Set the source of the gif
            .build(); // Create the message
      api.sendMessage(chat,  gif);

      IMPORTANT: Whatsapp doesn't support conventional gifs. Instead, videos can be played as gifs if particular attributes are set. This is the reason why the gif builder is under the VideoMessage class. Sending a conventional gif will result in an exception if detected or in undefined behaviour.

    • Document

      var document = DocumentMessage.newDocumentMessageBuilder() // Create a new document message builder
            .mediaConnection(api.store().mediaConnection()) // The media connection to use for the upload
            .media(urlMedia) // Set the document of this message
            .title("A nice pdf") // Set the title of the document
            .fileName("pdf-test.pdf") // Set the name of the document
            .pageCount(1) // Set the number of pages of the document
            .build(); // Create the message
      api.sendMessage(chat,  document);

How to change your status

To change the status of the client:

api.changePresence(true); // online
api.changePresence(false); // offline

If you want to change the status of your companion, start by choosing the right presence: These are the allowed values:

  • AVAILABLE
  • UNAVAILABLE
  • COMPOSING
  • RECORDING
  • PAUSED

Then, execute this method:

api.changePresence(chat,  presence);

IMPORTANT: The changePresence method returns a CompletableFuture: remember to handle this async construct if needed

How to query the last known presence for a contact

To query the last known status of a Contact, use the following snippet:

var lastKnownPresenceOptional = contact.lastKnownPresence();

If the returned value is an empty Optional, the last status of the contact is unknown.

Whatsapp starts sending updates regarding the presence of a contact only when:

  • A message was recently exchanged between you and said contact
  • A new message arrives from said contact
  • You send a message to said contact

To force Whatsapp to send these updates use:

api.subscribeToUserPresence(contact);

Then, after the subscribeToUserPresence's future is completed, query again the presence of that contact.

Query data about a group, or a contact

Text status
var status = api.queryStatus(contact) // A completable future
      .join() // Wait for the future to complete
      .map(ContactStatusResponse::status) // Map the response to its status
      .orElse(null); // If no status is available yield null
Profile picture or chat picture
var status = api.queryPic(contact) // A completable future
      .join() // Wait for the future to complete
      .orElse(null); // If no picture is available yield null
Group's Metadata
var metadata = api.queryGroupMetadata(group); // A completable future
      .join(); // Wait for the future to complete

Search messages

var messages = chat.messages(); // All the messages in a chat
var firstMessage = chat.firstMessage(); // First message in a chat chronologically
var lastMessage = chat.lastMessage(); // Last message in a chat chronologically 
var starredMessages = chat.starredMessages(); // All the starred messages in a chat

Change the state of a chat

Mute a chat
var future = api.mute(chat);  // A future for the request
var response = future.join(); // Wait for the future to complete
Unmute a chat
var future = api.mute(chat);  // A future for the request
var response = future.join(); // Wait for the future to complete
Archive a chat
var future = api.archive(chat);  // A future for the request
var response = future.join(); // Wait for the future to complete
Unarchive a chat
var future = api.unarchive(chat);  // A future for the request
var response = future.join(); // Wait for the future to complete
Change ephemeral message status in a chat
var future = api.changeEphemeralTimer(chat,  ChatEphemeralTimer.ONE_WEEK);  // A future for the request
var response = future.join(); // Wait for the future to complete
Mark a chat as read
var future = api.markAsRead(chat);  // A future for the request
var response = future.join(); // Wait for the future to complete
Mark a chat as unread
var future = api.markAsUnread(chat);  // A future for the request
var response = future.join(); // Wait for the future to complete
Pin a chat
var future = api.pin(chat);  // A future for the request
var response = future.join(); // Wait for the future to complete
Unpin a chat
var future = api.unpin(chat);  // A future for the request
var response = future.join(); // Wait for the future to complete

Change the state of a participant of a group

Add a contact to a group
var future = api.add(group, contact);  // A future for the request
var response = future.join(); // Wait for the future to complete
Remove a contact from a group
var future = api.remove(group, contact);  // A future for the request
var response = future.join(); // Wait for the future to complete
Promote a contact to admin in a group
var future = api.promote(group, contact);  // A future for the request
var response = future.join(); // Wait for the future to complete
Demote a contact to user in a group
var future = api.demote(group, contact);  // A future for the request
var response = future.join(); // Wait for the future to complete

Change the metadata or settings of a group

Change group's name/subject
var future = api.changeSubject(group, newName);  // A future for the request
var response = future.join(); // Wait for the future to complete
Change or remove group's description
var future = api.changeDescription(group, newDescription);  // A future for the request
var response = future.join(); // Wait for the future to complete
Change who can send messages in a group
var future = api.changeWhoCanSendMessages(group, GroupPolicy.ANYONE);  // A future for the request
var response = future.join(); // Wait for the future to complete
Change who can edit the metadata/settings in a group
var future = api.changeWhoCanEditInfo(group, GroupPolicy.ANYONE);  // A future for the request
var response = future.join(); // Wait for the future to complete
Change or remove the picture of a group
var future = api.changePicture(group, img);  // A future for the request
var response = future.join(); // Wait for the future to complete

Other group related methods

Create a group
var future = api.create("A nice name :)", friend, friend2);  // A future for the request
var response = future.join(); // Wait for the future to complete
Leave a group
var future = api.leave(group);  // A future for the request
var response = future.join(); // Wait for the future to complete
Query a group's invite code
var future = api.queryInviteCode(group);  // A future for the request
var response = future.join(); // Wait for the future to complete
Revoke a group's invite code
var future = api.revokeInviteCode(group);  // A future for the request
var response = future.join(); // Wait for the future to complete
Query a group's invite code
var future = api.acceptInvite(inviteCode);  // A future for the request
var response = future.join(); // Wait for the future to complete
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].