🔪 Facebook Messenger to email bridge based on reverse engineered auth and GraphQL APIs.

Related tags

GraphQLunzuckify
Overview

Unzuckify

This repository has a small Python application which allows me to receive an email notification when somebody sends me a Facebook message.

Why?

I don't like Facebook as a company, and I don't want to support them by using their products, including Messenger. However, when I came around to this point of view, I already had a number of existing contacts on Messenger. I migrated everyone I talked to regularly onto other platforms, but in case someone messaged me out of the blue, I still wanted to know about that, so I could redirect them onto Signal or SMS.

With the help of this application, I can make sure I won't miss it when a very old contact happens to message me on Facebook, while not having to ever actively check Messenger or keep it on my phone.

How?

I reverse-engineered the Messenger authentication flow and the recently rewritten GraphQL API, and created a command-line utility that can, in the same manner as the browser:

  • Fetch the list of threads that would show up on Messenger, their names, the users in each thread, the last message that was sent, who sent it, and whether it is unread according to the server.
  • Send a message to a thread.
  • Mark a thread as read if it is unread.

This all turned out to be fairly straightforward. The protocol and code is obfuscated, but nowhere near enough to foil basic reverse engineering techniques.

After creating the command-line utility, I wrote a Bash script that wrapped it with the following logic:

  1. Fetch my list of threads.
  2. Identify any threads that have unread messages and use SendGrid to notify me about them via email.
  3. Mark those threads as read.
  4. Login to a separate Facebook account and send my primary account a random inspirational quote by direct message.
  5. In step 2, the notifications for messages from the account in step 4 are sent to a separate email address that is monitored by Dead Man's Snitch. This, combined with step 4, ensures that as long as everything is in working order, Dead Man's Snitch will get an email every time I run the script.

Then I run the script on a cron job every few hours. If I get a message, it's forwarded to email. If the API changes out from under me, or something else goes wrong, I also get an email because Dead Man's Snitch will stop receiving notifications.

Prior work

I previously used Messenger Mirror to accomplish the same thing as this project. However, because Messenger Mirror relied on having an entire Chrome instance running in Selenium 24/7, I didn't want to have that running on my laptop (it would eat resources for no good reason). Unfortunately, after a couple weeks, Facebook banned the IP for my VPS, so I couldn't run the application there anymore. This is what inspired me to try reverse engineering the browser API directly, since if I did that, it would be far less resource intensive to run the application on my laptop in the background.

Setup

If you just want to use the CLI (perhaps as proof of concept for developing your own Messenger client using the reverse engineered API), setup is quite simple. Install Poetry, run poetry install and poetry shell, then you are good to go:

% ./unzuckify.py -u [email protected] -p your-password -v inbox
% ./unzuckify.py -u [email protected] -p your-password -v send
    -t thread-id-from-inbox -m "Some text message"
% ./unzuckify.py -u [email protected] -p your-password -v read
    -t thread-id-from-inbox

Cookies are automatically cached in ~/.cache/unzuckify/cookies.json, and are separated per email address so you can use different accounts in parallel. Omit -v to not log all the intermediate debugging info. Only inbox prints to stdout, and the output is JSON.

If you additionally want to set up a Messenger-to-email bridge like I have, then you should install jq and sign up for a free SendGrid account. Also go to Heroku, provision a Dead Man's Snitch addon, and get the email endpoint for the snitch. Then create a .env file in the repo as follows:

[email protected]  # facebook login
PRIMARY_PASSWORD='your-password'

[email protected]  # 2nd account login
SECONDARY_PASSWORD='other-password'

SENDGRID_API_KEY=SG.REDACTED  # from SendGrid
[email protected]  # from Dead Man's Snitch
SENTINEL_NAME='John Smith'  # Facebook name of 2nd account

[email protected]  # SendGrid verified sender
[email protected]  # where to receive notifications

Note for FROM_EMAIL, ideally you own a domain and can prove ownership of it, and this email is on that domain. According to the SendGrid documentation, if you use something like a Gmail address, your notifications are likely to get flagged by spam filters because it can be proven that Gmail was not actually the one to send the email, which looks suspicious. If you don't own a personal domain, may I suggest doing business with Namecheap and Forward Email?

Now you just need to set up the script to run on a semi-regular basis, for example by creating a cron job:

crontab - <<"EOF"
0 */3 * * * sh -c '. "$HOME/.profile" && ~/dev/unzuckify/unzuckify.bash'
EOF
Owner
Radon Rosborough
Software engineer recently graduated from Harvey Mudd College studying computer science. Interests include package management and Emacs, or both at once.
Radon Rosborough
A Python dependency resolver

python-resolver A Python dependency resolver. Issues Only supports wheels (no sdists!) Usage Python library import packaging.requirements import resol

Filipe Laíns 19 Jun 29, 2022
Simple GraphQL client for Python 2.7+

