Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ working without notice.

* [Installation](#installation)
* [Usage](#usage)
* [Configuration](#configuration)
* [Global configuration options](#global-configuration-options)
* [Troubleshooting](#troubleshooting)
* [FAQ](#faq)
* [Development](#development)
Expand Down Expand Up @@ -350,7 +350,16 @@ To get the WhatsApp ID of the logged in user:
npx mudslide@latest me
```

# Configuration
# Global configuration options

The global configuration options must precede the command.
For example:

```shell
npx mudslide@latest --timeout 3 send me 'hello world'
```

## Location of cache folder

By default WhatsApp credentials are cached in a folder located in the user's
home directory. This folder is `~/.local/share/mudslide` on Linux & macOS and
Expand All @@ -372,6 +381,15 @@ export HTTPS_PROXY=http://USER:PASS@proxy.server.com:80
npx mudslide@latest --proxy login
```

## Timeout

The default timeout for commands is 10 seconds. This duration can be changed
using the `--timeout <seconds>` flag:

```shell
npx mudslide@latest --timeout 3 send me 'hello world'
```

# Troubleshooting

In case Mudslide does not give any output or does not behave as expected, try
Expand Down
69 changes: 48 additions & 21 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env node
import {program} from "commander";
import {Command, Option, program} from "commander";
import {globalOptions, loginWithPairingCode, loginWithQrCode, logout, mudslideFooter} from "./whatsapp";
import {
listGroupParticipants,
Expand All @@ -13,6 +13,7 @@ import {
sendPoll
} from "./commands";
import {bootstrap} from 'global-agent';
import signale from "signale";

const packageJson = require('../package.json');

Expand Down Expand Up @@ -42,68 +43,94 @@ program.on('option:proxy', () => {
// @ts-ignore
global.GLOBAL_AGENT.HTTPS_PROXY = process.env.HTTPS_PROXY;
});
program
.command('login')
.description('Login to WhatsApp')
.option('--pairing-code', 'Use pairing code instead of QR code')
.action((options) => options.pairingCode ? loginWithPairingCode() : loginWithQrCode());
program
.command('logout')
.description('Logout from WhatsApp')
.action(() => logout());

function configureCommands() {
program.addOption(new Option('--timeout <sec>', 'Command timeout').default(10).argParser(parseInt));

program.hook('preAction', (command: Command) => {
const timeout = command.getOptionValue('timeout');
setTimeout(() => {
signale.error('Action timed out');
process.exit(1);
}, timeout * 1000);
});

function configureBasicCommands() {
program
.command('login')
.description('Login to WhatsApp')
.option('--pairing-code', 'Use pairing code instead of QR code')
.action((options) => options.pairingCode ? loginWithPairingCode() : loginWithQrCode());

program
.command('logout')
.description('Logout from WhatsApp')
.action(() => logout());

program
.command('me')
.description('Show current user details')
.action(() => me());
program
.command('groups')
.description('List all your groups')
.action(() => listGroups());
}

function configureSendCommands() {
program
.command('send <recipient> <message>')
.description('Send message')
.action((recipient, message, options) => sendMessage(recipient, message, options));

program
.command('send-image <recipient> <file>')
.option('--caption <text>', 'Caption text')
.description('Send image file')
.action((recipient, file, options) => sendImage(recipient, file, options));

program
.command('send-file <recipient> <file>')
.option('--caption <text>', 'Caption text')
.option('--type <document|audio|video>', 'File type', 'document')
.description('Send file')
.action((recipient, file, options) => sendFile(recipient, file, options));

program
.command('send-location <recipient> <latitude> <longitude>')
.allowUnknownOption()
.description('Send location')
.action((recipient, latitude, longitude) => sendLocation(recipient, latitude, longitude));

program
.command('send-poll <recipient> <name>')
.option('--item <text>', 'Poll item (repeatable option)', (val, prev: Array<string>) => prev.concat([val]), [])
.option('--selectable <count>', 'Number of selectable items', '1')
.description('Send poll')
.action((recipient, name, options) => sendPoll(recipient, name, options));
}

function configureGroupCommands() {
program
.command('groups')
.description('List all your groups')
.action(() => listGroups());

program
.command('list-group <group-id>')
.description('List group participants')
.action((groupId) => listGroupParticipants(groupId));

program
.command('add-to-group <group-id> <phone-number>')
.allowUnknownOption()
.description('Add group participant')
.action((groupId, phoneNumber) => mutateGroup(groupId, phoneNumber, 'add'));

program
.command('remove-from-group <group-id> <phone-number>')
.allowUnknownOption()
.description('Remove group participant')
.action((groupId, phoneNumber) => mutateGroup(groupId, phoneNumber, 'remove'));
program
.command('list-group <group-id>')
.description('List group participants')
.action((groupId) => listGroupParticipants(groupId));
}

configureCommands();
configureBasicCommands();
configureSendCommands();
configureGroupCommands();
program.addHelpText('after', `

Examples:
Expand Down
2 changes: 2 additions & 0 deletions src/whatsapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ export async function initWASocket(message?: string): Promise<WASocket> {
const os = process.platform === 'darwin' ? 'macOS' : process.platform === 'win32' ? 'Windows' : 'Linux';
const {version} = await fetchLatestWaWebVersion({});
const socket = makeWASocket({
connectTimeoutMs: 3_000,
defaultQueryTimeoutMs: 6_000,
logger: pino({level: globalOptions.logLevel}),
auth: state,
browser: [os, 'Chrome', '10.15.0'],
Expand Down