mirror of
https://github.com/FranP-code/Baileys.git
synced 2025-10-13 00:32:22 +00:00
Rewrite for extensibility & compactness
-This is a break from previous versions unfortunately -Connecting is now a promise -Chats, contacts & previously unread messages are supplied on connection -Groups! -Message confirmations are more reliable -Timeout queries & connections
This commit is contained in:
97
example/ConversationExtract.js
Normal file
97
example/ConversationExtract.js
Normal file
@@ -0,0 +1,97 @@
|
||||
const WhatsAppWeb = require("../WhatsAppWeb")
|
||||
const fs = require("fs")
|
||||
|
||||
/**
|
||||
* Extract all your WhatsApp conversations & save them to a file
|
||||
* produceAnonData => should the Id of the chat be recorded
|
||||
* */
|
||||
function extractChats (authCreds, outputFile, produceAnonData=false, offset=null) {
|
||||
let client = new WhatsAppWeb() // instantiate an instance
|
||||
// internal extract function
|
||||
const extract = function () {
|
||||
let rows = 0
|
||||
let chats = Object.keys(client.chats)
|
||||
let encounteredOffset
|
||||
if (offset) {
|
||||
encounteredOffset = false
|
||||
} else {
|
||||
encounteredOffset = true
|
||||
fs.writeFileSync(outputFile, "chat,input,output\n") // write header to file
|
||||
}
|
||||
|
||||
const extractChat = function (index) {
|
||||
const id = chats[index]
|
||||
if (id.includes("g.us") || !encounteredOffset) { // skip groups
|
||||
if (id === offset) {
|
||||
encounteredOffset = true
|
||||
}
|
||||
if (index+1 < chats.length) {
|
||||
return extractChat(index+1)
|
||||
}
|
||||
return
|
||||
}
|
||||
console.log("extracting for " + id + "...")
|
||||
|
||||
var curInput = ""
|
||||
var curOutput = ""
|
||||
var lastMessage
|
||||
return client.loadEntireConversation (id, m => {
|
||||
var text
|
||||
if (!m.message) { // if message not present, return
|
||||
return
|
||||
} else if (m.message.conversation) { // if its a plain text message
|
||||
text = m.message.conversation
|
||||
} else if (m.message.extendedTextMessage && m.message.extendedTextMessage.contextInfo) { // if its a reply to a previous message
|
||||
const mText = m.message.extendedTextMessage.text
|
||||
const quotedMessage = m.message.extendedTextMessage.contextInfo.quotedMessage
|
||||
// if it's like a '.' and the quoted message has no text, then just forget it
|
||||
if (mText.length <= 2 && !quotedMessage.conversation) {
|
||||
return
|
||||
}
|
||||
// if somebody sent like a '.', then the text should be the quoted message
|
||||
if (mText.length <= 2) {
|
||||
text = quotedMessage.conversation
|
||||
} else { // otherwise just use this text
|
||||
text = mText
|
||||
}
|
||||
} else {
|
||||
return
|
||||
}
|
||||
// if the person who sent the message has switched, flush the row
|
||||
if (lastMessage && !m.key.fromMe && lastMessage.key.fromMe) {
|
||||
|
||||
let row = "" + (produceAnonData ? "" : id) + ",\"" + curInput + "\",\"" + curOutput + "\"\n"
|
||||
fs.appendFileSync (outputFile, row)
|
||||
rows += 1
|
||||
curInput = ""
|
||||
curOutput = ""
|
||||
}
|
||||
|
||||
if (m.key.fromMe) {
|
||||
curOutput += curOutput === "" ? text : ("\n"+text)
|
||||
} else {
|
||||
curInput += curInput === "" ? text : ("\n"+text)
|
||||
}
|
||||
|
||||
lastMessage = m
|
||||
}, 50, false) // load from the start, in chunks of 50
|
||||
.then (() => console.log("finished extraction for " + id))
|
||||
.then (() => {
|
||||
if (index+1 < chats.length) {
|
||||
return extractChat(index+1)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
extractChat(0)
|
||||
.then (() => {
|
||||
console.log("extracted all; total " + rows + " rows")
|
||||
client.logout ()
|
||||
})
|
||||
}
|
||||
client.connect (authCreds)
|
||||
.then (() => extract())
|
||||
.catch (err => console.log("got error: " + error))
|
||||
}
|
||||
let creds = null//JSON.parse(fs.readFileSync("auth_info.json"))
|
||||
extractChats(creds, "output.csv")
|
||||
@@ -1,90 +1,88 @@
|
||||
const WhatsAppWeb = require("../WhatsAppWeb")
|
||||
const fs = require("fs")
|
||||
|
||||
let client = new WhatsAppWeb() // instantiate
|
||||
const client = new WhatsAppWeb() // instantiate
|
||||
client.autoReconnect = true // auto reconnect on disconnect
|
||||
client.logUnhandledMessages = false // set to true to see what kind of stuff you can implement
|
||||
var authInfo = null
|
||||
|
||||
try {
|
||||
const file = fs.readFileSync("auth_info.json") // load a closed session back if it exists
|
||||
const authInfo = JSON.parse(file)
|
||||
client.login( authInfo ) // log back in using the info we just loaded
|
||||
} catch {
|
||||
// if no auth info exists, start a new session
|
||||
client.connect() // start a new session, with QR code scanning and what not
|
||||
}
|
||||
// called once the client connects successfully to the WhatsApp servers
|
||||
client.handlers.onConnected = () => {
|
||||
authInfo = JSON.parse(file)
|
||||
} catch { }
|
||||
|
||||
client.connect (authInfo, 30*1000) // connect or timeout in 30 seconds
|
||||
.then (([user, chats, contacts, unread]) => {
|
||||
console.log ("oh hello " + user.name + " (" + user.id + ")")
|
||||
console.log ("you have " + unread.length + " unread messages")
|
||||
console.log ("you have " + chats.length + " chats & " + contacts.length + " contacts")
|
||||
|
||||
const authInfo = client.base64EncodedAuthInfo() // get all the auth info we need to restore this session
|
||||
fs.writeFileSync("auth_info.json", JSON.stringify(authInfo, null, "\t")) // save this info to a file
|
||||
/*
|
||||
Note: one can take this file and login again from any computer without having to scan the QR code, and get full access to one's WhatsApp
|
||||
Despite the convenience, be careful with this file
|
||||
*/
|
||||
}
|
||||
// called when someone's presence is updated
|
||||
client.handlers.presenceUpdated = (id, type) => {
|
||||
console.log("presence of " + id + " is " + type)
|
||||
}
|
||||
// called when your message gets delivered or read
|
||||
client.handlers.onMessageStatusChanged = (id, messageID, status) => {
|
||||
console.log(id + " acknowledged message '" + messageID + "' status as " + status)
|
||||
}
|
||||
// called when you have a pending unread message or recieve a new message
|
||||
client.handlers.onUnreadMessage = (m) => {
|
||||
// console.log("recieved message: " + JSON.stringify(m)) // uncomment to see what the raw message looks like
|
||||
/* Note: one can take this auth_info.json file and login again from any computer without having to scan the QR code,
|
||||
and get full access to one's WhatsApp. Despite the convenience, be careful with this file */
|
||||
|
||||
const messageType = client.getMessageType(m.message) // get what type of message it is -- text, image, video
|
||||
console.log("got message of type: " + messageType)
|
||||
client.setOnPresenceUpdate (json => console.log(json.id + " presence is " + json.type))
|
||||
client.setOnMessageStatusChange (json => {
|
||||
const participant = json.participant ? " ("+json.participant+")" : "" // participant exists when the message is from a group
|
||||
console.log(json.to + participant +
|
||||
" acknowledged message(s) " + json.ids +
|
||||
" as " + json.type + " at " + json.timestamp)
|
||||
})
|
||||
client.setOnUnreadMessage (m => {
|
||||
const [notificationType, messageType] = client.getNotificationType(m) // get what type of notification it is -- message, group add notification etc.
|
||||
console.log("got notification of type: " + notificationType)
|
||||
|
||||
if (messageType === WhatsAppWeb.MessageType.text) { // if it is plain text
|
||||
const text = m.message.conversation
|
||||
console.log (m.key.remoteJid + " sent: " + text)
|
||||
} else if (messageType === WhatsAppWeb.MessageType.extendedText) { // if it is a quoted thing
|
||||
const text = m.message.extendedTextMessage.text // the actual text
|
||||
const quotedMessage = m.message.extendedTextMessage.contextInfo.quotedMessage // message that was replied to
|
||||
console.log (m.key.remoteJid + " sent: " + text + " and quoted a " + client.getMessageType(quotedMessage))
|
||||
} else { // if it is a media (audio, image, video) message
|
||||
// decode, decrypt & save the media.
|
||||
// The extension to the is applied automatically based on the media type
|
||||
client.decodeMediaMessage(m.message, "media_in_" + m.key.id)
|
||||
.then (meta => console.log(m.key.remoteJid + " sent media, saved at: " + meta.fileName))
|
||||
.catch (err => console.log("error in decoding message: " + err))
|
||||
}
|
||||
console.log("responding...")
|
||||
|
||||
/* send a message after at least a 1 second timeout after recieving a message, otherwise WhatsApp will reject the message otherwise */
|
||||
setTimeout(() => client.sendReadReceipt(m.key.remoteJid, m.key.id), 2*1000) // send a read reciept for the message in 2 seconds
|
||||
setTimeout(() => client.updatePresence(m.key.remoteJid, WhatsAppWeb.Presence.composing), 2.5*1000) // let them know you're typing in 2.5 seconds
|
||||
setTimeout(() => {
|
||||
let promise
|
||||
if (Math.random() > 0.5) { // choose at random
|
||||
promise = client.sendTextMessage(m.key.remoteJid, "hello!", m) // send a "hello!" & quote the message recieved
|
||||
} else {
|
||||
const buffer = fs.readFileSync("./ma_gif.mp4") // load the gif
|
||||
const info = {
|
||||
gif: true, // the video is a gif
|
||||
caption: "hello!" // the caption
|
||||
}
|
||||
promise = client.sendMediaMessage (m.key.remoteJid, buffer, WhatsAppWeb.MessageType.video, info) // send this gif!
|
||||
if (notificationType !== "message") {
|
||||
return
|
||||
}
|
||||
promise.then (([m, q]) => {
|
||||
const success = m.status === 200
|
||||
const messageID = q[2][0][2].key.id
|
||||
console.log("sent message with ID '" + messageID + "' successfully: " + success)
|
||||
})
|
||||
|
||||
}, 4*1000) // send after 4 seconds
|
||||
}
|
||||
|
||||
// called if an error occurs
|
||||
client.handlers.onError = (err) => console.log(err)
|
||||
client.handlers.onDisconnect = () => { /* internet got disconnected, save chats here or whatever; will reconnect automatically */ }
|
||||
|
||||
const readline = require('readline').createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
let sender = m.key.remoteJid
|
||||
if (m.key.participant) { // participant exists if the message is in a group
|
||||
sender += " ("+m.key.participant+")"
|
||||
}
|
||||
if (messageType === WhatsAppWeb.MessageType.text) {
|
||||
const text = m.message.conversation
|
||||
console.log (sender + " sent: " + text)
|
||||
} else if (messageType === WhatsAppWeb.MessageType.extendedText) {
|
||||
const text = m.message.extendedTextMessage.text
|
||||
console.log (sender + " sent: " + text + " and quoted message: " + JSON.stringify(m.message))
|
||||
} else { // if it is a media (audio, image, video) message
|
||||
// decode, decrypt & save the media.
|
||||
// The extension to the is applied automatically based on the media type
|
||||
client.decodeMediaMessage(m.message, "media_in_" + m.key.id)
|
||||
.then (meta => console.log(sender + " sent media, saved at: " + meta.fileName))
|
||||
.catch (err => console.log("error in decoding message: " + err))
|
||||
}
|
||||
// send a reply after 3 seconds
|
||||
setTimeout (() => {
|
||||
client.sendReadReceipt (m.key.remoteJid, m.key.id) // send read receipt
|
||||
.then (() => client.updatePresence(m.key.remoteJid, WhatsAppWeb.Presence.available)) // tell them we're available
|
||||
.then (() => client.updatePresence(m.key.remoteJid, WhatsAppWeb.Presence.composing)) // tell them we're composing
|
||||
.then (() => { // send the message
|
||||
if (Math.random() > 0.5) { // choose at random
|
||||
return client.sendTextMessage(m.key.remoteJid, "hello!", m) // send a "hello!" & quote the message recieved
|
||||
} else {
|
||||
const buffer = fs.readFileSync("./ma_gif.mp4") // load the gif
|
||||
const info = {
|
||||
gif: true, // the video is a gif
|
||||
caption: "hello!" // the caption
|
||||
}
|
||||
return client.sendMediaMessage (m.key.remoteJid, buffer, WhatsAppWeb.MessageType.video, info) // send this gif!
|
||||
}
|
||||
})
|
||||
.then (([m, q]) => { // check if it went successfully
|
||||
const success = m.status === 200
|
||||
const messageID = q[2][0][2].key.id
|
||||
console.log("sent message with ID '" + messageID + "' successfully: " + success)
|
||||
})
|
||||
}, 3*1000)
|
||||
})
|
||||
/* custom functionality for tracking battery */
|
||||
client.registerCallback (["action", null, "battery"], json => {
|
||||
const batteryLevelStr = json[2][0][1].value
|
||||
const batterylevel = parseInt (batteryLevelStr)
|
||||
console.log ("battery level: " + batterylevel)
|
||||
})
|
||||
client.setOnUnexpectedDisconnect (err => console.log ("disconnected unexpectedly: " + err) )
|
||||
})
|
||||
readline.question("type exit to disconnect\n", (txt) => {
|
||||
if (txt === "exit") {
|
||||
client.close()
|
||||
process.exit(0)
|
||||
}
|
||||
})
|
||||
.catch (err => console.log ("encountered error: " + err))
|
||||
Reference in New Issue
Block a user