master 26a0b46eba2a cached
6 files
13.1 KB
3.9k tokens
1 requests
Download .txt
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": ["<all_urls>"]
    }
  ]
}


================================================
FILE: popup/popup.html
================================================
<!DOCTYPE html>
<html lang="en" dir="ltr">

<head>
    <meta charset="utf-8">
    <title>Reveal Deleted FB Message</title>

    <link rel="stylesheet" href="style.css">
</head>

<body>
    <h2>RVDFM<br />Đọc tin nhắn bị xóa trên FB</h2>

    <p class="highlight">Phiên bản mới đã tới 07/2023</p>
    <p class="highlight">Nội dung tin nhắn thu hồi sẽ hiện ngay tại vị trí thu hồi.</p>
    <img src="../screenshots/new.png" alt="" style="width:250px">

    <p>Trường hợp bạn vẫn thấy giao diện cũ như hình dưới, thì chỉ cần <b>tải lại trang</b> là được nhé.</p>
    <img src="../screenshots/new-fail.png" alt="" style="width: 250px;">

    <p>Trường hợp Tiện ích thấy tin thu hồi, nhưng <b>chưa kịp lưu nội dung</b> trước đó, thì sẽ hiện lỗi như sau.</p>
    <img src="../screenshots/new-fail2.png" alt="" style="width: 250px;">

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

    <p class="highlight">
        Xem thêm extension mới ra lò của mình:
        <a href="https://www.facebook.com/groups/1154059318582088" target="_blank">Useful-script</a>
        với gần 200 tính năng
    </p>

    <p class="highlight">
        Source code công khai tại
        <a href="https://github.com/HoangTran0410/RevealDeletedFBMessages" target="_blank">Github/Hoangtran0410</a>
        <br />Thấy hay thì cho mình 1 sao nhé.
        <br />Hoặc donate cho mình tại
        <a href="https://github.com/HoangTran0410/HoangTran0410/blob/main/DONATE.md" target="_blank">ĐÂY</a>
    </p>

    <p class="author">
        Made with ❤️ by <a href="https://www.facebook.com/99.hoangtran/" target="_blank">Hoang Tran</a>
    </p>
</body>

</html>

================================================
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;
}
Download .txt
gitextract_bb13qbde/

├── README.md
├── content.js
├── inject_websocket.js
├── manifest.json
└── popup/
    ├── popup.html
    └── style.css
Condensed preview — 6 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (15K chars).
[
  {
    "path": "README.md",
    "chars": 3159,
    "preview": "# Reveal Deleted FB Messages\n\nDonate? Muốn hỗ trợ mình 1 ly cafe <3 [Donate here](https://github.com/HoangTran0410/Hoang"
  },
  {
    "path": "content.js",
    "chars": 487,
    "preview": "// ============================= inject websocket code ============================\nvar inject_ws_script = document.crea"
  },
  {
    "path": "inject_websocket.js",
    "chars": 6913,
    "preview": "(function () {\n  window.ufs_rvdfm_all_msgs = JSON.parse(\n    localStorage.ufs_rvdfm_all_msgs || \"{}\"\n  );\n\n  if (Array.i"
  },
  {
    "path": "manifest.json",
    "chars": 893,
    "preview": "{\n  \"name\": \"Reveal Deleted FB Messages\",\n  \"description\": \"Xem lại tin nhắn đã gỡ trên fb\",\n  \"version\": \"0.0.4\",\n  \"ma"
  },
  {
    "path": "popup/popup.html",
    "chars": 1615,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\" dir=\"ltr\">\n\n<head>\n    <meta charset=\"utf-8\">\n    <title>Reveal Deleted FB Message</titl"
  },
  {
    "path": "popup/style.css",
    "chars": 384,
    "preview": "body {\n    min-height: 200px;\n    width: 400px;\n    background-color: #fff;\n    text-align: center;\n}\n\np {\n    font-size"
  }
]

About this extraction

This page contains the full source code of the HoangTran0410/RevealDeletedFBMessages GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 6 files (13.1 KB), approximately 3.9k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!