mirror of
https://github.com/hansjone/dsh-im-ops.git
synced 2026-10-17 03:40:46 +08:00
feat: add status reactions across messaging channels
This commit is contained in:
parent
aa8fd71b93
commit
da01e3acee
30 changed files with 1853 additions and 274 deletions
|
|
@ -6,6 +6,7 @@ export const WHATSAPP_DESCRIPTOR = Object.freeze({
|
|||
label: 'WhatsApp',
|
||||
// Translated lazily: t() must run after setImHostLanguage, not at import time.
|
||||
get connectionLabel() { return t(' Web 关联设备'); },
|
||||
reactions: Object.freeze({ processing: '👀', success: '✅', error: '❌' }),
|
||||
});
|
||||
|
||||
export class WhatsappHarnessBridge extends TextHarnessBridge {
|
||||
|
|
|
|||
|
|
@ -246,6 +246,7 @@ export function normalizeWhatsappMessage(message, accountJid, {
|
|||
addressed: !group || fromMe || mentioned || replyToSelf,
|
||||
selfChat,
|
||||
replyTarget: { jid: remoteJid, quoted: message, selfChat },
|
||||
reactionTarget: { jid: remoteJid, key: message.key },
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -411,6 +412,41 @@ export class WhatsappBotClient {
|
|||
}, 'image');
|
||||
}
|
||||
|
||||
async addReaction(target, emoji, { signal } = {}) {
|
||||
if (typeof emoji !== 'string' || !emoji.trim()) {
|
||||
throw new TypeError('A WhatsApp reaction emoji is required');
|
||||
}
|
||||
const reactionKey = emoji.trim();
|
||||
await this.#sendReaction(target, reactionKey, signal);
|
||||
return reactionKey;
|
||||
}
|
||||
|
||||
removeReaction(target, _reactionKey, { signal } = {}) {
|
||||
return this.#sendReaction(target, '', signal);
|
||||
}
|
||||
|
||||
async #sendReaction(target, text, signal) {
|
||||
if (typeof target?.jid !== 'string' || !target.jid || !target.key?.id) {
|
||||
throw new TypeError('A WhatsApp reaction target is required');
|
||||
}
|
||||
const operationSignal = signal ?? this.#signal;
|
||||
operationSignal?.throwIfAborted();
|
||||
const messageId = randomBytes(10).toString('hex').toUpperCase();
|
||||
if (typeof this.#outboundIds.reserve === 'function') {
|
||||
this.#outboundIds.reserve(messageId);
|
||||
} else {
|
||||
this.#outboundIds.remember(messageId);
|
||||
}
|
||||
const pending = this.#socket.sendMessage(
|
||||
target.jid,
|
||||
{ react: { text, key: target.key } },
|
||||
{ messageId },
|
||||
);
|
||||
const result = await waitWithSignal(pending, operationSignal);
|
||||
this.#outboundIds.remember(result?.key?.id);
|
||||
return result;
|
||||
}
|
||||
|
||||
async #sendArtifact(target, file, content, presentation) {
|
||||
this.#signal?.throwIfAborted();
|
||||
await this.#stopTyping(target.jid);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue