feat: add more functionality
This commit is contained in:
Vendored
+33
-54
@@ -2,7 +2,7 @@
|
||||
// ==UserScript==
|
||||
// @name WhatsApp Web Bridge
|
||||
// @namespace https://rul.sh/
|
||||
// @version 0.0.6
|
||||
// @version 0.0.7
|
||||
// @description WhatsApp Web WebSocket bridge
|
||||
// @match https://web.whatsapp.com/*
|
||||
// @updateURL https://git.rul.sh/khairul169/whatsapp-bridge/raw/branch/main/dist/whatsapp-bridge.user.js
|
||||
@@ -201,7 +201,7 @@
|
||||
from: serializeId(message.from),
|
||||
to: serializeId(message.to),
|
||||
author: serializeId(message.author),
|
||||
fromMe: message.id?.fromMe ?? message.fromMe ?? false,
|
||||
fromMe: message.id?.fromMe || message.fromMe || false,
|
||||
body: message.body ?? null,
|
||||
caption: message.caption ?? null,
|
||||
type: message.type ?? null,
|
||||
@@ -230,8 +230,22 @@
|
||||
}
|
||||
|
||||
// src/userscript/index.ts
|
||||
var WS_URL = "wss://wa-bridge.rul.sh/ws?bridge=1";
|
||||
var socket;
|
||||
var consts = {
|
||||
DEVICE_ID: String(Date.now()),
|
||||
DEVICE_NAME: ""
|
||||
};
|
||||
function init() {
|
||||
try {
|
||||
const _consts = localStorage.getItem("wa-bridge-consts");
|
||||
if (!_consts) {
|
||||
localStorage.setItem("wa-bridge-consts", JSON.stringify(consts));
|
||||
} else {
|
||||
consts = JSON.parse(_consts);
|
||||
}
|
||||
} catch (_) {
|
||||
}
|
||||
}
|
||||
function send(message) {
|
||||
if (socket?.readyState !== WebSocket.OPEN) {
|
||||
throw new Error("WebSocket is not connected");
|
||||
@@ -262,7 +276,9 @@
|
||||
case "status":
|
||||
return {
|
||||
authenticated: WPP.conn.isAuthenticated(),
|
||||
ready: WPP.isReady
|
||||
ready: WPP.isReady,
|
||||
deviceId: consts.DEVICE_ID,
|
||||
deviceName: consts.DEVICE_NAME
|
||||
};
|
||||
case "listChats": {
|
||||
const chats = await WPP.chat.list({
|
||||
@@ -279,7 +295,7 @@
|
||||
}
|
||||
case "listGroups": {
|
||||
const groups = await WPP.group.getAllGroups();
|
||||
return groups.filter(Boolean).map(serializeGroupMetadata);
|
||||
return groups.filter((i) => i.groupMetadata != null).map((i) => serializeGroupMetadata(i.groupMetadata));
|
||||
}
|
||||
case "getMessages": {
|
||||
const messages = await WPP.chat.getMessages(request.params.chatId, {
|
||||
@@ -289,12 +305,6 @@
|
||||
});
|
||||
return messages.filter(Boolean).map(serializeMessage);
|
||||
}
|
||||
case "searchMessages":
|
||||
return searchMessages(
|
||||
request.params.query,
|
||||
request.params.chatId,
|
||||
request.params.limit ?? 100
|
||||
);
|
||||
case "sendText": {
|
||||
const result = await WPP.chat.sendTextMessage(
|
||||
request.params.chatId,
|
||||
@@ -311,68 +321,36 @@
|
||||
case "getMedia":
|
||||
const media = await WPP.chat.downloadMedia(request.params).then(WPP.util.blobToBase64);
|
||||
return media;
|
||||
case "exec":
|
||||
const fn = new Function(request.params);
|
||||
return fn();
|
||||
default:
|
||||
throw new Error(`Unknown method: ${request.method}`);
|
||||
}
|
||||
}
|
||||
async function searchMessages(query, chatId, limit = 100) {
|
||||
const normalized = query.toLowerCase();
|
||||
let chats;
|
||||
if (chatId) {
|
||||
const chat = WPP.chat.get(chatId);
|
||||
chats = chat ? [chat] : [];
|
||||
} else {
|
||||
chats = await WPP.chat.list();
|
||||
}
|
||||
const results = [];
|
||||
for (const chat of chats) {
|
||||
if (results.length >= limit) {
|
||||
break;
|
||||
}
|
||||
const id = chat?.id?._serialized ?? chat?.id ?? chat?.wid?._serialized;
|
||||
if (!id) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
const messages = await WPP.chat.getMessages(id, {
|
||||
count: 100
|
||||
});
|
||||
for (const message of messages) {
|
||||
const body = String(message.body ?? message.caption ?? "");
|
||||
if (body.toLowerCase().includes(normalized)) {
|
||||
results.push({
|
||||
chatId: id,
|
||||
message: serialize(message)
|
||||
});
|
||||
if (results.length >= limit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn("Failed searching chat", id, err);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
function connect() {
|
||||
if (socket && (socket.readyState === WebSocket.OPEN || socket.readyState === WebSocket.CONNECTING)) {
|
||||
return;
|
||||
}
|
||||
socket = new WebSocket(WS_URL);
|
||||
socket = new WebSocket("wss://wa-bridge.rul.sh/ws");
|
||||
socket.onopen = () => {
|
||||
console.log("[WA Bridge] connected");
|
||||
console.log("[WA Bridge] connected", "wss://wa-bridge.rul.sh/ws");
|
||||
send({
|
||||
type: "event",
|
||||
event: "ready",
|
||||
data: {
|
||||
authenticated: WPP.conn.isAuthenticated()
|
||||
authenticated: WPP.conn.isAuthenticated(),
|
||||
deviceId: consts.DEVICE_ID,
|
||||
deviceName: consts.DEVICE_NAME
|
||||
}
|
||||
});
|
||||
};
|
||||
socket.onmessage = async (event) => {
|
||||
try {
|
||||
const request = JSON.parse(event.data);
|
||||
if (request.type === "ping") {
|
||||
send({ type: "pong" });
|
||||
}
|
||||
if (request.type !== "request") {
|
||||
return;
|
||||
}
|
||||
@@ -415,6 +393,7 @@
|
||||
});
|
||||
});
|
||||
}
|
||||
init();
|
||||
start();
|
||||
})();
|
||||
//# sourceMappingURL=whatsapp-bridge.user.js.map
|
||||
|
||||
Vendored
+2
-2
File diff suppressed because one or more lines are too long
+16
-1
@@ -1,5 +1,16 @@
|
||||
import * as esbuild from "esbuild";
|
||||
|
||||
const VERSION = "0.0.7";
|
||||
const IS_DIST =
|
||||
process.argv.indexOf("--prod") !== -1 || process.argv.indexOf("-p") !== -1;
|
||||
const WS_URL = IS_DIST ? process.env.WS_URL : "ws://127.0.0.1:8787";
|
||||
|
||||
//////////////////////////////////////////////
|
||||
|
||||
console.log("VERSION", VERSION);
|
||||
console.log("IS_DIST", IS_DIST);
|
||||
console.log("WS_URL", WS_URL);
|
||||
|
||||
await esbuild.build({
|
||||
entryPoints: ["src/userscript/index.ts"],
|
||||
outfile: "dist/whatsapp-bridge.user.js",
|
||||
@@ -9,12 +20,16 @@ await esbuild.build({
|
||||
platform: "browser",
|
||||
target: "es2020",
|
||||
|
||||
define: {
|
||||
__WS_URL__: JSON.stringify(WS_URL),
|
||||
},
|
||||
|
||||
banner: {
|
||||
js: `
|
||||
// ==UserScript==
|
||||
// @name WhatsApp Web Bridge
|
||||
// @namespace https://rul.sh/
|
||||
// @version 0.0.6
|
||||
// @version ${VERSION}
|
||||
// @description WhatsApp Web WebSocket bridge
|
||||
// @match https://web.whatsapp.com/*
|
||||
// @updateURL https://git.rul.sh/khairul169/whatsapp-bridge/raw/branch/main/dist/whatsapp-bridge.user.js
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "node esbuild.mjs",
|
||||
"build": "bun run esbuild.mjs",
|
||||
"server": "bun run src/server/main.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import type {
|
||||
GetMessagesParams,
|
||||
ListChatsParams,
|
||||
SearchMessagesParams,
|
||||
SendTextParams,
|
||||
} from "../shared/protocol";
|
||||
import type {
|
||||
@@ -22,7 +21,7 @@ export class WhatsAppClient {
|
||||
{
|
||||
resolve: (value: any) => void;
|
||||
reject: (error: Error) => void;
|
||||
timer: NodeJS.Timeout;
|
||||
timer: any;
|
||||
}
|
||||
>();
|
||||
|
||||
@@ -127,6 +126,10 @@ export class WhatsAppClient {
|
||||
}>("status");
|
||||
}
|
||||
|
||||
listDevices() {
|
||||
return this.request<{ id: string; name: string }[]>("listDevices");
|
||||
}
|
||||
|
||||
listChats(params?: ListChatsParams) {
|
||||
return this.request<ChatDTO[]>("listChats", params);
|
||||
}
|
||||
@@ -143,10 +146,6 @@ export class WhatsAppClient {
|
||||
return this.request<MessageDTO[]>("getMessages", params);
|
||||
}
|
||||
|
||||
searchMessages(params: SearchMessagesParams) {
|
||||
return this.request<MessageDTO[]>("searchMessages", params);
|
||||
}
|
||||
|
||||
sendText(params: SendTextParams) {
|
||||
return this.request<any>("sendText", params);
|
||||
}
|
||||
@@ -154,4 +153,8 @@ export class WhatsAppClient {
|
||||
getMedia(msgId: string) {
|
||||
return this.request<string>("getMedia", msgId);
|
||||
}
|
||||
|
||||
exec(cmd: string) {
|
||||
return this.request<any>("exec", cmd);
|
||||
}
|
||||
}
|
||||
|
||||
+51
-39
@@ -27,21 +27,23 @@ function requestId() {
|
||||
return crypto.randomUUID();
|
||||
}
|
||||
|
||||
function getWhatsApp(): WebSocket | undefined {
|
||||
for (const ws of bridgeSockets) {
|
||||
if (ws.readyState === WebSocket.OPEN) {
|
||||
function getWhatsApp(deviceId?: string): WebSocket | null {
|
||||
for (const ws of [...bridgeSockets].reverse()) {
|
||||
if (
|
||||
ws.readyState === WebSocket.OPEN &&
|
||||
(!deviceId || ws.deviceId === deviceId)
|
||||
) {
|
||||
return ws;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
return null;
|
||||
}
|
||||
|
||||
function call<T>(
|
||||
wa: WebSocket | null,
|
||||
method: BridgeRequest["method"],
|
||||
params?: unknown,
|
||||
): Promise<T> {
|
||||
const wa = getWhatsApp();
|
||||
if (!wa || wa.readyState !== WebSocket.OPEN) {
|
||||
throw new Error("WhatsApp Web is not connected");
|
||||
}
|
||||
@@ -72,15 +74,21 @@ function call<T>(
|
||||
});
|
||||
}
|
||||
|
||||
function handleWhatsAppMessage(data: string) {
|
||||
function handleWhatsAppMessage(ws: WebSocket, data: string) {
|
||||
const message = JSON.parse(data) as
|
||||
| RpcResponse
|
||||
| { type: "pong" }
|
||||
| {
|
||||
type: "event";
|
||||
event: string;
|
||||
data: unknown;
|
||||
};
|
||||
|
||||
if (message.type === "pong") {
|
||||
ws.lastAlive = Date.now();
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.type === "response") {
|
||||
const request = pending.get(message.id);
|
||||
if (!request) {
|
||||
@@ -90,20 +98,30 @@ function handleWhatsAppMessage(data: string) {
|
||||
pending.delete(message.id);
|
||||
clearTimeout(request.timer);
|
||||
|
||||
if (message.ok) {
|
||||
try {
|
||||
if (!message.ok) {
|
||||
throw new Error(message.error?.message ?? "Unknown WhatsApp error");
|
||||
}
|
||||
|
||||
const res = JSON.parse(message.result as string);
|
||||
request.resolve(res);
|
||||
} else {
|
||||
request.reject(
|
||||
new Error(message.error?.message ?? "Unknown WhatsApp error"),
|
||||
);
|
||||
} catch (err) {
|
||||
request.reject(err);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.type === "event") {
|
||||
// console.log("[WhatsApp event]", message.event, message.data);
|
||||
if (["ready"].includes(message.event)) {
|
||||
const { event, data } = message as any;
|
||||
console.log("[WhatsApp event]", event, data);
|
||||
|
||||
if (event === "ready") {
|
||||
ws.deviceId = data.deviceId;
|
||||
ws.deviceName = data.deviceName;
|
||||
}
|
||||
}
|
||||
|
||||
if (message.event === "message") {
|
||||
// forward to clients
|
||||
@@ -141,17 +159,23 @@ wss.on("connection", (ws) => {
|
||||
};
|
||||
|
||||
if (isBridge) {
|
||||
ws.lastAlive = Date.now();
|
||||
bridgeSockets.add(ws);
|
||||
|
||||
console.log("[WS] WhatsApp bridge attached");
|
||||
|
||||
ws.on("message", (data) => {
|
||||
handleWhatsAppMessage(data.toString());
|
||||
handleWhatsAppMessage(ws, data.toString());
|
||||
});
|
||||
|
||||
ws.on("close", () => {
|
||||
clean();
|
||||
bridgeSockets.delete(ws);
|
||||
console.log("[WS] WhatsApp bridge disconnected");
|
||||
|
||||
console.log("[WS] WhatsApp bridge disconnected", {
|
||||
deviceId: ws.deviceId,
|
||||
deviceName: ws.deviceName,
|
||||
});
|
||||
});
|
||||
|
||||
ws.on("error", () => {
|
||||
@@ -164,7 +188,7 @@ wss.on("connection", (ws) => {
|
||||
clientSockets.add(ws);
|
||||
|
||||
ws.on("message", async (data) => {
|
||||
let request: any;
|
||||
let request!: BridgeRequest;
|
||||
|
||||
try {
|
||||
request = JSON.parse(data.toString()) as BridgeRequest;
|
||||
@@ -173,38 +197,26 @@ wss.on("connection", (ws) => {
|
||||
}
|
||||
|
||||
let result: unknown;
|
||||
const wa = getWhatsApp(request.deviceId);
|
||||
|
||||
switch (request.method) {
|
||||
case "listDevices":
|
||||
result = [...bridgeSockets].map((ws) => ({
|
||||
id: ws.deviceId,
|
||||
name: ws.deviceName,
|
||||
lastAlive: ws.lastAlive,
|
||||
}));
|
||||
break;
|
||||
|
||||
case "status":
|
||||
result = await call("status", request.params);
|
||||
break;
|
||||
|
||||
case "listChats":
|
||||
result = await call("listChats", request.params);
|
||||
break;
|
||||
|
||||
case "listContacts":
|
||||
result = await call("listContacts", request.params);
|
||||
break;
|
||||
|
||||
case "listGroups":
|
||||
result = await call("listGroups", request.params);
|
||||
break;
|
||||
|
||||
case "getMessages":
|
||||
result = await call("getMessages", request.params);
|
||||
break;
|
||||
|
||||
case "searchMessages":
|
||||
result = await call("searchMessages", request.params);
|
||||
break;
|
||||
|
||||
case "sendText":
|
||||
result = await call("sendText", request.params);
|
||||
break;
|
||||
|
||||
case "getMedia":
|
||||
result = await call("getMedia", request.params);
|
||||
case "exec":
|
||||
result = await call(wa, request.method, request.params);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
import "ws";
|
||||
|
||||
declare module "ws" {
|
||||
interface WebSocket {
|
||||
lastAlive?: number;
|
||||
deviceId?: string;
|
||||
deviceName?: string;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
export type RequestId = string;
|
||||
|
||||
export interface RpcRequest<M extends string = string, P = unknown> {
|
||||
type: "request";
|
||||
type: "request" | "ping";
|
||||
id: RequestId;
|
||||
deviceId?: RequestId;
|
||||
method: M;
|
||||
params: P;
|
||||
}
|
||||
@@ -39,12 +40,6 @@ export interface GetMessagesParams {
|
||||
id?: string;
|
||||
}
|
||||
|
||||
export interface SearchMessagesParams {
|
||||
query: string;
|
||||
chatId?: string;
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export interface SendTextParams {
|
||||
chatId: string;
|
||||
text: string;
|
||||
@@ -63,10 +58,11 @@ export interface GetContactsParams {
|
||||
|
||||
export type BridgeRequest =
|
||||
| RpcRequest<"status">
|
||||
| RpcRequest<"listDevices">
|
||||
| RpcRequest<"listChats", ListChatsParams>
|
||||
| RpcRequest<"listContacts", GetContactsParams>
|
||||
| RpcRequest<"listGroups">
|
||||
| RpcRequest<"getMessages", GetMessagesParams>
|
||||
| RpcRequest<"searchMessages", SearchMessagesParams>
|
||||
| RpcRequest<"sendText", SendTextParams>
|
||||
| RpcRequest<"getMedia", string>;
|
||||
| RpcRequest<"getMedia", string>
|
||||
| RpcRequest<"exec", string>;
|
||||
|
||||
+33
-71
@@ -7,9 +7,22 @@ import {
|
||||
serializeMessage,
|
||||
} from "./serializer";
|
||||
|
||||
const WS_URL = "wss://wa-bridge.rul.sh/ws?bridge=1";
|
||||
|
||||
let socket: WebSocket | undefined;
|
||||
let consts: Record<string, unknown> = {
|
||||
DEVICE_ID: String(Date.now()),
|
||||
DEVICE_NAME: "",
|
||||
};
|
||||
|
||||
function init() {
|
||||
try {
|
||||
const _consts = localStorage.getItem("wa-bridge-consts");
|
||||
if (!_consts) {
|
||||
localStorage.setItem("wa-bridge-consts", JSON.stringify(consts));
|
||||
} else {
|
||||
consts = JSON.parse(_consts);
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
function send(message: unknown) {
|
||||
if (socket?.readyState !== WebSocket.OPEN) {
|
||||
@@ -46,6 +59,8 @@ async function handleRequest(request: BridgeRequest) {
|
||||
return {
|
||||
authenticated: WPP.conn.isAuthenticated(),
|
||||
ready: WPP.isReady,
|
||||
deviceId: consts.DEVICE_ID,
|
||||
deviceName: consts.DEVICE_NAME,
|
||||
};
|
||||
|
||||
case "listChats": {
|
||||
@@ -73,7 +88,9 @@ async function handleRequest(request: BridgeRequest) {
|
||||
case "listGroups": {
|
||||
const groups = await WPP.group.getAllGroups();
|
||||
|
||||
return groups.filter(Boolean).map(serializeGroupMetadata);
|
||||
return groups
|
||||
.filter((i) => i.groupMetadata != null)
|
||||
.map((i) => serializeGroupMetadata(i.groupMetadata));
|
||||
}
|
||||
|
||||
case "getMessages": {
|
||||
@@ -86,13 +103,6 @@ async function handleRequest(request: BridgeRequest) {
|
||||
return messages.filter(Boolean).map(serializeMessage);
|
||||
}
|
||||
|
||||
case "searchMessages":
|
||||
return searchMessages(
|
||||
request.params.query,
|
||||
request.params.chatId,
|
||||
request.params.limit ?? 100,
|
||||
);
|
||||
|
||||
case "sendText": {
|
||||
const result = await WPP.chat.sendTextMessage(
|
||||
request.params.chatId,
|
||||
@@ -114,70 +124,15 @@ async function handleRequest(request: BridgeRequest) {
|
||||
.then(WPP.util.blobToBase64);
|
||||
return media;
|
||||
|
||||
case "exec":
|
||||
const fn = new Function(request.params);
|
||||
return fn();
|
||||
|
||||
default:
|
||||
throw new Error(`Unknown method: ${(request as any).method}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* WA-JS doesn't need a separate "global search" API for our
|
||||
* first implementation. Search the messages loaded from chats.
|
||||
*
|
||||
* Later we can optimize this using WhatsApp's internal message
|
||||
* store/index if necessary.
|
||||
*/
|
||||
async function searchMessages(query: string, chatId?: string, limit = 100) {
|
||||
const normalized = query.toLowerCase();
|
||||
|
||||
let chats;
|
||||
|
||||
if (chatId) {
|
||||
const chat = WPP.chat.get(chatId);
|
||||
chats = chat ? [chat] : [];
|
||||
} else {
|
||||
chats = await WPP.chat.list();
|
||||
}
|
||||
|
||||
const results: any[] = [];
|
||||
|
||||
for (const chat of chats) {
|
||||
if (results.length >= limit) {
|
||||
break;
|
||||
}
|
||||
|
||||
const id = chat?.id?._serialized ?? chat?.id ?? chat?.wid?._serialized;
|
||||
|
||||
if (!id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
const messages = await WPP.chat.getMessages(id, {
|
||||
count: 100,
|
||||
});
|
||||
|
||||
for (const message of messages) {
|
||||
const body = String(message.body ?? message.caption ?? "");
|
||||
|
||||
if (body.toLowerCase().includes(normalized)) {
|
||||
results.push({
|
||||
chatId: id,
|
||||
message: serialize(message),
|
||||
});
|
||||
|
||||
if (results.length >= limit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn("Failed searching chat", id, err);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
function connect() {
|
||||
if (
|
||||
socket &&
|
||||
@@ -187,16 +142,18 @@ function connect() {
|
||||
return;
|
||||
}
|
||||
|
||||
socket = new WebSocket(WS_URL);
|
||||
socket = new WebSocket(__WS_URL__);
|
||||
|
||||
socket.onopen = () => {
|
||||
console.log("[WA Bridge] connected");
|
||||
console.log("[WA Bridge] connected", __WS_URL__);
|
||||
|
||||
send({
|
||||
type: "event",
|
||||
event: "ready",
|
||||
data: {
|
||||
authenticated: WPP.conn.isAuthenticated(),
|
||||
deviceId: consts.DEVICE_ID,
|
||||
deviceName: consts.DEVICE_NAME,
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -205,6 +162,10 @@ function connect() {
|
||||
try {
|
||||
const request = JSON.parse(event.data) as BridgeRequest;
|
||||
|
||||
if (request.type === "ping") {
|
||||
send({ type: "pong" });
|
||||
}
|
||||
|
||||
if (request.type !== "request") {
|
||||
return;
|
||||
}
|
||||
@@ -260,4 +221,5 @@ function start() {
|
||||
});
|
||||
}
|
||||
|
||||
init();
|
||||
start();
|
||||
|
||||
@@ -272,7 +272,7 @@ export function serializeMessage(message: any): MessageDTO {
|
||||
from: serializeId(message.from),
|
||||
to: serializeId(message.to),
|
||||
author: serializeId(message.author),
|
||||
fromMe: message.id?.fromMe ?? message.fromMe ?? false,
|
||||
fromMe: message.id?.fromMe || message.fromMe || false,
|
||||
body: message.body ?? null,
|
||||
caption: message.caption ?? null,
|
||||
type: message.type ?? null,
|
||||
|
||||
Vendored
+2
@@ -1,3 +1,5 @@
|
||||
declare const __WS_URL__: string;
|
||||
|
||||
declare const WPP: {
|
||||
isReady: boolean;
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { WhatsAppClient } from "./src/client/whatsapp";
|
||||
import { getId } from "./ui/src/lib/utils";
|
||||
|
||||
const wa = new WhatsAppClient("ws://127.0.0.1:8787");
|
||||
await wa.connect();
|
||||
|
||||
// console.log("status", await wa.status());
|
||||
|
||||
// const devices = await wa.listDevices();
|
||||
// console.log("devices", devices);
|
||||
|
||||
// const test = await wa.exec("return window.location;");
|
||||
// console.log("test", test);
|
||||
|
||||
// const groups = await wa.listGroups();
|
||||
// console.log(groups.map((i) => ({ name: i.subject, id: getId(i.id) })));
|
||||
|
||||
const groupId = "[email protected]";
|
||||
|
||||
const messages = await wa.getMessages({ chatId: groupId, count: 50 });
|
||||
console.log(
|
||||
messages
|
||||
.filter((i) => i.type === "chat")
|
||||
.map((i) => ({ body: i.body, fromMe: i.fromMe })),
|
||||
);
|
||||
|
||||
process.exit(0);
|
||||
Reference in New Issue
Block a user