python-graphql-client Simple GraphQL client for Python 2.7+ Install pip install graphqlclient Usage from graphqlclient import GraphQLClient client =

Prisma Labs 150 Nov 29, 2022
Ariadne is a Python library for implementing GraphQL servers using schema-first approach.

Ariadne Ariadne is a Python library for implementing GraphQL servers. Schema-first: Ariadne enables Python developers to use schema-first approach to

Mirumee Labs 1.9k Jan 01, 2023
Graphene MongoEngine integration

Graphene-Mongo A Mongoengine integration for Graphene. Installation For installing graphene-mongo, just run this command in your shell pip install gra

GraphQL Python 261 Dec 31, 2022
A library to help construct a graphql-py server supporting react-relay

Relay Library for GraphQL Python GraphQL-relay-py is the Relay library for GraphQL-core. It allows the easy creation of Relay-compliant servers using

GraphQL Python 143 Nov 15, 2022
MGE-GraphQL is a Python library for building GraphQL mutations fast and easily

MGE-GraphQL Introduction MGE-GraphQL is a Python library for building GraphQL mutations fast and easily. Data Validations: A similar data validation w

MGE Software 4 Apr 23, 2022
GraphQL is a query language and execution engine tied to any backend service.

GraphQL The GraphQL specification is edited in the markdown files found in /spec the latest release of which is published at https://graphql.github.io

GraphQL 14k Jan 01, 2023
ASGI support for the Tartiflette GraphQL engine

tartiflette-asgi is a wrapper that provides ASGI support for the Tartiflette Python GraphQL engine. It is ideal for serving a GraphQL API over HTTP, o

tartiflette 99 Dec 27, 2022
GraphQL security auditing script with a focus on performing batch GraphQL queries and mutations

BatchQL BatchQL is a GraphQL security auditing script with a focus on performing batch GraphQL queries and mutations. This script is not complex, and

Assetnote 267 Dec 24, 2022
A new GraphQL library for Python 🍓

Strawberry GraphQL Python GraphQL library based on dataclasses Installation ( Quick Start ) The quick start method provides a server and CLI to get go

Strawberry GraphQL 2.8k Jan 01, 2023
GraphiQL & the GraphQL LSP Reference Ecosystem for building browser & IDE tools.

Black Lives Matter 🖤 GraphQL IDE Monorepo Security Notice: All versions of graphiql 1.4.7 are vulnerable to an XSS attack in cases where the GraphQ

GraphQL 14.5k Jan 08, 2023
(Now finding maintainer) 🐍A Pythonic way to provide JWT authentication for Flask-GraphQL

Flask-GraphQL-Auth What is Flask-GraphQL-Auth? Flask-GraphQL-Auth is JWT decorator for flask-graphql inspired from Flask-JWT-Extended. all you have to

Seonghyeon Kim 64 Feb 19, 2022
UltraGraphQL - a GraphQL interface for querying and modifying RDF data on the Web.

UltraGraphQL - cloned from https://git.rwth-aachen.de/i5/ultragraphql Updated or extended files: build.gradle: updated maven to use maven {url "https:

DrSnowbird 1 Jan 07, 2023
GraphQL framework for Python

Graphene 💬 Join the community on Slack We are looking for contributors! Please check the ROADMAP to see how you can help ❤️ The below readme is the d

GraphQL Python 7.5k Jan 01, 2023
Gerenciar a velocidade da internet banda larga

Monitoramento da Velocidade da internet 📶 Status do Projeto: ✔️ (pronto) Tópicos ✍️ Descrição do projeto Funcionalidades Deploy da Aplicação Pré-requ

Bárbara Guerbas de Figueiredo 147 Nov 02, 2022
Generate daily updated visualizations of user and repository statistics from the GitHub API using GitHub Actions

Generate daily updated visualizations of user and repository statistics from the GitHub API using GitHub Actions for any combination of private and public repositories - dark mode supported

Adam Ross 15 Dec 31, 2022
This is a minimal project using graphene with django and user authentication to expose a graphql endpoint.

Welcome This is a minimal project using graphene with django and user authentication to expose a graphql endpoint. Definitely checkout how I have mana

yosef salmalian 1 Nov 18, 2021
Enable idempotent operations in POST and PATCH endpoints

Idempotency Header ASGI Middleware A middleware for making POST and PATCH endpoints idempotent. The purpose of the middleware is to guarantee that exe

Sondre Lillebø Gundersen 12 Dec 28, 2022
ASGI support for the Tartiflette GraphQL engine

tartiflette-asgi is a wrapper that provides ASGI support for the Tartiflette Python GraphQL engine. It is ideal for serving a GraphQL API over HTTP, o

tartiflette 99 Dec 27, 2022
A small command-line tool for interacting with GQL APIs

igqloo A small tool for interacting with GQL APIs Arguments, mutations, aliases are all supported. Other features, such as fragments, are left unsuppo

Joshua Mottaz 7 Dec 20, 2021