Examples

These are a few examples on how to use fbchat. Remember to swap out <email> and <password> for your email and password

Basic example

This will show basic usage of fbchat

import fbchat

# Log the user in
session = fbchat.Session.login("<email>", "<password>")

print("Own id: {}".format(session.user.id))

# Send a message to yourself
session.user.send_text("Hi me!")

# Log the user out
session.logout()

Interacting with Threads

This will interact with the thread in every way fbchat supports

import fbchat
import requests

session = fbchat.Session.login("<email>", "<password>")

client = fbchat.Client(session)

thread = session.user
# thread = fbchat.User(session=session, id="0987654321")
# thread = fbchat.Group(session=session, id="1234567890")

# Will send a message to the thread
thread.send_text("<message>")

# Will send the default `like` emoji
thread.send_sticker(fbchat.EmojiSize.LARGE.value)

# Will send the emoji `👍`
thread.send_emoji("👍", size=fbchat.EmojiSize.LARGE)

# Will send the sticker with ID `767334476626295`
thread.send_sticker("767334476626295")

# Will send a message with a mention
thread.send_text(
    text="This is a @mention",
    mentions=[fbchat.Mention(thread.id, offset=10, length=8)],
)

# Will send the image located at `<image path>`
with open("<image path>", "rb") as f:
    files = client.upload([("image_name.png", f, "image/png")])
thread.send_text(text="This is a local image", files=files)

# Will download the image at the URL `<image url>`, and then send it
r = requests.get("<image url>")
files = client.upload([("image_name.png", r.content, "image/png")])
thread.send_files(files)  # Alternative to .send_text


# Only do these actions if the thread is a group
if isinstance(thread, fbchat.Group):
    # Will remove the user with ID `<user id>` from the group
    thread.remove_participant("<user id>")
    # Will add the users with IDs `<1st user id>`, `<2nd user id>` and `<3th user id>` to the group
    thread.add_participants(["<1st user id>", "<2nd user id>", "<3rd user id>"])
    # Will change the title of the group to `<title>`
    thread.set_title("<title>")


# Will change the nickname of the user `<user id>` to `<new nickname>`
thread.set_nickname(fbchat.User(session=session, id="<user id>"), "<new nickname>")

# Will set the typing status of the thread
thread.start_typing()

# Will change the thread color to #0084ff
thread.set_color("#0084ff")

# Will change the thread emoji to `👍`
thread.set_emoji("👍")

message = fbchat.Message(thread=thread, id="<message id>")

# Will react to a message with a 😍 emoji
message.react("😍")

Fetching Information

This will show the different ways of fetching information about users and threads

import fbchat

session = fbchat.Session.login("<email>", "<password>")

client = fbchat.Client(session=session)

# Fetches a list of all users you're currently chatting with, as `User` objects
users = client.fetch_all_users()

print("users' IDs: {}".format([user.id for user in users]))
print("users' names: {}".format([user.name for user in users]))


# If we have a user id, we can use `fetch_user_info` to fetch a `User` object
user = client.fetch_user_info("<user id>")["<user id>"]
# We can also query both mutiple users together, which returns list of `User` objects
users = client.fetch_user_info("<1st user id>", "<2nd user id>", "<3rd user id>")

print("user's name: {}".format(user.name))
print("users' names: {}".format([users[k].name for k in users]))


# `search_for_users` searches for the user and gives us a list of the results,
# and then we just take the first one, aka. the most likely one:
user = client.search_for_users("<name of user>")[0]

print("user ID: {}".format(user.id))
print("user's name: {}".format(user.name))
print("user's photo: {}".format(user.photo))
print("Is user client's friend: {}".format(user.is_friend))


# Fetches a list of the 20 top threads you're currently chatting with
threads = client.fetch_thread_list()
# Fetches the next 10 threads
threads += client.fetch_thread_list(offset=20, limit=10)

print("Threads: {}".format(threads))


# If we have a thread id, we can use `fetch_thread_info` to fetch a `Thread` object
thread = client.fetch_thread_info("<thread id>")["<thread id>"]
print("thread's name: {}".format(thread.name))


# Gets the last 10 messages sent to the thread
messages = thread.fetch_messages(limit=10)
# Since the message come in reversed order, reverse them
messages.reverse()

# Prints the content of all the messages
for message in messages:
    print(message.text)


# `search_for_threads` searches works like `search_for_users`, but gives us a list of threads instead
thread = client.search_for_threads("<name of thread>")[0]
print("thread's name: {}".format(thread.name))


