Repository: HoangTran0410/RevealDeletedFBMessages Branch: master Commit: 26a0b46eba2a Files: 6 Total size: 13.1 KB Directory structure: gitextract_bb13qbde/ ├── README.md ├── content.js ├── inject_websocket.js ├── manifest.json └── popup/ ├── popup.html └── style.css ================================================ FILE CONTENTS ================================================ ================================================ FILE: README.md ================================================ # Reveal Deleted FB Messages Donate? Muốn hỗ trợ mình 1 ly cafe <3 [Donate here](https://github.com/HoangTran0410/HoangTran0410/blob/main/DONATE.md) ## [MỚI] Cài đặt ngay từ [Chrome Webstore](https://chrome.google.com/webstore/detail/reveal-deleted-fb-message/oddpcajnaolfbinffajkacjhohhahlib/related?hl=vi&authuser=1) ![normal](./screenshots/webstore.jpg) Một extension nho nhỏ, giúp mọi người xem lại những tin nhắn đã bị đối phương xóa trong fb messenger. - [Post hướng dẫn tạo Extension này](https://www.facebook.com/groups/j2team.community/posts/1650103925321721/) - [Post giới thiệu v2](https://www.facebook.com/groups/j2team.community/posts/1651683238497123/) *Ý tưởng và Tham khảo code từ [KB2A Tool](https://kb2atool.com/)* ## Cài đặt **Cập nhật**: Extension đã có trên webstore, vào link và cài trực tiếp nhé: [Chrome WebStore](https://chrome.google.com/webstore/detail/reveal-deleted-fb-message/oddpcajnaolfbinffajkacjhohhahlib/related?hl=vi&authuser=1) Hoặc các bạn có thể cài đặt thủ công - B1: **Tải code** về (ấn nút clone - dowload zip) - B2: **Giải nén** file zip vừa tải - B3: Vào trang quản lý extension của trình duyệt bạn dùng, bật **developer mode** (để có thể cài extension từ các nguồn ngoài web store) - B4: **Kéo thả folder** vừa giải nén vào - XONG ## Sử dụng - Khi vào trang facebook hoặc messenger thì **extension sẽ tự chạy** - RVDFM sẽ **lắng nghe và lưu** mọi tin nhắn tới và tin nhắn đi, hoặc khi bạn xem tin nhắn của ai đó RVDFM cũng sẽ lưu cho bạn - Khi có ai đó **thu hồi tin nhắn**, RVDFM sẽ kiểm tra xem tin nhắn đó đã được lưu hay chưa, nếu đã được lưu, RVDFM sẽ hiển thị **nội dung đã lưu** ra cho bạn. - **LƯU Ý**: Hiện tại **chưa đồng bộ** tin nhắn giữa [facebook.com](https://facebook.com) và [messenger.com](https://messenger.com), nên RVDFM sẽ lưu tin nhắn trong 2 trang này 1 cách riêng biệt. ## Cập nhật Lưu ý: Nếu bạn cài tool trước khi có bản cập nhật gần nhất được liệt kê dưới đây, thì bạn nên tải cài lại để có thể dùng những chức năng mới nhất và tránh lỗi nhé. - **15/07/2023**: Fix lỗi "Error when display this message" - **12/07/2023**: Hiển thị nội dung tin nhắn ngay tại vị trí tin thu hồi => Không hiển thị trong giao diện riêng nữa => sẽ giúp bạn biết chính xác ai thu hồi, thời điểm nào, trong đoạn chat nào. - **07/11/2021**: Đã fix lỗi không lưu được tin nhắn sau khi facebook cập nhật - ver 2.1 - **02/09/2021**: Giao diện đẹp hơn, gọn gàng hơn, khung kéo thả tối giản hơn. - **01/09/2021**: [Bài viết](https://www.facebook.com/groups/j2team.community/posts/1651683238497123/) Version 2: Có giao diện ngay trong trang fb, hiển thị mọi loại tin nhắn, prevent XSS, ... - **31/08/2021**: extension đã có giao diện popup riêng. Các bạn ấn vào icon extension là sẽ thấy các tin nhắn bị gỡ. - **30/08/2021**: chức năng cơ bản hoàn thành. Hiển thị tin nhắn trong console. ## Screenshots ### v3 ngày 12/07/2023 - ![v3](./screenshots/new.png) ### v2 ngày 02/09/2021 - Normal - ![normal](./screenshots/normal.png) - Expanded - ![expand](./screenshots/expand.png) - Reveal 1 - ![reveal 1](./screenshots/reveal1.png) - Reveal 2 - ![reveal 2](./screenshots/reveal2.png) ================================================ FILE: content.js ================================================ // ============================= inject websocket code ============================ var inject_ws_script = document.createElement("script"); inject_ws_script.src = chrome.runtime.getURL("./inject_websocket.js"); // Sau khi thêm vào DOM và chạy xong code thì tự xóa dấu vết inject_ws_script.onload = function () { this.parentNode.removeChild(this); }; // // Bắt đầu thêm vào DOM let doc = document.body || document.head || document.documentElement; doc.appendChild(inject_ws_script); ================================================ FILE: inject_websocket.js ================================================ (function () { window.ufs_rvdfm_all_msgs = JSON.parse( localStorage.ufs_rvdfm_all_msgs || "{}" ); if (Array.isArray(window.ufs_rvdfm_all_msgs)) window.ufs_rvdfm_all_msgs = {}; window.addEventListener("beforeunload", () => { localStorage.ufs_rvdfm_all_msgs = JSON.stringify(window.ufs_rvdfm_all_msgs); }); const UfsChatType = { text: "chữ", image: "ảnh", video: "video", gif: "gif", audioclip: "âm thanh", sticker: "sticker", share_location: "vị trí", realtime_location: "vị trí thực", link: "link", reply: "trả lời", add_reaction: "react", remove_reaction: "gỡ react", attachment: "đính kèm", sound: "sound", pending: "pending", user_data: "user_data", delete_msg: "delete_msg", }; window.UfsChatType = UfsChatType; const WebSocketOrig = window.WebSocket; window.WebSocket = function fakeConstructor(dt, config) { const isMsgIdStr = (str) => str?.startsWith?.("mid.$"); // recursive find all array in payload const findArray = (obj) => { let arr = []; for (let key in obj) { if (Array.isArray(obj[key]) && obj[key][0] === 5) { arr.push(obj[key].filter((i) => !Array.isArray(i))); } else if (typeof obj[key] === "object") { arr.push(...findArray(obj[key])); } } return arr; }; const findMessageData = (payload) => { let all_arrays = findArray(payload); // console.log(all_arrays); let result = []; for (let arr of all_arrays) { let all_msg_id = arr.filter( (i) => typeof i === "string" && isMsgIdStr(i) ); let msg_id = all_msg_id[0]; // if (arr[1] === "upsertReaction") { // result.push({ // msg_id, // type: UfsChatType.add_reaction, // data: arr[3], // }); // } // if (arr[1] === "deleteReaction") { // result.push({ // msg_id, // type: UfsChatType.remove_reaction, // }); // } if (arr[1] === "insertAttachmentCta") { if (arr[5] === "xma_live_location_sharing") { if (arr[7]) { result.push({ msg_id, type: UfsChatType.share_location, data: "https://www.google.com/maps/search/" + arr[7], }); } else { result.push({ msg_id, type: UfsChatType.realtime_location, data: arr[6], }); } } if (arr[5] === "xma_web_url") { result.push({ msg_id, type: UfsChatType.link, data: arr[6], }); } } if (arr[1] === "insertStickerAttachment") { result.push({ msg_id, type: UfsChatType.sticker, data: arr[2], }); } if (arr[1] === "insertBlobAttachment") { result.push({ msg_id, type: UfsChatType[arr[2].split("-")[0]], data: arr[4], }); } if (arr[1] === "insertMessage" && !isMsgIdStr(arr[2])) { if (isMsgIdStr(arr[7])) { // result.push({ // msg_id, // type: UfsChatType.reply, // data: { // content: arr[2], // reply_to: arr[7], // }, // }); } else { result.push({ msg_id, type: UfsChatType.text, data: arr[2], }); } } if (arr[1] === "upsertMessage" && arr[2]) { result.push({ msg_id, type: UfsChatType.text, data: arr[2], }); } if (arr[1] === "deleteThenInsertMessage") { let savedMsgData = window.ufs_rvdfm_all_msgs[msg_id]; // notify to content script // if (savedMsgData) { // window.postMessage( // { // type: "ufs_rvdfm_delete_msg", // msg_id, // data: savedMsgData, // }, // "*" // ); // } // result.push({ // msg_id, // type: UfsChatType.delete_msg, // }); } } result = result.map((_) => ({ ..._, saved_time: Date.now() })); return result; }; const saveChatData = (chats) => { for (let c of chats) { window.ufs_rvdfm_all_msgs[c.msg_id] = { data: c.data, type: c.type, // saved_time: c.saved_time, }; } }; // ====== Start hacking ====== let textDecoder = new TextDecoder("utf-8"); const websocket_instant = new WebSocketOrig(dt, config); websocket_instant.addEventListener("message", async function (achunk) { try { const utf8_str = textDecoder.decode(achunk.data); if (utf8_str[0] === "1" || utf8_str[0] === "2" || utf8_str[0] === "3") { const have_msg_id = /(?=mid\.\$)(.*?)(?=\\")/.exec(utf8_str); if (have_msg_id) { let dataStr = utf8_str.slice(utf8_str.indexOf("{")); let data = JSON.parse(dataStr); let payload = JSON.parse(data?.["payload"]); let chats = findMessageData(payload); saveChatData(chats); console.log( "RVDFM - Tất cả tin nhắn lưu được: " + Object.keys(window.ufs_rvdfm_all_msgs)?.length, window.ufs_rvdfm_all_msgs ); } } } catch (e) { console.log("ERROR: ", e); } }); return websocket_instant; }; window.WebSocket.prototype = WebSocketOrig.prototype; window.WebSocket.prototype.constructor = window.WebSocket; })(); window.onload = () => { requireLazy(["MWV2ChatUnsentMessage.react"], (MWV2ChatUnsentMessage) => { const origin = MWV2ChatUnsentMessage.MWV2ChatUnsentMessage; MWV2ChatUnsentMessage.MWV2ChatUnsentMessage = function (a) { if (a) { let outgoing = a.outgoing; let { isUnsent, messageId, threadKey, offlineThreadingId, displayedContentTypes, senderId, } = a.message; if (isUnsent) { let savedMsg = window.ufs_rvdfm_all_msgs[messageId]; a.message.isUnsent = false; a.message.displayedContentTypes = [0, 1]; // text if (savedMsg) { let title = `[Tin thu hồi - ${savedMsg.type}]:\n`; let text = `${savedMsg?.data}`; a.message.text = title + text; } else { a.message.text = "[Tin thu hồi]: -Không có dữ liệu-"; } } } return origin.apply(this, arguments); }; }); }; ================================================ FILE: manifest.json ================================================ { "name": "Reveal Deleted FB Messages", "description": "Xem lại tin nhắn đã gỡ trên fb", "version": "0.0.4", "manifest_version": 3, "action": { "default_title": "Reveal Deleted FB Message", "default_popup": "popup/popup.html", "default_icon": { "16": "icons/icon16.png", "24": "icons/icon24.png", "32": "icons/icon32.png", "48": "icons/icon48.png" } }, "externally_connectable": { "matches": ["*://*.facebook.com/*"] }, "permissions": [], "host_permissions": ["*://*.facebook.com/*"], "content_scripts": [ { "js": ["./content.js"], "matches": ["*://*.facebook.com/*"], "run_at": "document_start" } ], "web_accessible_resources": [ { "resources": [ "inject_websocket.js", "icons/icon16.png", "icons/icon32.png" ], "matches": [""] } ] } ================================================ FILE: popup/popup.html ================================================ Reveal Deleted FB Message

RVDFM
Đọc tin nhắn bị xóa trên FB

Phiên bản mới đã tới 07/2023

Nội dung tin nhắn thu hồi sẽ hiện ngay tại vị trí thu hồi.

Trường hợp bạn vẫn thấy giao diện cũ như hình dưới, thì chỉ cần tải lại trang là được nhé.

Trường hợp Tiện ích thấy tin thu hồi, nhưng chưa kịp lưu nội dung trước đó, thì sẽ hiện lỗi như sau.

Chúc bạn ngày mới vui vẻ ❤️

Xem thêm extension mới ra lò của mình: Useful-script với gần 200 tính năng

Source code công khai tại Github/Hoangtran0410
Thấy hay thì cho mình 1 sao nhé.
Hoặc donate cho mình tại ĐÂY

Made with ❤️ by Hoang Tran

================================================ FILE: popup/style.css ================================================ body { min-height: 200px; width: 400px; background-color: #fff; text-align: center; } p { font-size: 1.2em; } p.highlight { font-weight: bold; background-color: rgb(231, 220, 199); color: rgb(253, 94, 2); } a { text-decoration: none; } .author { font-family: 'Courier New', Courier, monospace; font-size: 1.2em; font-weight: bold; }