WhatsBox.win-x64
0.2.0
dotnet add package WhatsBox.win-x64 --version 0.2.0
NuGet\Install-Package WhatsBox.win-x64 -Version 0.2.0
<PackageReference Include="WhatsBox.win-x64" Version="0.2.0" />
<PackageVersion Include="WhatsBox.win-x64" Version="0.2.0" />
<PackageReference Include="WhatsBox.win-x64" />
paket add WhatsBox.win-x64 --version 0.2.0
#r "nuget: WhatsBox.win-x64, 0.2.0"
#:package WhatsBox.win-x64@0.2.0
#addin nuget:?package=WhatsBox.win-x64&version=0.2.0
#tool nuget:?package=WhatsBox.win-x64&version=0.2.0
The native whatsbox adapter implements Inbox Client Protocol (ICP) for WhatsApp —
one process owns a linked-device session and exposes it on the bus. The
WhatsBox NuGet is the managed
host on top of that native adapter (it is not the protocol itself). Protocol,
events, and InboxClient: the Inbox
package.
The WhatsApp connection is powered by whatsmeow;
clients never talk to whatsmeow directly. WhatsApp-specific mapping (LID
topics, QR pairing, ContextInfo quotes, HistorySync headers,
attachments: "single") is docs/WHATSBOX.md.
Managed host
WhatsBoxClient is an InboxClient that starts the native whatsbox /
whatsbox.exe sidecar. PackageReference it, then publish for your RID —
the matching native binary is restored and copied next to the app.
<PackageReference Include="WhatsBox" Version="*" />
WhatsBox is a pointer package: it ships WhatsBox.dll plus a
runtime.json that maps each runtime identifier to a RID-only package.
| Package | Contents |
|---|---|
WhatsBox |
Managed API (WhatsBox.dll) and runtime.json |
WhatsBox.win-x64 / .win-arm64 / .linux-x64 / .linux-arm64 / .osx-x64 / .osx-arm64 |
Native whatsbox / whatsbox.exe under runtimes/{rid}/native/ |
You only reference WhatsBox. Restore and dotnet publish -r <rid> pull the
matching WhatsBox.{rid} package automatically. The sidecar lands next to the
app (AppContext.BaseDirectory); WhatsBoxClient starts it from there — never
from the current working directory. Inbox's RID packing targets are not
transitive.
dotnet add package WhatsBox
dotnet publish -c Release -r win-x64
Do not add WhatsBox.win-x64 (or any other RID package) by hand. Do not treat
this as a .NET tool (PackAsTool); it is a PackageReference library plus a
native asset.
The companion sample REPL is a separate tool package (wd, for WhatsBox Demo) with the
same pointer + RID split:
ndnx wd
We recommend using
ndnxfor fastest native-only execution. It's like dnx but native, with no .NET runtime/SDK dependency.
Supported RIDs: win-x64, win-arm64, linux-x64, linux-arm64, osx-x64,
osx-arm64.
QR pairing and store
new WhatsBoxClient() starts the sidecar from AppContext.BaseDirectory.
Use WhatsBoxClient.Start(baseDirectory) to point at another folder, or
construct from an already-started WhatsBoxHost if you spawn the process
yourself.
Start consuming Events before (or concurrently with) a connecting
InitializeAsync. Pairing QR codes arrive as SessionQr while that call is
still waiting for a scan.
using WhatsBox;
var store = Path.GetFullPath("whatsbox-store");
var files = Path.GetFullPath("whatsbox-files");
Directory.CreateDirectory(store);
Directory.CreateDirectory(files);
await using var box = new WhatsBoxClient();
var pump = Task.Run(async () =>
{
await foreach (var ev in box.Events)
{
switch (ev)
{
case SessionQr qr:
// Render qr.Code as a QR image and scan it in WhatsApp → Linked devices.
Console.WriteLine(qr.Code);
break;
case SessionOnline online:
Console.WriteLine($"online as {online.Me}");
break;
case ChatMessage msg:
Console.WriteLine($"{msg.ByName ?? msg.By}: {msg.Text}");
if (msg.Id is not null)
await box.ReadAsync(msg);
break;
}
}
});
var session = await box.InitializeAsync(new InitializeOptions
{
Store = store,
Files = files,
Subscribe = ["$directory"],
Connect = true,
});
if (session.Status == "online")
{
var listed = await box.ListDirectoryAsync(new DirectoryListOptions { Query = "+15551234567" });
var chat = listed.Items[0].Topic;
await box.SubscribeAsync([chat]);
await box.SendAsync(chat, text: "hello from whatsbox");
}
await pump;
InitializeAsync(store) is the short form. The linked-device name defaults to
whatsbox on {machine}. Pass InitializeOptions when you want blobs, initial
topics, a custom DeviceName, or Connect = true (implicit session.connect,
and implicit QR pairing when the store is new).
There is no default store. One process, one store, one WhatsApp session.
SubscribeAsync / UnsubscribeAsync take canonical JIDs (LID, group, or PN
JID). Resolve names and phone numbers with ListDirectoryAsync first.
SendAsync, ReadAsync, and GetDirectoryAsync still accept a LID, a
phone-number JID, or a phone number (+15551234567 or digits). Results and
event topics are always canonical (LID or group JID) once a LID is known.
JID or Jabber ID is the canonical identifier for a WhatsApp chat. LID is a logical identifier (like a username) that is stable across devices.
Chat events have no phone number — look up By (or a 1:1 Topic) with
GetDirectoryAsync when you need Pn. In 1:1 the sidecar ignores by on
reply / react / read; in groups every id in that call must share that author.
Native sidecar
whatsbox [--store ABSOLUTE_PATH] [--version] [--help]
stdin / stdout is NDJSON JSON-RPC; stderr is logs. LID / QR / store layout:
docs/WHATSBOX.md.
v1 scope
Does: pair via QR, connect / auto-reconnect / disconnect / logout,
directory populate + list/get + live $directory, subscribe by JID
(LID-first), live messages / receipts / in-chat meta, send contents[],
reply, react, explicit mark-read.
Does not: message history, search, backfill, export; stored bodies or last-message previews; typing or “available” presence; edit or revoke; pair-code or passkey pairing; channels, status, calls, blocklist or group admin RPCs; MCP / sockets; multi-account in one process; topic wildcards; a default store path.
Open Source Maintenance Fee
To ensure the long-term sustainability of this project, users of this package who generate revenue must pay an Open Source Maintenance Fee. While the source code is freely available under the terms of the License, this package and other aspects of the project require adherence to the Maintenance Fee.
To pay the Maintenance Fee, become a Sponsor at the proper OSMF tier. A single fee covers all of Devlooped packages.
Sponsors
Learn more about Target Frameworks and .NET Standard.
This package has no dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.