# Here should be an example of `getUnread`


# Print image url for up to 20 last images from thread.
images = list(thread.fetch_images(limit=20))
for image in images:
    if isinstance(image, fbchat.ImageAttachment):
        url = client.fetch_image_url(image.id)
        print(url)

Echobot

This will reply to any message with the same message

import fbchat

session = fbchat.Session.login("<email>", "<password>")
listener = fbchat.Listener(session=session, chat_on=False, foreground=False)

for event in listener.listen():
    if isinstance(event, fbchat.MessageEvent):
        print(f"{event.message.text} from {event.author.id} in {event.thread.id}")
        # If you're not the author, echo
        if event.author.id != session.user.id:
            event.thread.send_text(event.message.text)

Remove Bot

This will remove a user from a group if they write the message Remove me!

import fbchat


def on_message(event):
    # We can only kick people from group chats, so no need to try if it's a user chat
    if not isinstance(event.thread, fbchat.Group):
        return
    if event.message.text == "Remove me!":
        print(f"{event.author.id} will be removed from {event.thread.id}")
        event.thread.remove_participant(event.author.id)


session = fbchat.Session.login("<email>", "<password>")
listener = fbchat.Listener(session=session, chat_on=False, foreground=False)
for event in listener.listen():
    if isinstance(event, fbchat.MessageEvent):
        on_message(event)

“Prevent changes”-Bot

This will prevent chat color, emoji, nicknames and chat name from being changed. It will also prevent people from being added and removed

# This example uses the `blinker` library to dispatch events. See echobot.py for how
# this could be done differenly. The decision is entirely up to you!
import fbchat
import blinker

# Change this to your group id
old_thread_id = "1234567890"

# Change these to match your liking
old_color = "#0084ff"
old_emoji = "👍"
old_title = "Old group chat name"
old_nicknames = {
    "12345678901": "User nr. 1's nickname",
    "12345678902": "User nr. 2's nickname",
    "12345678903": "User nr. 3's nickname",
    "12345678904": "User nr. 4's nickname",
}

# Create a blinker signal
events = blinker.Signal()

# Register various event handlers on the signal
@events.connect_via(fbchat.ColorSet)
def on_color_set(sender, event: fbchat.ColorSet):
    if old_thread_id != event.thread.id:
        return
    if old_color != event.color:
        print(f"{event.author.id} changed the thread color. It will be changed back")
        event.thread.set_color(old_color)


@events.connect_via(fbchat.EmojiSet)
def on_emoji_set(sender, event: fbchat.EmojiSet):
    if old_thread_id != event.thread.id:
        return
    if old_emoji != event.emoji:
        print(f"{event.author.id} changed the thread emoji. It will be changed back")
        event.thread.set_emoji(old_emoji)


@events.connect_via(fbchat.TitleSet)
def on_title_set(sender, event: fbchat.TitleSet):
    if old_thread_id != event.thread.id:
        return
    if old_title != event.title:
        print(f"{event.author.id} changed the thread title. It will be changed back")
        event.thread.set_title(old_title)


@events.connect_via(fbchat.NicknameSet)
def on_nickname_set(sender, event: fbchat.NicknameSet):
    if old_thread_id != event.thread.id:
        return
    old_nickname = old_nicknames.get(event.subject.id)
    if old_nickname != event.nickname:
        print(
            f"{event.author.id} changed {event.subject.id}'s' nickname."
            " It will be changed back"
        )
        event.thread.set_nickname(event.subject.id, old_nickname)


@events.connect_via(fbchat.PeopleAdded)
def on_people_added(sender, event: fbchat.PeopleAdded):
    if old_thread_id != event.thread.id:
        return
    if event.author.id != session.user.id:
        print(f"{', '.join(x.id for x in event.added)} got added. They will be removed")
        for added in event.added:
            event.thread.remove_participant(added.id)


@events.connect_via(fbchat.PersonRemoved)
def on_person_removed(sender, event: fbchat.PersonRemoved):
    if old_thread_id != event.thread.id:
        return
    # No point in trying to add ourself
    if event.removed.id == session.user.id:
        return
    if event.author.id != session.user.id:
        print(f"{event.removed.id} got removed. They will be re-added")
        event.thread.add_participants([event.removed.id])


# Login, and start listening for events
session = fbchat.Session.login("<email>", "<password>")
listener = fbchat.Listener(session=session, chat_on=False, foreground=False)

for event in listener.listen():
    # Dispatch the event to the subscribed handlers
    events.send(type(event), event=event)