@whanext/core 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/README.md +98 -0
- package/SECURITY.md +1 -1
- package/dist/index.d.ts +70 -3
- package/dist/index.js +317 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.14.0
|
|
4
|
+
|
|
5
|
+
### Adicionado
|
|
6
|
+
|
|
7
|
+
- `guards.owner()` para restringir comandos à própria conta conectada ao WhatsApp.
|
|
8
|
+
- `onlyOwner: true` para manter o mesmo recurso disponível na API legada de comandos.
|
|
9
|
+
- `ctx.isOwner` e `ctx.account` no contexto moderno; em multi-account, `ctx.account.id` identifica qual conta executou o comando.
|
|
10
|
+
- `app.account` com os identificadores atuais da conta e `isOwner(message)` sem exigir JID, LID ou número manual.
|
|
11
|
+
- `createMulti()` e `WhaNextMultiApp` para manter várias contas independentes no mesmo processo.
|
|
12
|
+
- `multi.commands` para registrar comandos, middleware, handlers de erro e autoload em todas as contas da instância.
|
|
13
|
+
- `multi.login()`, `multi.disconnect()`, `multi.health()`, `multi.get()`, `multi.ids()` e `multi.isReady` para operar as contas em conjunto.
|
|
14
|
+
- `multi.on()` para observar eventos de todas as contas com `accountId`, aplicação e payload de origem.
|
|
15
|
+
- Sessões automáticas isoladas em `./sessions/<id>` quando `auth` não é informado.
|
|
16
|
+
- Banco de mute automático separado por conta (`./data/whanext-<id>.sqlite`) quando o mute é habilitado sem banco/store explícito.
|
|
17
|
+
|
|
18
|
+
### Segurança e compatibilidade
|
|
19
|
+
|
|
20
|
+
- IDs de contas multi-account são validados para impedir caminhos de sessão inseguros.
|
|
21
|
+
- Diretórios `auth` duplicados são rejeitados entre contas que usam o provider padrão.
|
|
22
|
+
- `create()` e toda a API de uma única conta continuam compatíveis.
|
|
23
|
+
- Cada conta mantém provider, socket, sessão, cache, reconexão e identidade próprios; nenhuma sessão ativa é compartilhada entre contas.
|
|
24
|
+
|
|
25
|
+
## 0.13.1
|
|
26
|
+
|
|
27
|
+
- Corrigido download de mídias para mensagens visualização única citadas, através do cache do payload citado carregado em `contextInfo`.
|
|
28
|
+
- Adicionado desempacotamento explícito para envelopes de mensagens efêmeras e de visualização única, incluindo `viewOnceMessageV2Extension`.
|
|
29
|
+
|
|
3
30
|
## 0.13.0
|
|
4
31
|
|
|
5
32
|
- Adicionado `MessageService.repost()` para republicar qualquer mensagem do WhatsApp recebida recentemente, sem criar uma resposta.
|
package/README.md
CHANGED
|
@@ -33,7 +33,9 @@ await app.login({
|
|
|
33
33
|
|
|
34
34
|
- API pública sem objetos ou tipos crus do Baileys.
|
|
35
35
|
- Login por pairing code, sessão persistente e reconexão automática.
|
|
36
|
+
- Uma ou várias contas independentes no mesmo processo com `createMulti()`.
|
|
36
37
|
- Prefixo global e comandos declarativos com argumentos tipados.
|
|
38
|
+
- Comandos exclusivos da conta conectada com `guards.owner()` ou `onlyOwner`.
|
|
37
39
|
- Usuários normalizados entre JID, LID e PN.
|
|
38
40
|
- Mensagens, replies, edição, exclusão, menções, mídias e download normalizado.
|
|
39
41
|
- Operações de grupos e membros com resultados idempotentes.
|
|
@@ -101,6 +103,62 @@ await app.login({
|
|
|
101
103
|
|
|
102
104
|
O prefixo é definido uma vez. O router identifica o comando, remove o prefixo e cria o `ArgsParser` automaticamente.
|
|
103
105
|
|
|
106
|
+
## Múltiplas contas
|
|
107
|
+
|
|
108
|
+
Para manter duas, três ou mais contas de WhatsApp no mesmo processo, use `createMulti()`. Cada conta possui conexão, sessão, cache, reconexão e identidade próprios. A instância conjunta apenas coordena essas aplicações independentes.
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
import {
|
|
112
|
+
Browser,
|
|
113
|
+
createMulti,
|
|
114
|
+
defineCommand,
|
|
115
|
+
guards,
|
|
116
|
+
} from '@whanext/core';
|
|
117
|
+
|
|
118
|
+
const multi = await createMulti({
|
|
119
|
+
prefix: ';',
|
|
120
|
+
browser: Browser.Windows,
|
|
121
|
+
authRoot: './sessions',
|
|
122
|
+
logger: 'info',
|
|
123
|
+
accounts: [
|
|
124
|
+
{ id: 'principal', phone: process.env.PHONE_1 },
|
|
125
|
+
{ id: 'secundaria', phone: process.env.PHONE_2 },
|
|
126
|
+
{ id: 'terceira', phone: process.env.PHONE_3 },
|
|
127
|
+
],
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
multi.commands.command(defineCommand({
|
|
131
|
+
name: 'painel',
|
|
132
|
+
description: 'Exibe um painel exclusivo do dono.',
|
|
133
|
+
guards: [guards.owner()],
|
|
134
|
+
async execute(ctx) {
|
|
135
|
+
await ctx.reply(`Conta: ${ctx.account.id}`);
|
|
136
|
+
},
|
|
137
|
+
}));
|
|
138
|
+
|
|
139
|
+
await multi.login({
|
|
140
|
+
onCode(accountId, code) {
|
|
141
|
+
console.log(`[${accountId}] Código de pareamento:`, code);
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Quando `auth` não é informado na conta, o WhaNext cria automaticamente caminhos separados como `./sessions/principal`, `./sessions/secundaria` e `./sessions/terceira`. O mesmo diretório de sessão não pode ser usado por duas contas do provider padrão.
|
|
147
|
+
|
|
148
|
+
Uma conta específica continua sendo um `WhaNextApp` completo:
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
const principal = multi.get('principal');
|
|
152
|
+
|
|
153
|
+
if (principal?.isReady) {
|
|
154
|
+
await principal.message.send('5511999999999@s.whatsapp.net', {
|
|
155
|
+
text: 'Olá pela conta principal.',
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
`multi.commands.command()`, `use()`, `onError()` e `load()` aplicam a mesma configuração de comandos a todas as contas. Dentro de um comando, `ctx.account.id` informa qual conta recebeu e executou aquela interação. Eventos também podem ser observados em conjunto com `multi.on()`.
|
|
161
|
+
|
|
104
162
|
## Logging
|
|
105
163
|
|
|
106
164
|
O nível padrão é `info`. Estão disponíveis `debug`, `info`, `warn`, `error` e `silent`.
|
|
@@ -477,6 +535,45 @@ app.commands.command(
|
|
|
477
535
|
);
|
|
478
536
|
```
|
|
479
537
|
|
|
538
|
+
### Comandos exclusivos do dono
|
|
539
|
+
|
|
540
|
+
O dono é a própria conta conectada naquela aplicação. Não é necessário salvar número, JID ou LID manualmente. O provider usa a marca de mensagem enviada pela própria conta e, quando necessário, compara as identidades normalizadas da sessão.
|
|
541
|
+
|
|
542
|
+
```ts
|
|
543
|
+
app.commands.command(defineCommand({
|
|
544
|
+
name: 'chay',
|
|
545
|
+
description: 'Comando privado da conta conectada.',
|
|
546
|
+
guards: [guards.owner()],
|
|
547
|
+
|
|
548
|
+
async execute(ctx) {
|
|
549
|
+
await ctx.reply('💣 *Comando autorizado*');
|
|
550
|
+
},
|
|
551
|
+
}));
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
No contexto moderno também é possível consultar a informação diretamente:
|
|
555
|
+
|
|
556
|
+
```ts
|
|
557
|
+
if (ctx.isOwner) {
|
|
558
|
+
console.log(ctx.account.ids);
|
|
559
|
+
}
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
Na API legada, use `onlyOwner: true`:
|
|
563
|
+
|
|
564
|
+
```ts
|
|
565
|
+
app.router().command(defineCommand({
|
|
566
|
+
name: 'interno',
|
|
567
|
+
description: 'Comando exclusivo do dono.',
|
|
568
|
+
onlyOwner: true,
|
|
569
|
+
execute(message) {
|
|
570
|
+
return app.message.reply(message, { text: 'Autorizado.' });
|
|
571
|
+
},
|
|
572
|
+
}));
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
Em uma instância criada com `createMulti()`, o dono é resolvido separadamente para cada conta. Uma mensagem enviada pela conta `principal` não passa automaticamente como dona da conta `secundaria`.
|
|
576
|
+
|
|
480
577
|
### Subcomandos
|
|
481
578
|
|
|
482
579
|
```ts
|
|
@@ -579,6 +676,7 @@ Restrições disponíveis:
|
|
|
579
676
|
- `onlyPrivate`
|
|
580
677
|
- `onlyAdmin`
|
|
581
678
|
- `botMustBeAdmin`
|
|
679
|
+
- `onlyOwner`
|
|
582
680
|
|
|
583
681
|
`ArgsParser` possui `string`, `number`, `boolean`, `enum`, `user`, `duration`, `peek`, `skip` e `rest`. `args.user()` retorna `User`, nunca uma string crua.
|
|
584
682
|
|
package/SECURITY.md
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -129,9 +129,7 @@ type MediaSource = Uint8Array | {
|
|
|
129
129
|
path: string;
|
|
130
130
|
};
|
|
131
131
|
type MentionTarget = string | User;
|
|
132
|
-
/** Options for reposting a previously received message without quoting it. */
|
|
133
132
|
interface RepostMessageOptions {
|
|
134
|
-
/** Hidden or visible mentions injected into the reposted payload. */
|
|
135
133
|
mentions?: readonly MentionTarget[];
|
|
136
134
|
}
|
|
137
135
|
interface TextContent {
|
|
@@ -470,7 +468,13 @@ interface CommandCatalogView {
|
|
|
470
468
|
has(path: string): boolean;
|
|
471
469
|
find(path: string): RegisteredCommand | undefined;
|
|
472
470
|
}
|
|
471
|
+
interface CommandAccountContext {
|
|
472
|
+
readonly id: string | undefined;
|
|
473
|
+
readonly ids: readonly string[];
|
|
474
|
+
isOwner(message: Pick<Message, 'keys' | 'senderIds'>): boolean;
|
|
475
|
+
}
|
|
473
476
|
interface CommandRuntimeServices {
|
|
477
|
+
account: CommandAccountContext;
|
|
474
478
|
messages: MessageService;
|
|
475
479
|
media: MediaService;
|
|
476
480
|
groups: GroupService;
|
|
@@ -495,6 +499,8 @@ interface ReplyOptions {
|
|
|
495
499
|
interface CommandContext<Schema extends CommandOptionSchema = CommandOptionSchema> extends Message {
|
|
496
500
|
readonly message: Message;
|
|
497
501
|
readonly user: User;
|
|
502
|
+
readonly account: CommandAccountContext;
|
|
503
|
+
readonly isOwner: boolean;
|
|
498
504
|
readonly chat: CommandChatContext;
|
|
499
505
|
readonly group: CommandGroupContext | undefined;
|
|
500
506
|
readonly command: RegisteredCommand;
|
|
@@ -548,6 +554,7 @@ interface GuardResult {
|
|
|
548
554
|
}
|
|
549
555
|
type CommandGuard = (context: CommandContext) => boolean | void | GuardResult | Promise<boolean | void | GuardResult>;
|
|
550
556
|
declare const guards: {
|
|
557
|
+
owner(): CommandGuard;
|
|
551
558
|
group(): CommandGuard;
|
|
552
559
|
private(): CommandGuard;
|
|
553
560
|
userAdmin(): CommandGuard;
|
|
@@ -596,6 +603,7 @@ interface CommandMetadata {
|
|
|
596
603
|
onlyPrivate?: boolean;
|
|
597
604
|
onlyAdmin?: boolean;
|
|
598
605
|
botMustBeAdmin?: boolean;
|
|
606
|
+
onlyOwner?: boolean;
|
|
599
607
|
}
|
|
600
608
|
interface ExecutableCommandDefinition<Schema extends CommandOptionSchema = CommandOptionSchema> extends CommandMetadata {
|
|
601
609
|
options?: Schema;
|
|
@@ -702,6 +710,14 @@ declare class Logger {
|
|
|
702
710
|
error(message: string, context?: LogContext): void;
|
|
703
711
|
}
|
|
704
712
|
|
|
713
|
+
declare class AccountService {
|
|
714
|
+
#private;
|
|
715
|
+
readonly id: string | undefined;
|
|
716
|
+
constructor(provider: WhatsAppProvider, id?: string);
|
|
717
|
+
get ids(): readonly string[];
|
|
718
|
+
isOwner(message: Pick<Message, 'keys' | 'senderIds'>): boolean;
|
|
719
|
+
}
|
|
720
|
+
|
|
705
721
|
interface AppEvents {
|
|
706
722
|
message: Message;
|
|
707
723
|
connection: ConnectionUpdate;
|
|
@@ -731,9 +747,11 @@ interface WhaNextAppOptions {
|
|
|
731
747
|
logger?: LoggerConfig;
|
|
732
748
|
mute?: MuteOptions;
|
|
733
749
|
router?: Omit<RouterOptions, 'prefix'>;
|
|
750
|
+
accountId?: string;
|
|
734
751
|
}
|
|
735
752
|
declare class WhaNextApp {
|
|
736
753
|
#private;
|
|
754
|
+
readonly account: AccountService;
|
|
737
755
|
readonly message: MessageService;
|
|
738
756
|
readonly media: MediaService;
|
|
739
757
|
readonly group: GroupService;
|
|
@@ -777,9 +795,58 @@ interface CreateOptions {
|
|
|
777
795
|
reconnect?: ReconnectOptions;
|
|
778
796
|
messageCacheSize?: number;
|
|
779
797
|
provider?: WhatsAppProvider;
|
|
798
|
+
accountId?: string;
|
|
780
799
|
}
|
|
781
800
|
declare function create(options?: CreateOptions): Promise<WhaNextApp>;
|
|
782
801
|
|
|
802
|
+
interface MultiAccountOptions extends Omit<CreateOptions, 'accountId'> {
|
|
803
|
+
id: string;
|
|
804
|
+
}
|
|
805
|
+
interface CreateMultiOptions extends Omit<CreateOptions, 'accountId' | 'auth' | 'phone' | 'provider'> {
|
|
806
|
+
accounts: readonly MultiAccountOptions[];
|
|
807
|
+
authRoot?: string;
|
|
808
|
+
}
|
|
809
|
+
interface MultiLoginOptions extends Omit<LoginOptions, 'onCode'> {
|
|
810
|
+
onCode?: (accountId: string, code: string) => void | Promise<void>;
|
|
811
|
+
}
|
|
812
|
+
interface MultiAppHealth extends AppHealth {
|
|
813
|
+
accountId: string;
|
|
814
|
+
}
|
|
815
|
+
interface MultiAppEvent<Event extends keyof AppEvents> {
|
|
816
|
+
accountId: string;
|
|
817
|
+
app: WhaNextApp;
|
|
818
|
+
payload: AppEvents[Event];
|
|
819
|
+
}
|
|
820
|
+
interface MultiLoadCommandsResult {
|
|
821
|
+
accountId: string;
|
|
822
|
+
result: LoadCommandsResult;
|
|
823
|
+
}
|
|
824
|
+
declare class MultiCommandRouter {
|
|
825
|
+
#private;
|
|
826
|
+
constructor(apps: ReadonlyMap<string, WhaNextApp>);
|
|
827
|
+
command(definition: CommandDefinition): this;
|
|
828
|
+
use(middleware: CommandMiddleware): this;
|
|
829
|
+
onError(handler: CommandErrorHandler): () => void;
|
|
830
|
+
load(dirPath: string | URL, options?: LoadCommandsOptions): Promise<readonly MultiLoadCommandsResult[]>;
|
|
831
|
+
}
|
|
832
|
+
declare class WhaNextMultiApp {
|
|
833
|
+
#private;
|
|
834
|
+
readonly commands: MultiCommandRouter;
|
|
835
|
+
constructor(apps: ReadonlyMap<string, WhaNextApp>);
|
|
836
|
+
get size(): number;
|
|
837
|
+
get isReady(): boolean;
|
|
838
|
+
ids(): readonly string[];
|
|
839
|
+
has(accountId: string): boolean;
|
|
840
|
+
get(accountId: string): WhaNextApp | undefined;
|
|
841
|
+
values(): readonly WhaNextApp[];
|
|
842
|
+
router(): MultiCommandRouter;
|
|
843
|
+
on<Event extends keyof AppEvents>(event: Event, listener: (entry: MultiAppEvent<Event>) => void | Promise<void>): () => void;
|
|
844
|
+
health(): readonly MultiAppHealth[];
|
|
845
|
+
login(options?: MultiLoginOptions): Promise<void>;
|
|
846
|
+
disconnect(): Promise<void>;
|
|
847
|
+
}
|
|
848
|
+
declare function createMulti(options: CreateMultiOptions): Promise<WhaNextMultiApp>;
|
|
849
|
+
|
|
783
850
|
interface MemoryCacheStats {
|
|
784
851
|
size: number;
|
|
785
852
|
maxEntries: number;
|
|
@@ -812,4 +879,4 @@ declare class SqliteMuteStore implements MuteStore {
|
|
|
812
879
|
close(): void;
|
|
813
880
|
}
|
|
814
881
|
|
|
815
|
-
export { type AddMuteOptions, type AddMuteResult, type AppEvents, type AppHealth, type AppHealthStatus, ArgsParser, type AudioContent, type BooleanOption, Browser, type CacheOptions, type CacheStore, type CallEvent, type CallStatus, type ChangeResult, type CommandCatalogOptions, type CommandCatalogView, type CommandChatContext, type CommandConcurrency, type CommandContext, type CommandCooldown, type CommandDefinition, type CommandErrorHandler, type CommandGroupContext, type CommandGroupDefinition, type CommandGuard, type CommandHelpOptions, type CommandHooks, type CommandLocalization, type CommandMetadata, type CommandMiddleware, type CommandOptionDefinition, type CommandOptionSchema, type CommandOptionValue, type CommandOptionValues, type CommandRegistrar, CommandRouter, type CommandRuntimeServices, type CommandScope, type ConcurrencyStrategy, type ConnectionState, type ConnectionUpdate, type CreateOptions, DeferredReply, type DownloadedMedia, type DurationOption, type EnumOption, type ExecutableCommandDefinition, type GroupAccess, type GroupAddressingMode, type GroupParticipant, type GroupParticipantAction, type GroupParticipantsChanged, type GroupRole, type GroupSnapshot, type GuardResult, type ImageContent, type InviteResult, type LoadCommandsOptions, type LoadCommandsResult, type LoadedCommand, type LogContext, type LogEntry, type LogFormat, type LogLevel, type LogWriter, Logger, type LoggerConfig, type LoggerOptions, type LoginOptions, type MediaKind, type MediaSource, type MemberActionState, MemoryCache, type MemoryCacheStats, type MentionTarget, type Message, type MessageContent, type MessageContentKind, type MessageKey, type MessageMedia, type MuteChangeResult, type MuteEnforcement, type MuteOptions, type MuteRecord, MuteService, type MuteStore, type NumberOption, ParsedCommandOptions, type ParticipantUpdateResult, type PresenceState, type QuotedMessage, type ReconnectOptions, type RegisteredCommand, type RemoveMuteResult, type ReplyOptions, type RepostMessageOptions, type RouterOptions, type SentMessage, SqliteMuteStore, type StickerContent, type StoredMute, type StringOption, type TextContent, User, type UserData, type UserOption, type VideoContent, WhaNextApp, WhaNextError, type WhaNextErrorCode, type WhatsAppProvider, create, defineCommand, defineCommandGroup, defineCommands, defineSubcommand, guards, isCommandGroup, loadCommands, option, toWhaNextError };
|
|
882
|
+
export { AccountService, type AddMuteOptions, type AddMuteResult, type AppEvents, type AppHealth, type AppHealthStatus, ArgsParser, type AudioContent, type BooleanOption, Browser, type CacheOptions, type CacheStore, type CallEvent, type CallStatus, type ChangeResult, type CommandAccountContext, type CommandCatalogOptions, type CommandCatalogView, type CommandChatContext, type CommandConcurrency, type CommandContext, type CommandCooldown, type CommandDefinition, type CommandErrorHandler, type CommandGroupContext, type CommandGroupDefinition, type CommandGuard, type CommandHelpOptions, type CommandHooks, type CommandLocalization, type CommandMetadata, type CommandMiddleware, type CommandOptionDefinition, type CommandOptionSchema, type CommandOptionValue, type CommandOptionValues, type CommandRegistrar, CommandRouter, type CommandRuntimeServices, type CommandScope, type ConcurrencyStrategy, type ConnectionState, type ConnectionUpdate, type CreateMultiOptions, type CreateOptions, DeferredReply, type DownloadedMedia, type DurationOption, type EnumOption, type ExecutableCommandDefinition, type GroupAccess, type GroupAddressingMode, type GroupParticipant, type GroupParticipantAction, type GroupParticipantsChanged, type GroupRole, type GroupSnapshot, type GuardResult, type ImageContent, type InviteResult, type LoadCommandsOptions, type LoadCommandsResult, type LoadedCommand, type LogContext, type LogEntry, type LogFormat, type LogLevel, type LogWriter, Logger, type LoggerConfig, type LoggerOptions, type LoginOptions, type MediaKind, type MediaSource, type MemberActionState, MemoryCache, type MemoryCacheStats, type MentionTarget, type Message, type MessageContent, type MessageContentKind, type MessageKey, type MessageMedia, type MultiAccountOptions, type MultiAppEvent, type MultiAppHealth, MultiCommandRouter, type MultiLoadCommandsResult, type MultiLoginOptions, type MuteChangeResult, type MuteEnforcement, type MuteOptions, type MuteRecord, MuteService, type MuteStore, type NumberOption, ParsedCommandOptions, type ParticipantUpdateResult, type PresenceState, type QuotedMessage, type ReconnectOptions, type RegisteredCommand, type RemoveMuteResult, type ReplyOptions, type RepostMessageOptions, type RouterOptions, type SentMessage, SqliteMuteStore, type StickerContent, type StoredMute, type StringOption, type TextContent, User, type UserData, type UserOption, type VideoContent, WhaNextApp, WhaNextError, type WhaNextErrorCode, WhaNextMultiApp, type WhatsAppProvider, create, createMulti, defineCommand, defineCommandGroup, defineCommands, defineSubcommand, guards, isCommandGroup, loadCommands, option, toWhaNextError };
|