[core] Add message.reaction webhook
This commit is contained in:
1 parent
a31af45d97
commit
dfdb033769
8 files changed
+148
-5
No files matched your search
@@ -86,7 +86,7 @@ Here, you will find a list of supported endpoints and webhooks per engine.
|
||||
If you don't specify `WHATSAPP_DEFAULT_ENGINE` environment variable - look at **WEBJS** engine,
|
||||
it's the engine WAHA runs by default.
|
||||
|
||||
### Engine
|
||||
### Protocols
|
||||
|
||||
| | WEBJS | NOWEB | VENOM |
|
||||
|--------------------------------------------------------------|:-----:|:-----:|:-----:|
|
||||
@@ -186,10 +186,13 @@ please [create an issue](https://github.com/devlikeapro/whatsapp-http-api/issues
|
||||
| `GET /api/version` | ➖ | ✔️ | ➖ |
|
||||
| `GET /health`  | ✔️ | ✔️ | ✔️ |
|
||||
|
||||
### Webhooks
|
||||
|
||||
| **Webhooks** | WEBJS | NOWEB | VENOM |
|
||||
|-----------------------------------------------------|:-----:|:-----:|:-----:|
|
||||
| `message` | ✔️ | ✔️ | ✔️ |
|
||||
| `message` with files  | ✔️ | ✔️ | ✔️ |
|
||||
| `message.reaction` | ✔️ | ✔️ | ➖ |
|
||||
| `message.any` | ✔️ | ✔️ | ✔️ |
|
||||
| `message.ack` | ✔️ | ✔️ | ✔️ |
|
||||
| `message.revoked` | ✔️ | ➖ | ➖ |
|
||||
|
||||
@@ -226,6 +226,43 @@ Fired on all message creations, including your own. The payload is the same as f
|
||||
}
|
||||
```
|
||||
|
||||
### message.reaction
|
||||
Receive events when a message is reacted to by a user (or **yourself** reacting to a message).
|
||||
- `payload.reaction.text` - emoji that was used to react to the message. It'll be an empty string if the reaction was removed.
|
||||
- `payload.reaction.messageId` - id of the message that was reacted to.
|
||||
|
||||
```json
|
||||
{
|
||||
"event": "message.reaction",
|
||||
"session": "default",
|
||||
"me": {
|
||||
"id": "79222222222@c.us",
|
||||
"pushName": "WAHA"
|
||||
},
|
||||
"payload": {
|
||||
"id": "false_79111111@c.us_11111111111111111111111111111111",
|
||||
"from": "79111111@c.us",
|
||||
"fromMe": false,
|
||||
"participant": "79111111@c.us",
|
||||
"to": "79111111@c.us",
|
||||
"timestamp": 1710481111.853,
|
||||
"reaction": {
|
||||
"text": "🙏",
|
||||
"messageId": "true_79111111@c.us_11111111111111111111111111111111"
|
||||
}
|
||||
},
|
||||
"engine": "WEBJS",
|
||||
"environment": {
|
||||
"version": "2024.3.3",
|
||||
"engine": "WEBJS",
|
||||
"tier": "PLUS",
|
||||
"browser": "/usr/bin/google-chrome-stable"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{{< alert icon="👉" text="NOWEB engine note - reactions were sent in 'message' and 'message.any' events, not it's available only in 'message.reaction'!" />}}
|
||||
|
||||
### message.ack
|
||||
Receive events when server or recipient gets the message, read or played it.
|
||||
|
||||
|
||||
@@ -19,6 +19,10 @@ If you wish to get and read Release Notes - read them on one of our platforms, *
|
||||
|
||||
You even can **subscribe to get new updates** there!
|
||||
|
||||
## 2024.3
|
||||
- Add [message.reaction]({{< relref "/docs/how-to/webhooks#messagereaction" >}}) webhook in **WEBJS** and **NOWEB** engines ([#275](https://github.com/devlikeapro/whatsapp-http-api/issues/275)).
|
||||
- 👉 **NOWEB** engine note - reactions were sent in `'message'` and `'message.any'` events, not it's available **only** in `'message.reaction'`!
|
||||
|
||||
## 2024.2
|
||||
- Add support for [MongoDB as storage for Session data]({{< relref "/docs/how-to/storages" >}})
|
||||
- Support persistent file storage for media files - [now you can save media files between container restarts]({{< relref "/docs/how-to/storages#media" >}})
|
||||
|
||||
@@ -55,7 +55,10 @@ import {
|
||||
WAHAChatPresences,
|
||||
WAHAPresenceData,
|
||||
} from '../../../structures/presence.dto';
|
||||
import { WAMessage } from '../../../structures/responses.dto';
|
||||
import {
|
||||
WAMessage,
|
||||
WAMessageReaction,
|
||||
} from '../../../structures/responses.dto';
|
||||
import { MeInfo } from '../../../structures/sessions.dto';
|
||||
import { BROADCAST_ID, TextStatus } from '../../../structures/status.dto';
|
||||
import {
|
||||
@@ -585,6 +588,12 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
this.handleIncomingMessages(messages, handler, false);
|
||||
});
|
||||
return true;
|
||||
case WAHAEvents.MESSAGE_REACTION:
|
||||
this.sock.ev.on(BaileysEvents.MESSAGES_UPSERT, ({ messages }) => {
|
||||
const reactions = this.processMessageReaction(messages);
|
||||
reactions.map(handler);
|
||||
});
|
||||
return true;
|
||||
case WAHAEvents.MESSAGE_ANY:
|
||||
this.sock.ev.on(BaileysEvents.MESSAGES_UPSERT, ({ messages }) =>
|
||||
this.handleIncomingMessages(messages, handler, true),
|
||||
@@ -641,6 +650,8 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
// if there is no text or media message
|
||||
if (!message) return;
|
||||
if (!message.message) return;
|
||||
// Ignore reactions, we have dedicated handler for that
|
||||
if (message.message.reactionMessage) return;
|
||||
// Ignore poll votes, we have dedicated handler for that
|
||||
if (message.message.pollUpdateMessage) return;
|
||||
// Do not include my messages
|
||||
@@ -651,6 +662,34 @@ export class WhatsappSessionNoWebCore extends WhatsappSession {
|
||||
}
|
||||
}
|
||||
|
||||
private processMessageReaction(messages: any[]): WAMessageReaction[] {
|
||||
const reactions = [];
|
||||
for (const message of messages) {
|
||||
if (!message) return;
|
||||
if (!message.message) return;
|
||||
if (!message.message.reactionMessage) return;
|
||||
|
||||
const id = buildMessageId(message.key);
|
||||
const fromToParticipant = getFromToParticipant(message);
|
||||
const reactionMessage = message.message.reactionMessage;
|
||||
const messageId = buildMessageId(reactionMessage.key);
|
||||
const reaction: WAMessageReaction = {
|
||||
id: id,
|
||||
timestamp: message.messageTimestamp,
|
||||
from: toCusFormat(fromToParticipant.from),
|
||||
fromMe: message.key.fromMe,
|
||||
to: toCusFormat(fromToParticipant.to),
|
||||
participant: toCusFormat(fromToParticipant.participant),
|
||||
reaction: {
|
||||
text: reactionMessage.text,
|
||||
messageId: messageId,
|
||||
},
|
||||
};
|
||||
reactions.push(reaction);
|
||||
}
|
||||
return reactions;
|
||||
}
|
||||
|
||||
private processIncomingMessage(message) {
|
||||
return this.downloadMedia(message)
|
||||
.then(this.toWAMessage)
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
GroupChat,
|
||||
Location,
|
||||
Message,
|
||||
Reaction,
|
||||
} from 'whatsapp-web.js';
|
||||
import { Message as MessageInstance } from 'whatsapp-web.js/src/structures';
|
||||
|
||||
@@ -39,7 +40,10 @@ import {
|
||||
ParticipantsRequest,
|
||||
SettingsSecurityChangeInfo,
|
||||
} from '../../../structures/groups.dto';
|
||||
import { WAMessage } from '../../../structures/responses.dto';
|
||||
import {
|
||||
WAMessage,
|
||||
WAMessageReaction,
|
||||
} from '../../../structures/responses.dto';
|
||||
import { MeInfo } from '../../../structures/sessions.dto';
|
||||
import { WAMessageRevokedBody } from '../../../structures/webhooks.dto';
|
||||
import { IEngineMediaProcessor } from '../../abc/media.abc';
|
||||
@@ -520,6 +524,11 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
},
|
||||
);
|
||||
return true;
|
||||
case WAHAEvents.MESSAGE_REACTION:
|
||||
this.whatsapp.on('message_reaction', (message) =>
|
||||
handler(this.processMessageReaction(message)),
|
||||
);
|
||||
return true;
|
||||
case WAHAEvents.MESSAGE_ANY:
|
||||
this.whatsapp.on(Events.MESSAGE_CREATE, (message) =>
|
||||
this.processIncomingMessage(message).then(handler),
|
||||
@@ -557,6 +566,21 @@ export class WhatsappSessionWebJSCore extends WhatsappSession {
|
||||
return await this.toWAMessage(message);
|
||||
}
|
||||
|
||||
private processMessageReaction(reaction: Reaction): WAMessageReaction {
|
||||
return {
|
||||
id: reaction.id._serialized,
|
||||
from: reaction.senderId,
|
||||
fromMe: reaction.id.fromMe,
|
||||
participant: reaction.senderId,
|
||||
to: reaction.id.remote,
|
||||
timestamp: reaction.timestamp,
|
||||
reaction: {
|
||||
text: reaction.reaction,
|
||||
messageId: reaction.msgId._serialized,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
protected toWAMessage(message: Message): Promise<WAMessage> {
|
||||
// @ts-ignore
|
||||
return Promise.resolve({
|
||||
|
||||
@@ -3,6 +3,7 @@ export const SECOND = 1000;
|
||||
export enum WAHAEvents {
|
||||
SESSION_STATUS = 'session.status',
|
||||
MESSAGE = 'message',
|
||||
MESSAGE_REACTION = 'message.reaction',
|
||||
MESSAGE_ANY = 'message.any',
|
||||
MESSAGE_ACK = 'message.ack',
|
||||
MESSAGE_REVOKED = 'message.revoked',
|
||||
|
||||
@@ -30,7 +30,7 @@ export class WAMedia {
|
||||
filename?: string;
|
||||
}
|
||||
|
||||
export class WAMessage {
|
||||
class WAMessageBase {
|
||||
@MessageIdProperty()
|
||||
id: string;
|
||||
|
||||
@@ -65,7 +65,9 @@ export class WAMessage {
|
||||
description: 'For groups - participant who sent the message',
|
||||
})
|
||||
participant: string;
|
||||
}
|
||||
|
||||
export class WAMessage extends WAMessageBase {
|
||||
@ApiProperty({
|
||||
description: 'Message content',
|
||||
})
|
||||
@@ -121,3 +123,25 @@ export class WAMessage {
|
||||
})
|
||||
_data?: any;
|
||||
}
|
||||
|
||||
export class WAReaction {
|
||||
@ApiProperty({
|
||||
description:
|
||||
'Reaction to the message. Either the reaction (emoji) or empty string to remove the reaction',
|
||||
})
|
||||
text: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: 'Message ID for the message to react to',
|
||||
example: 'false_11111111111@c.us_AAAAAAAAAAAAAAAAAAAA',
|
||||
})
|
||||
messageId: string;
|
||||
}
|
||||
|
||||
export class WAMessageReaction extends WAMessageBase {
|
||||
@ApiProperty({
|
||||
description:
|
||||
'Reaction to the message. Either the reaction (emoji) or empty string to remove the reaction',
|
||||
})
|
||||
reaction: WAReaction;
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
import { WAHAEnvironment } from './environment.dto';
|
||||
import { WAHAChatPresences } from './presence.dto';
|
||||
import { ChatIdProperty, MessageIdProperty } from './properties.dto';
|
||||
import { WAMessage } from './responses.dto';
|
||||
import { WAMessage, WAMessageReaction } from './responses.dto';
|
||||
import { MeInfo } from './sessions.dto';
|
||||
|
||||
export class WAMessageAckBody {
|
||||
@@ -134,6 +134,16 @@ class WAHAWebhookMessage extends WAHAWebhook {
|
||||
payload: WAMessage;
|
||||
}
|
||||
|
||||
class WAHAWebhookMessageReaction extends WAHAWebhook {
|
||||
@ApiProperty({
|
||||
description:
|
||||
'The event is triggered when a user reacts or removes a reaction.',
|
||||
})
|
||||
event = WAHAEvents.MESSAGE_REACTION;
|
||||
|
||||
payload: WAMessageReaction;
|
||||
}
|
||||
|
||||
class WAHAWebhookMessageAny extends WAHAWebhook {
|
||||
@ApiProperty({
|
||||
description: 'Fired on all message creations, including your own.',
|
||||
@@ -223,6 +233,7 @@ class WAHAWebhookPollVoteFailed extends WAHAWebhook {
|
||||
const WAHA_WEBHOOKS = [
|
||||
WAHAWebhookSessionStatus,
|
||||
WAHAWebhookMessage,
|
||||
WAHAWebhookMessageReaction,
|
||||
WAHAWebhookMessageAny,
|
||||
WAHAWebhookMessageAck,
|
||||
WAHAWebhookMessageRevoked,
|
||||
|
||||
Reference in new issue
Block a user