mirror of
https://github.com/FranP-code/Baileys.git
synced 2025-10-13 00:32:22 +00:00
277 lines
11 KiB
JavaScript
277 lines
11 KiB
JavaScript
const BinaryCoding = require('./binary_coding/binary_encoder.js')
|
|
const QR = require('qrcode-terminal')
|
|
const Utils = require('./WhatsAppWeb.Utils')
|
|
|
|
/**
|
|
* @typedef WhatsAppMessage
|
|
* @property {Object} key metadata about the sender
|
|
* @property {string} key.remoteJid sender ID (could be group or individual)
|
|
* @property {bool} key.fromMe
|
|
* @property {string} key.id ID of the message
|
|
* @property {string} [key.participant] if its a group, which individual sent it
|
|
* @property {Object} [message] the actual message
|
|
* @property {string} messageTimestamp unix timestamp
|
|
* @property {number} [duration] the duration of the live location
|
|
*/
|
|
|
|
class WhatsAppWeb {
|
|
/**
|
|
* set of statuses visible to other people; see updatePresence() in WhatsAppWeb.Send
|
|
*/
|
|
static Presence = {
|
|
available: "available", // "online"
|
|
unavailable: "unavailable", // "offline"
|
|
composing: "composing", // "typing..."
|
|
recording: "recording", // "recording..."
|
|
paused: "paused" // I have no clue
|
|
}
|
|
/**
|
|
* Status of a message sent or received
|
|
*/
|
|
static MessageStatus = {
|
|
sent: "sent",
|
|
received: "received",
|
|
read: "read"
|
|
}
|
|
/**
|
|
* set of message types that are supported by the library
|
|
*/
|
|
static MessageType = {
|
|
text: "conversation",
|
|
image: "imageMessage",
|
|
video: "videoMessage",
|
|
sticker: "stickerMessage",
|
|
document: "documentMessage",
|
|
audio: "audioMessage",
|
|
extendedText: "extendedTextMessage",
|
|
contact: "contactMessage",
|
|
location: "locationMessage",
|
|
liveLocation: "liveLocationMessage"
|
|
}
|
|
/**
|
|
* Tells us what kind of message it is
|
|
*/
|
|
static MessageStubTypes = {
|
|
20: "addedToGroup",
|
|
32: "leftGroup",
|
|
39: "createdGroup"
|
|
}
|
|
|
|
constructor() {
|
|
/** The version of WhatsApp Web we're telling the servers we are */
|
|
this.version = [0,4,1296]
|
|
this.browserDescriptions = ["Baileys", "Baileys"]
|
|
/** The websocket connection
|
|
* @private
|
|
*/
|
|
this.conn = null
|
|
/** Data structure of tokens & IDs used to establish one's identiy to WhatsApp Web */
|
|
this.authInfo = {
|
|
clientID: null,
|
|
serverToken: null,
|
|
clientToken: null,
|
|
encKey: null,
|
|
macKey: null
|
|
}
|
|
/** Metadata like WhatsApp id, name set on WhatsApp etc. */
|
|
this.userMetaData = {id: null, name: null, phone: null}
|
|
/** @private */
|
|
this.msgCount = 0 // (epoch) number of messages sent to the server; required field for sending messages etc.
|
|
/** Shoud reconnect automatically after an unexpected disconnect */
|
|
this.autoReconnect = true //
|
|
/** @private */
|
|
this.lastSeen = null // updated by sending a keep alive request to the server, and the server responds with our updated last seen
|
|
/** Log messages that are not handled, so you can debug & see what custom stuff you can implement */
|
|
this.logUnhandledMessages = false
|
|
/** @private */
|
|
this.callbacks = {}
|
|
|
|
/**
|
|
* What to do when you need the phone to authenticate the connection (generate QR code by default)
|
|
*/
|
|
this.onReadyForPhoneAuthentication = this.generateQRCode
|
|
|
|
this.onRe
|
|
this.encoder = new BinaryCoding.Encoder()
|
|
this.decoder = new BinaryCoding.Decoder()
|
|
|
|
this.unexpectedDisconnect = (err) => { this.close () }
|
|
}
|
|
/**
|
|
* Set the callback for unexpected disconnects
|
|
* @param {function(object)} callback
|
|
*/
|
|
setOnUnexpectedDisconnect (callback) {
|
|
this.unexpectedDisconnect = (err) => {
|
|
this.close ()
|
|
callback (err)
|
|
}
|
|
}
|
|
/**
|
|
* Set the callback for message status updates (when a message is delivered, read etc.)
|
|
* @param {function(object)} callback
|
|
*/
|
|
setOnMessageStatusChange (callback) {
|
|
const func = (json) => {
|
|
json = json[1]
|
|
var ids = json.id
|
|
if (json.cmd === "ack") {
|
|
ids = [json.id]
|
|
}
|
|
const ackTypes = [
|
|
WhatsAppWeb.MessageStatus.sent,
|
|
WhatsAppWeb.MessageStatus.received,
|
|
WhatsAppWeb.MessageStatus.read
|
|
]
|
|
const data = {
|
|
from: json.from,
|
|
to: json.to,
|
|
participant: json.participant,
|
|
timestamp: new Date (json.t*1000),
|
|
ids: ids,
|
|
type: ackTypes[json.ack-1] || "unknown (" + json.ack + ")"
|
|
}
|
|
callback (data)
|
|
}
|
|
this.registerCallback ("Msg", func)
|
|
this.registerCallback ("MsgInfo", func)
|
|
}
|
|
/**
|
|
* Set the callback for new/unread messages; if someone sends you a message, this callback will be fired
|
|
* @param {function(WhatsAppMessage)} callback
|
|
* @param {boolean} callbackOnMyMessages - should the callback be fired on a message you sent
|
|
*/
|
|
setOnUnreadMessage (callback, callbackOnMyMessages=false) {
|
|
this.registerCallback (["action", "add:relay", "message"], (json) => {
|
|
const message = json[2][0][2]
|
|
if (!message.key.fromMe || callbackOnMyMessages) { // if this message was sent to us, notify
|
|
callback (message)
|
|
} else if (this.logUnhandledMessages) {
|
|
this.log (`[Unhandled] message - ${JSON.stringify(message)}`)
|
|
}
|
|
})
|
|
}
|
|
/**
|
|
* Set the callback for presence updates; if someone goes offline/online, this callback will be fired
|
|
* @param {function(object)} callback
|
|
*/
|
|
setOnPresenceUpdate (callback) {
|
|
this.registerCallback ("Presence", (json) => callback(json[1]))
|
|
}
|
|
/**
|
|
* base 64 encode the authentication credentials and return them
|
|
* these can then be used to login again by passing the object to the connect () function.
|
|
* @see connect () in WhatsAppWeb.Session
|
|
*/
|
|
base64EncodedAuthInfo () {
|
|
return {
|
|
clientID: this.authInfo.clientID,
|
|
serverToken: this.authInfo.serverToken,
|
|
clientToken: this.authInfo.clientToken,
|
|
encKey: this.authInfo.encKey.toString('base64'),
|
|
macKey: this.authInfo.macKey.toString('base64')
|
|
}
|
|
}
|
|
/** Generate a QR code from the ref & the curve public key. This is scanned by the phone */
|
|
generateQRCode ([ref, publicKey, clientID]) {
|
|
const str = ref + "," + publicKey + "," + clientID
|
|
QR.generate(str, {small: true})
|
|
}
|
|
|
|
log (text) {
|
|
console.log (`[Baileys] ${text}"`)
|
|
}
|
|
}
|
|
|
|
/* Import the rest of the code */
|
|
|
|
const recv = require("./WhatsAppWeb.Recv")
|
|
/** Called when a message is recieved on the socket */
|
|
WhatsAppWeb.prototype.onMessageRecieved = recv.onMessageRecieved
|
|
/** The type of notification one recieved */
|
|
WhatsAppWeb.prototype.getNotificationType = recv.getNotificationType
|
|
/** Register for a callback for a certain function, will cancel automatically after one execution */
|
|
WhatsAppWeb.prototype.registerCallbackOneTime = recv.registerCallbackOneTime
|
|
/** Register for a callback for a certain function */
|
|
WhatsAppWeb.prototype.registerCallback = recv.registerCallback
|
|
/** Cancel all further callback events associated with the given parameters */
|
|
WhatsAppWeb.prototype.deregisterCallback = recv.deregisterCallback
|
|
/** Wait for a message with a certain tag to be received */
|
|
WhatsAppWeb.prototype.waitForMessage = recv.waitForMessage
|
|
/** Decode a media message (video, image, document, audio) & save it to the given file */
|
|
WhatsAppWeb.prototype.decodeMediaMessage = recv.decodeMediaMessage
|
|
|
|
const session = require("./WhatsAppWeb.Session")
|
|
WhatsAppWeb.prototype.connect = session.connect
|
|
WhatsAppWeb.prototype.beginAuthentication = session.beginAuthentication
|
|
WhatsAppWeb.prototype.validateNewConnection = session.validateNewConnection
|
|
WhatsAppWeb.prototype.respondToChallenge = session.respondToChallenge
|
|
WhatsAppWeb.prototype.generateKeysForAuth = session.generateKeysForAuth
|
|
WhatsAppWeb.prototype.startKeepAliveRequest = session.startKeepAliveRequest
|
|
WhatsAppWeb.prototype.logout = session.logout
|
|
WhatsAppWeb.prototype.close = session.close
|
|
|
|
const send = require("./WhatsAppWeb.Send")
|
|
/** Send a read receipt to the given ID for a certain message */
|
|
WhatsAppWeb.prototype.sendReadReceipt = send.sendReadReceipt
|
|
/** Tell someone about your presence -- online, typing, offline etc.
|
|
* @see WhatsAppWeb.Presence for all presence types
|
|
*/
|
|
WhatsAppWeb.prototype.updatePresence = send.updatePresence
|
|
/** Send a text message */
|
|
WhatsAppWeb.prototype.sendTextMessage = send.sendTextMessage
|
|
/** Send a contact message */
|
|
WhatsAppWeb.prototype.sendContactMessage = send.sendContactMessage
|
|
/** Send a location message */
|
|
WhatsAppWeb.prototype.sendLocationMessage = send.sendLocationMessage
|
|
/** Send a media message */
|
|
WhatsAppWeb.prototype.sendMediaMessage = send.sendMediaMessage
|
|
/** @private */
|
|
WhatsAppWeb.prototype.sendMessage = send.sendMessage
|
|
/** Generic function for group related queries */
|
|
WhatsAppWeb.prototype.groupQuery = send.groupQuery
|
|
/** Query something from the WhatsApp servers */
|
|
WhatsAppWeb.prototype.query = send.query
|
|
/** @private */
|
|
WhatsAppWeb.prototype.sendBinary = send.sendBinary
|
|
/** @private */
|
|
WhatsAppWeb.prototype.sendJSON = send.sendJSON
|
|
/** @private */
|
|
WhatsAppWeb.prototype.send = send.send
|
|
|
|
const query = require("./WhatsAppWeb.Query")
|
|
/** Query whether a given number is registered on WhatsApp */
|
|
WhatsAppWeb.prototype.isOnWhatsApp = query.isOnWhatsApp
|
|
/** Check the presence of a given person (online, offline) */
|
|
WhatsAppWeb.prototype.requestPresenceUpdate = query.requestPresenceUpdate
|
|
/** Query the status of the person (see groupMetadata() for groups) */
|
|
WhatsAppWeb.prototype.getStatus = query.getStatus
|
|
/** Get the URL to download the profile picture of a person/group */
|
|
WhatsAppWeb.prototype.getProfilePicture = query.getProfilePicture
|
|
/** Query all your contacts */
|
|
WhatsAppWeb.prototype.getContacts = query.getContacts
|
|
/** Query all the people/groups you have a chat history with */
|
|
WhatsAppWeb.prototype.getChats = query.getChats
|
|
/** Query whether your phone is still connected to this WhatsApp Web */
|
|
WhatsAppWeb.prototype.isPhoneConnected = query.isPhoneConnected
|
|
/** Load the conversation with a group or person */
|
|
WhatsAppWeb.prototype.loadConversation = query.loadConversation
|
|
/** Load the entire friggin conversation with a group or person */
|
|
WhatsAppWeb.prototype.loadEntireConversation = query.loadEntireConversation
|
|
/** Get the metadata of the group */
|
|
WhatsAppWeb.prototype.groupMetadata = query.groupMetadata
|
|
/** Create a group */
|
|
WhatsAppWeb.prototype.groupCreate = query.groupCreate
|
|
/** Leave a group */
|
|
WhatsAppWeb.prototype.groupLeave = query.groupLeave
|
|
/** Add somebody to the group */
|
|
WhatsAppWeb.prototype.groupAdd = query.groupAdd
|
|
/** Remove somebody from the group */
|
|
WhatsAppWeb.prototype.groupRemove = query.groupRemove
|
|
/** Make somebody admin on the group */
|
|
WhatsAppWeb.prototype.groupMakeAdmin = query.groupMakeAdmin
|
|
/** Get the invite code of the group */
|
|
WhatsAppWeb.prototype.groupInviteCode = query.groupInviteCode
|
|
|
|
|
|
module.exports = WhatsAppWeb |