Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I am not getting the contact names in WhatsApp after logging in for the second time. #1259

Open
JaydeepVasundhara1 opened this issue Feb 17, 2025 · 2 comments
Labels
bug Something isn't working

Comments

@JaydeepVasundhara1
Copy link

JaydeepVasundhara1 commented Feb 17, 2025

Below is my code. When I scan the QR code in WhatsApp, it gives me all contact names correctly. However, when I log out and log in again, it does not provide any contact names —only the group names are displayed properly.

This is the code

const express = require('express');
const cors = require('cors');

const app = express();
const port = 8080;
app.use(cors());
app.use(express.json());

const ConnectionStatus = Object.freeze({
connected: "connected",
notConnected: "notConnected",
notStart: "notStart"
});

let status = ConnectionStatus.notStart;
let qrCodeString = "";

const { Mutex } = require('async-mutex');
const messageMutex = new Mutex();

let messageArray = [];

// GET API to check current connection status
app.get('/status', async (req, res) => {
console.log(status getStatus api ${status});
if (status === ConnectionStatus.notStart) {
status = ConnectionStatus.notConnected
uniqueName = session_${Date.now()};
connectToWhatsApp()
}else if (status === ConnectionStatus.notConnected) {
res.json(
{
status: status,
type: "qr",
qrCode: qrCodeString
}
);
}else {
if (messageArray.length > 0) {
// const release = await messageMutex.acquire();
let oldMessage = [...messageArray]; // Clone the array to avoid reference issues
messageArray = [];
// release()
res.json(
{
status: status,
messageArray: oldMessage
}
);
}else {
res.json(
{
status: status
}
);
}
}
});

// API to trigger event
app.post('/sendMessage', async (req, res) => {
const { senderNumber, messageContent } = req.body;

// Input validation
if (!senderNumber || !messageContent) {
    return res.status(400).json({
        success: false,
        message: 'senderNumber and messageContent are required fields.'
    });
}

try {
    console.log(`Message will be sent to ${senderNumber}: ${messageContent}`);

    const message = {
        to: senderNumber,  // The recipient's number (with country code, e.g., '1234567890@c.us' for individual or 'groupID@g.us' for group)
        message: {
            text: messageContent // Explicitly define the message type as text
        }
    };

    // Send the message using your WhatsApp service
    await sock.sendMessage(message.to, message.message);

    // Respond with a success status
    res.json({
        success: true,
        message: 'Message successfully sent!',
        data: {
            to: senderNumber,
            messageContent: messageContent
        }
    });
} catch (error) {
    // Log the error for debugging
    console.error('Error sending message:', error);

    // Respond with a failure status and error details
    res.status(500).json({
        success: false,
        message: 'Failed to send message.',
        error: error.message // Provide the error message for debugging
    });
}

});

