Code: Select all
https://web.whatsapp.com
Code: Select all
extension WhatsWebVC: WKScriptMessageHandler {
@objc func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
guard let body = message.body as? [String: Any],
let type = body["type"] as? String,
let data = body["data"] as? [String: Any] else { return }
switch type {
case "messageDeleted":
handleDeletedMessage(data) // This function is not being called
case "mediaMessage":
handleMediaMessage(data)
case "wsReceive":
handleWebSocketMessage(data)
case "wsSend":
print("Outgoing WS message:", data)
default:
print("Unknown message type received:", type)
}
}
}
Hier sind die JavaScript-Code, den ich in WhatsApp-Web inject eingreift: < /p>
Code: Select all
(function() {
let messageCache = new Map();
function extractMessageContent(element) {
let messageContainer = element.querySelector('[data-pre-plain-text]');
let messageText = element.querySelector('.selectable-text');
let mediaContainer = element.querySelector('.media-container');
let timestampElement = element.querySelector('div[data-pre-plain-text]');
let timestamp = '';
let sender = '';
let mediaUrl = '';
let mediaName = '';
if (timestampElement) {
let preText = timestampElement.getAttribute('data-pre-plain-text');
if (preText) {
let matches = preText.match(/\\[(.*?)\\].*?([^:]+):/);
if (matches) {
timestamp = matches[1];
sender = matches[2].trim();
}
}
}
if (mediaContainer) {
let mediaElement = mediaContainer.querySelector('img, video');
if (mediaElement) {
mediaUrl = mediaElement.src;
mediaName = mediaElement.alt || mediaElement.src.split('/').pop();
}
}
return {
id: element.getAttribute('data-id'),
text: messageText ? messageText.innerText : '',
sender: sender,
timestamp: timestamp,
hasMedia: !!mediaContainer,
mediaUrl: mediaUrl,
mediaName: mediaName
};
}
const messageObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'childList') {
mutation.removedNodes.forEach((node) => {
if (node.nodeType === Node.ELEMENT_NODE) {
let messageElement = node.querySelector('[data-id]');
if (messageElement) {
let messageId = messageElement.getAttribute('data-id');
window.webkit.messageHandlers.messageObserver.postMessage({
type: 'messageDeleted',
data: extractMessageContent(messageElement)
});
}
}
});
}
});
});
function observeChat() {
const chatContainer = document.querySelector('#main div.copyable-area');
if (chatContainer) {
messageObserver.observe(chatContainer, {
childList: true,
subtree: true
});
} else {
setTimeout(observeChat, 1000);
}
}
function initObserver() {
if (document.querySelector('#app')) {
observeChat();
} else {
setTimeout(initObserver, 1000);
}
}
initObserver();
})();
- Ein MutationObserver lauscht auf Änderungen im Chat-Container und prüft gezielt wenn Nachrichten entfernt werden.
- Wenn eine Nachricht gelöscht wird, rufe ich window.webkit.messageHandlers.messageObserver.postMessage() auf, um die App mit der Nachricht „messageDeleted“ zu benachrichtigen Geben Sie den Typ und die entsprechende Meldung ein Daten.
[*]Stellen Sie sicher, dass das JavaScript injiziert wird: Ich habe bestätigt, dass das JavaScript ordnungsgemäß in die WKWebView injiziert wird. Der Beobachter löst aus, wenn Elemente aus dem DOM entfernt werden, aber die messageDeleted-Nachricht erreicht nie die Methode userContentController(_:didReceive:) in der iOS-App.
Nachrichtentyp und -daten: Ich habe in der App Druckanweisungen hinzugefügt, um eingehende Nachrichten zu protokollieren, aber der Fall „messageDeleted“ wird nicht ausgelöst, obwohl die WebView führt das korrekt aus JavaScript.
[*]WebView-Konfiguration: Ich stelle sicher, dass der WKUserContentController des WebView ordnungsgemäß für die Verarbeitung von Nachrichten konfiguriert ist :
Code: Select all
let userContentController = WKUserContentController()
userContentController.add(self, name: "messageObserver")
let config = WKWebViewConfiguration()
config.userContentController = userContentController
let webView = WKWebView(frame: .zero, configuration: config)