Closed pauloboc closed 3 years ago
Do you have any chats open with verified businesses, by any chance?
No, I took the test with 1 chat and 2 groups.
Teste with Whatsapp personal, not the Wpp businesses
try adding try { } catch (e) { }
inside async function
like this
client.on('ready', () => {
getUnreadMsg(client);
});
async function getUnreadMsg(client) {
try {
const allChats = await client.getChats();
console.log(allChats);
} catch (e) {
console.error(e);
}
}
try adding
try { } catch (e) { }
inside async functionlike this
client.on('ready', () => { getUnreadMsg(client); }); async function getUnreadMsg(client) { try { const allChats = await client.getChats(); console.log(allChats); } catch (e) { console.error(e); } }
@Nurutomo TypeError: Cannot read property 'map' of undefined
I'm also experiencing this bug. If I'm executing:
await window.WWebJS.getChats();
On Chromium console, it does find the chats.
I've made a PR some time ago that would probably fix this behaviour. #304
But the problem with that solution was that some people would be already doing a try-catch, so adding a null check in the functions would introduce some breaking changes. Anyway, the PR was closed due to inactivity and I decided in the end to do my own fork which added those changes from the PR.
Note: I do not encourage anyone else to use my fork, because I can't guarantee it will be updated regularly. I'm just using it in a personal project.
Thanks for responding, But the question is why we get this undefine although await window.WWebJS.getChats();
works when I run it in Chromium console.
Is it something with puppeteer?
I don't think @stefanfuchs PR would fix this issue. If it works in chromium, but is returning undefined when being called from puppeteer it mean that some Chats have a property that can't be properly serialized and sent through puppeteer.
This means that one of those chats has some special case that I haven't encountered before. Usually people have resolved It by deleting the specific chat in question, but this isn't ideal and I would like to find the root cause of the issue. If you guys could identify which of your chats is having the issue and maybe even what the difference is, that would be greatly appreciated. I can't find out myself since none of my chats have the issue.
I know of one case where the chat from a verified business account, using the WhatsApp api, from Brazil. I don't know what caused it specifically there.
To track down which chat is having the issue I would try to get each chat, one by one, and see which one has a problem being sent. I wrote this code snippet to find it back then:
const chatIds = await client.pupPage.evaluate(() => {
return window.WWebJS.getChats().map(c => c.id._serialized);
});
let chatCount = 0;
for (let chatId of chatIds) {
const chat = await client.getChatById(chatId);
if (!chat) {
console.log(`Could not serialize chat ${chatId}`);
} else {
chatCount++;
}
}
console.log(`Correctly got ${chatCount} chats`);
Please, if you find which chat has the issue try to identify it and any special things it may have so we can get to a proper solution that's not just deleting the chat.
Ok, I managed to get all chats by using JSON.stringify()
async function getAllChats(client: Client): Promise<Chat[]> {
// @ts-ignore
const chats =await client.pupPage.evaluate(async () => {
// @ts-ignore
const chats = await window.WWebJS.getChats();
return JSON.stringify(chats)
})
return JSON.parse(chats).map((chat: any) => ChatFactory.create(client, chat));
}
But then I got an array of Chats with field id as a string instead of ChatId object, same as groupMetadata.participants.[0].id. It same for me all chats.
Maybe WhatsApp changed the structure of Ids?
@yuvalfis can you try out the code snippet I posted above? JSON serialization has a different structure, and formats IDs this way.
@pedroslopez Yes. I changed it a bit :
const chatIds = await whatsappClient.pupPage.evaluate(async () => {
const chats = await window.WWebJS.getChats();
return chats.map(c => c.id._serialized);
});
let chatCount = 0;
for (let chatId of chatIds) {
try {
const chat = await whatsappClient.getChatById(chatId);
if (!chat) {
console.log(`Could not serialize chat ${chatId}`);
} else {
chatCount++;
}
} catch (e) {
console.log(`Could not serialize chat ${chatId}`, e);
}
}
console.log(`Correctly got ${chatCount} chats`);
and got:
Could not serialize chat 13473313545@c.us TypeError: Cannot read property 'isGroup' of undefined
at Function.create (/Users/yuvalfishler/dev/whatsapp-manger/node_modules/whatsapp-web.js/src/factories/ChatFactory.js:8:17)
at Client.getChatById (/Users/yuvalfishler/dev/whatsapp-manger/node_modules/whatsapp-web.js/src/Client.js:498:28)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at Object.getContext (/Users/yuvalfishler/dev/whatsapp-manger/src/server/getContext.ts:27:26)
at Client.<anonymous> (/Users/yuvalfishler/dev/whatsapp-manger/src/server/whatsapp-server.ts:23:18)
Correctly got 780 chats
chat id 13473313545@c.us -> it is a business account powered by a bot and sends messages as a template with buttons (WhatsappAPI)
thats how it looks like on Chromium console when I print it:
0:
archive: false
changeNumberNewJid: undefined
changeNumberOldJid: undefined
ephemeralDuration: 0
ephemeralSettingTimestamp: 0
formattedTitle: "Luke"
id: e {server: "c.us", user: "13473313545", _serialized: "13473313545@c.us"}
isAnnounceGrpRestrict: undefined
isGroup: false
isMuted: false
isReadOnly: false
labels: undefined
lastReceivedKey: e {fromMe: false, remote: e, id: "9D666B365267BA7080", _serialized: "false_13473313545@c.us_9D666B365267BA7080"}
modifyTag: 872101
msgUnsyncedButtonReplyMsgs: undefined
msgs: (5) [{…}, {…}, {…}, {…}, {…}]
muteExpiration: 0
name: "Luke"
notSpam: true
pendingMsgs: false
pin: 0
t: 1603369374
unreadCount: 0
__proto__: Object
length: 1
__proto__: Array(0
@yuvalfis Great! Could you try to identify which property is having the issue?
The function that takes care of serializing the chat is this: https://github.com/pedroslopez/whatsapp-web.js/blob/3d06babed9b8ea830d63b19f0692a3531310d2f4/src/util/Injected.js#L175-L184
Try eliminating properties that contain data that's unserializable. Some candidates that come to mind could be .msgUnsyncedButtonReplyMsgs
or if maybe messages are the issue, .msgs
.
To remove a property, you can edit that function above and just do something like
delete res.msgUnsyncedButtonReplyMsgs
If messages are indeed the problem (maybe because of the buttons) we may have to do the same thing, getting the messages for the chat and seeing which message has the issue, identify which property has the problem and correct it or remove it from the serialization function (window.WWebJS.getMessageModel()
in this case)
@pedroslopez It looks the problem is in .msgs
But I didn't manage to find window.WWebJS.getMessageModel()
function, any idea?
@pedroslopez It looks the problem is in .msgs
But I didn't manage to find
window.WWebJS.getMessageModel()
function, any idea?
@yuvalfis what version of the library is it? It was introduced in a recent version to fix another issue
@pedroslopez
"whatsapp-web.js": "^1.10.0",
@pedroslopez
"whatsapp-web.js": "^1.10.0",
@yuvalfis weird, should be there. Anyway, it's right here:
@pedroslopez ok I think I found a solution:
I added to window.WWebJS.getChatModel
:
if (res.msgs.length) {
res.msgs = res.msgs.map(msg => msg.buttons ? msg.buttons.serialize() : msg);
}
now it looks like:
window.WWebJS.getChatModel = async chat => {
let res = chat.serialize();
res.isGroup = chat.isGroup;
res.formattedTitle = chat.formattedTitle;
res.isMuted = chat.mute && chat.mute.isMuted;
if (chat.groupMetadata) {
await window.Store.GroupMetadata.update(chat.id._serialized);
res.groupMetadata = chat.groupMetadata.serialize();
}
if (res.msgs.length) {
res.msgs = res.msgs.map(msg => msg.buttons ? msg.buttons.serialize() : msg);
}
return res;
};
Let me know what you think.
@pedroslopez Mabye should add it here as well:
window.WWebJS.getMessageModel = message => {
const msg = message.serialize();
if (msg.buttons) {
msg.buttons = msg.buttons.serialize();
}
delete msg.pendingAckUpdate;
return msg;
};
@yuvalfis We don't really use the .msgs
property on chats, so we could just get rid of it (delete res.msgs
on the serializer function`.
The change in the getMessageModel
function seems good. Can you confirm serializing buttons in this way solves the issue? Please post the result of msg.buttons
and msg.buttons.serialize()
here.
Also, could you try to fetchMessages()
on the chat with the issue before and after applying your fix? Seems like it will work, just want to confirm.
If all this works, please create a pull request with your changes so I can test and merge.
Hi, Ok, no problem. here is console.log before buttons.serialize() and after: Before serializing msg.buttons :
t {_models: Array(1), _index: {…}, _inflight: {…}, modelClass: ƒ, _comparator: ƒ, …}
modelClass: ƒ t()
_cachePolicy: t {_collection: t, _id: "none"}
_comparator: ƒ (e,t)
_index: {0: t}
_inflight: {}
_models: [t]
_resumeOnAvailable: false
_staleCollection: false
isCollection: (...)
length: (...)
models: (...)
__proto__: t
VM62 __puppeteer_evaluation_script__:145
After serializing msg.buttons : [{…}] 0: displayText: "Open listings" id: "0" phoneNumber: undefined selectionId: "https://www.iamluke.us/" subtype: "quick_reply" url: undefined proto: Object length: 1 proto: Array(0)
@pedroslopez when I trying to push a new branch into Github I get this error:
$ git push origin fix/templete-buttons-serialize
ERROR: Permission to pedroslopez/whatsapp-web.js.git denied to yuvalfis.
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
Any idea why?
@pedroslopez when I trying to push a new branch into Github I get this error:
$ git push origin fix/templete-buttons-serialize ERROR: Permission to pedroslopez/whatsapp-web.js.git denied to yuvalfis. fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.
Any idea why?
@yuvalfis you need to fork the repository first, make your changes in your fork, and then create a PR to this repository
@pedroslopez PR: https://github.com/pedroslopez/whatsapp-web.js/pull/402