app.listen(port, () => {
console.log(Server running on http://localhost:${port});
});

// -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

const { default: makeWASocket, DisconnectReason, useMultiFileAuthState, fetchLatestBaileysVersion, downloadContentFromMessage, makeInMemoryStore} = require('@whiskeysockets/baileys');
const e = require('express');
const fs = require('fs');
const path = require('path');

let connectedClients = [];

let sock = null; // Global variable to store the WhatsApp socket
let store = makeInMemoryStore({}); // Store for chats, messages, and contacts

async function sendMessageToWhatsApp(senderNumber, messageContent) {
try {
console.log(Message will be sent to ${senderNumber}: ${messageContent});

    const message = {
        to: senderNumber,  // The recipient's number (with country code, e.g., '1234567890@c.us' for individual or 'groupID@g.us' for group)
        message: {
            text: messageContent // Explicitly define the message type as text
        }
    };

    // Send the message
    await sock.sendMessage(message.to, message.message);
    console.log(`Message sent to ${senderNumber}: ${messageContent}`);
} catch (error) {
    console.error('Error sending message:', error);
}

}

// Function to download media
async function downloadMedia(message, type) {
const stream = await downloadContentFromMessage(message, type);
let buffer = Buffer.from([]);
for await (const chunk of stream) {
buffer = Buffer.concat([buffer, chunk]);
}
return buffer;
}

async function saveMediaToFile(buffer, filename) {
fs.writeFileSync(filename, buffer);
}

let uniqueName = session_${Date.now()};
let oldUname = '';

// Function to handle authentication state
async function setupAuthState() {
oldUname = uniqueName;
const { state, saveCreds } = await useMultiFileAuthState(uniqueName);
return { state, saveCreds };
}

async function connectToWhatsApp() {
try {

    console.log("Called-=--->>> 175");

    const { state, saveCreds } = await setupAuthState();
    const { version, isLatest } = await fetchLatestBaileysVersion();
    console.log(`Using Baileys version: ${version}, is latest: ${isLatest}`);

    sock = makeWASocket({
        auth: state,
        printQRInTerminal: true,
        version,
        syncFullHistory: true
    });

    // Bind the store to the socket
    store.bind(sock.ev);

    sock.ev.on('creds.update', saveCreds);

    sock.ev.on('messaging-history.set', async ({chats, contact, message}) => {
        console.log(`history contacts =====> ${contact}`);
    }); 

    sock.ev.on('contacts.upsert', (contacts) => {
        console.log('Contacts updated:', contacts);
    })

    sock.ev.on('contacts.update', (contacts) => {
        console.log('Contacts updated:', contacts);
    });


    sock.ev.on('connection.update', (update) => {
        const { qr,connection, lastDisconnect } = update;
        console.log("update===>>>",update);

        qrCodeString = qr

        if (connection === 'close') {
            const shouldReconnect = (lastDisconnect?.error?.output?.statusCode !== DisconnectReason.loggedOut) && lastDisconnect?.error?.output?.statusCode !== 401;
            console.log('Connection closed due to', lastDisconnect?.error, ', reconnecting', shouldReconnect);

            if (lastDisconnect?.error?.output?.statusCode === 401 || lastDisconnect?.error?.message.includes('Connection Failure')) {
                console.log('Unauthorized or connection failure. Re-authentication needed.');
                // Clear the auth state to reset QR code scan
                console.log("Called-=--->>> 208", oldUname);
                fs.rmSync(oldUname, { recursive: true, force: true });
                uniqueName = `session_${Date.now()}`;
                connectToWhatsApp();
            } else if (shouldReconnect) {
                console.log("Called-=--->>> 212");
                connectToWhatsApp();
            }
            status = ConnectionStatus.notConnected
        } else if (connection === 'open') {
            console.log('Opened connection');
            status = ConnectionStatus.connected
            // sock.end('Reload user detail')
            getAllHistory();
        }
    });

} catch (error) {
    console.error('Error connecting to WhatsApp:', error);
}

}

async function getContectList(remoteJid) {
try {
console.log("getContectList ====================> start");
if (!store) {
console.log("getContectList: store is not initialized", store);
return "Unknown";
}

    // Wait for store to be populated with contacts and chats
    await new Promise(resolve => {
        const checkStore = setInterval(() => {
            if (Object.keys(store.contacts).length > 0) {
                clearInterval(checkStore);
                resolve();
            }
        }, 1000); // Check every second if store is populated
    });

    // Fetch the specific contact by remoteJid
    const contact = store.contacts[remoteJid];
    if (contact) {
        // Return the contact name if available, otherwise return "Unknown"
        return contact.name || contact.notify || "Unknown";
    } else {
        console.log(`No contact found for JID: ${remoteJid}`);
        return "Unknown";
    }
} catch (error) {
    console.error('Error fetching contact:', error);
    return "Unknown";
}

}

async function getAllHistory() {
try {

    console.log("getAllHistory ====================> strat");

    if (!store) {
        console.log("getAllHistory : store", store);
        return;
    }

    // Wait for store to be populated with contacts and chats
    await new Promise(resolve => {
        const checkStore = setInterval(() => {
            if (Object.keys(store.contacts).length > 0 && Object.keys(store.chats).length > 0) {
                clearInterval(checkStore);
                resolve();
            }
        }, 1000); // Check every second if store is populated
    });

    // Fetch all contacts
    const contacts = store.contacts;
    console.log("All Contacts:", contacts);

    const messages = store.messages;
    const entries = Object.entries(messages);
    const filteredEntries = entries.filter(([key, value]) => 
        value.array.length > 0 &&
        value.array.some(
            (message) =>
                message.message?.extendedTextMessage?.text || 
                message.message?.conversation
        )
    );
    const reversedEntries = filteredEntries.slice(0, 10).reverse();

    for (const [key, value] of reversedEntries) {
        console.log(`Key start ===========>: ${key}`);


        if (value.array.length > 0 && 
            value.array.some(
                (message) =>
                    message.message?.extendedTextMessage?.text || 
                    message.message?.conversation
            )
        ) {
            // Proceed with the loop
        } else {
            continue; // Skip if conditions are not met
        }      
        
        let allSingleMessage = [];

        const firstMessage = value.array[0]; // Take first message as reference
        const senderNumber = firstMessage.key.remoteJid; // Sender's number

        let isPersonal = false;
        let titleName = "N/A";
        let profilePictureUrl = "";
    
        if (senderNumber.includes('@g.us')) {
            const groupId = senderNumber.split('@')[0]; // Extract group ID
    
            try {
                const groupMetadata = await sock.groupMetadata(groupId + '@g.us');
                titleName = groupMetadata.subject;
                isPersonal = false; // It's a group message
            } catch (err) {
                console.error('Error fetching group metadata:', err);
            }
        } else {
            isPersonal = true;
            titleName = await getContectList(senderNumber);
        }
    
        try {
            profilePictureUrl = await sock.profilePictureUrl(senderNumber);
            console.log('Profile Picture URL:', profilePictureUrl);
        } catch (error) {
            console.log('Profile Picture URL: not found');
        }        
        
        for (const message of value.array) {
            const timestamp = message.messageTimestamp.low * 1000;
            const date = new Date(timestamp);            
            // Format date and time
            const formattedDate = date.toLocaleDateString(); // Example: "2/14/2025"
            const formattedTime = date.toLocaleTimeString(); // Example: "10:30:15 AM"
            console.log('Key message array time ===>', formattedDate, formattedTime);


            if (message.message) {
                if (message.message?.extendedTextMessage?.text || message.message?.conversation) {
                    const isFromMe = message.key.fromMe; // Check if the message is from you
                    const senderName = message.pushName; // Get the sender's name
    
                    let messageContent = ''; // To store the message content

                    // Check if it's a conversation message (normal text message)
                    if (message.message.conversation) {
                        messageContent = message.message.conversation;
                    }
                    // Check if it's an extended text message (text with more details)
                    else if (message.message.extendedTextMessage) {
                        messageContent = message.message.extendedTextMessage.text;
                    }
                    // Check if it's a group message
                    else if (message.message.senderKeyDistributionMessage) {
                        messageContent = message.message.conversation;
                    }
            
                    // Print the details in the console
                    // console.log('Is Personal:', isPersonal);
                    console.log('titleName:', titleName || 'N/A');
                    // console.log('Sender Name:', senderName || 'N/A');
                    // console.log('Sent by Me:', isFromMe);
                    // console.log('Message:', messageContent);
                    // console.log('Remote Jid:', senderNumber);
    
                    const messageNew = {
                        type: 'messageDetails',
                        isPersonal: isPersonal,
                        titleName: titleName || 'N/A',
                        senderName: senderName || 'N/A',
                        isSentByMe: isFromMe,
                        data: messageContent,
                        remoteJid: senderNumber,
                        profilePictureUrl: profilePictureUrl
                    };
                    allSingleMessage.push(messageNew);
                }
            }
        }

        messageArray.push(...allSingleMessage);
    
        console.log(`<=========== Key End : ${key}`);
    }

    // Listen for new status updates
    sock.ev.on('messages.upsert', async ({ messages, type }) => {

        messages.forEach(async message => {
            if (message.message) {
                const isFromMe = message.key.fromMe; // Check if the message is from you
                const senderNumber = message.key.remoteJid; // Get the sender's number
                const senderName = message.pushName; // Get the sender's name

                if (senderNumber && senderNumber.includes('@newsletter')) {
                    console.log('Message from @newsletter detected. Skipping...');
                    return; 
                }            

                let messageContent = ''; // To store the message content
                let isPersonal = false;
                let titleName = "N|A"

                // Check if it's a conversation message (normal text message)
                if (message.message.conversation) {
                    messageContent = message.message.conversation;
                    isPersonal = true; // It's a personal message
                    titleName = await getContectList(senderNumber);
                }
                // Check if it's an extended text message (text with more details)
                else if (message.message.extendedTextMessage) {
                    messageContent = message.message.extendedTextMessage.text;
                    isPersonal = true; // It's a personal message
                    titleName = await getContectList(senderNumber);
                }
                // Check if it's a group message
                else if (message.message.senderKeyDistributionMessage) {
                    messageContent = message.message.conversation;
                }

                // Check if it's a group message (remoteJid contains @g.us)
                if (senderNumber.includes('@g.us')) {
                    // It's a group message, so we need to get the group name
                    const groupId = senderNumber.split('@')[0]; // Extract group ID from the remoteJid

                    // Fetch group metadata to get the group name
                    try {
                        const groupMetadata = await sock.groupMetadata(groupId + '@g.us');
                        titleName = groupMetadata.subject; // Get the group name
                        isPersonal = false; // It's a group message
                    } catch (err) {
                        console.error('Error fetching group metadata:', err);
                    }
                }

                // Print the details in the console
                console.log('Is Personal:', isPersonal);
                console.log('titleName:', titleName || 'N/A');
                console.log('Sender Name:', senderName || 'N/A');
                console.log('Sent by Me:', isFromMe);
                console.log('Message:', messageContent);
                console.log('Remote Jid:', senderNumber);

                // Retrieve the profile picture URL
                // const profilePictureUrl = await sock.profilePictureUrl(senderNumber) || '';

                let profilePictureUrl = ''
                try {
                    profilePictureUrl = await sock.profilePictureUrl(senderNumber);
                    console.log('Profile Picture URL:', profilePictureUrl);
                } catch (error) {
                    console.log('Profile Picture URL: not get error');
                }

                const messageNew = {
                    type: 'messageDetails',
                    isPersonal: isPersonal,
                    titleName: titleName || 'N/A',
                    senderName: senderName || 'N/A',
                    isSentByMe: isFromMe,
                    data: messageContent,
                    remoteJid: senderNumber,
                    profilePictureUrl: profilePictureUrl
                };
                messageArray.push(messageNew);
            }
        });

    });

} catch (error) {
    console.error('Error fetching history:', error);
}

}

status = ConnectionStatus.notConnected
uniqueName = session_${Date.now()};
connectToWhatsApp()

@JaydeepVasundhara1 JaydeepVasundhara1 added the bug Something isn't working label Feb 17, 2025
@JaydeepVasundhara1
Copy link
Author

Image

@zulfio
Copy link

zulfio commented Feb 20, 2025

me too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants