Skip to content

Instantly share code, notes, and snippets.

@beebeo
Last active November 23, 2025 17:01
Show Gist options
  • Select an option

  • Save beebeo/41a9224d7d2eb701bf424809c885d8e9 to your computer and use it in GitHub Desktop.

Select an option

Save beebeo/41a9224d7d2eb701bf424809c885d8e9 to your computer and use it in GitHub Desktop.
Disable future "Seen" and "Typing" in the Facebook Messenger
var uid = window.require('CurrentUserInitialData').ACCOUNT_ID
window.requireLazy(['MWV2ChatText.bs', 'MqttProtocolClient'], (MWV2ChatText, protocolClient) => {
const publish = protocolClient.prototype.publish
protocolClient.prototype.publish = function () {
let args = arguments[1]
let data = safeParse(args)
if (args && data) {
if (opt.block_typing && data.type === 4 && data.payload && data.payload.includes('is_typing')) {
data.payload = safeParse(data.payload)
data.payload.payload = safeParse(data.payload.payload)
data.payload.payload.is_typing = false
data.payload.payload = JSON.stringify(data.payload.payload)
data.payload = JSON.stringify(data.payload)
}
if (opt.block_seen && data.type === 3 && data.payload && data.payload.includes('last_read_watermark_ts')) {
data.payload = safeParse(data.payload)
if (data.payload.tasks.length === 1) {
data.payload.tasks.map(task => {
task.payload = safeParse(task.payload)
task.payload.thread_id = uid
task.payload = JSON.stringify(task.payload)
return task
})
}
data.payload = JSON.stringify(data.payload)
}
data = JSON.stringify(data)
arguments[1] = data
}
return publish.apply(this, arguments)
}
})
var opt = {
block_seen: true,
block_typing: true
}
var WebSocketProxy = new Proxy(window.WebSocket, {
construct: function (target, args) {
const instance = new target(...args)
const openHandler = event => {}
const messageHandler = event => {}
const closeHandler = event => {
instance.removeEventListener('open', openHandler)
instance.removeEventListener('close', closeHandler)
instance.removeEventListener('message', messageHandler)
}
const sendProxy = new Proxy(instance.send, {
apply: function (target, thisArg, args) {
let a = new Uint8Array(args[0])
if (!a || a.length < 100 || 1500 < a.length) return target.apply(thisArg, args)
let data = new TextDecoder().decode(a)
if (opt.block_typing && data.includes('"type":4') && data.includes('\\"label\\":\\"3\\"') && data.includes('is_typing')) return
if (opt.block_seen && data.includes('"type":3') && data.includes('\\"label\\":\\"21\\"') && !data.includes('\\"label\\":\\"46\\"') && data.includes('last_read_watermark_ts')) {
let text = ''
a.map(e => (text += String.fromCharCode(e)))
let regfex = /\\\\\\"thread_id\\\\\\":[0-9]+,\\\\\\"last_read/g
let matches = text.match(regfex)
if (matches) {
matches.forEach(e => {
var thread_id = e.match(/[0-9]+/g)?.[0] || ''
thread_id = 15 < thread_id.length ? '1000000000000000' : uid
text = text.replace(e, `\\\\\\"thread_id\\\\\\":${thread_id},\\\\\\"last_read`)
})
args[0] = new Uint8Array(text.split('').map(e => e.charCodeAt(0)))
}
}
target.apply(thisArg, args)
}
})
instance.send = sendProxy
instance.addEventListener('open', openHandler)
instance.addEventListener('close', closeHandler)
instance.addEventListener('message', messageHandler)
return instance
}
})
window.WebSocket = WebSocketProxy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment