Python fbchat库
Python等编程语言的强大之处在于其为用户提供的广泛模块和库。这次我们要探索其中的一个库。每个人都可能有一次或另一次希望给我们的Facebook好友发送消息(或垃圾邮件)的愿望。能够自动化活动并在Facebook Messenger上创建支持机器人似乎很有趣。在接下来的教程中,我们将了解如何使用Python编程语言在Facebook Messenger上建立连接,并执行各种令人惊叹的事情。
这个陈述意味着我们将执行相同的GET/POST请求,并欺骗Facebook以认为它正在正常访问网站。我们需要一个名为 fbchat 的Python库来模拟浏览器进行此操作。因此,此应用程序编程接口(API)并非官方,无需任何API密钥。但是,它需要Facebook账户的凭据。
那么,让我们开始吧。
Python fbchat库简介
Python编程语言中的 fbchat 库利用电子邮件ID和密码与Facebook服务器进行通信。这意味着如果有人在编写代码时偷看密码,我们应该始终将密码存储在单独的文件中。我们还应确保文件的访问控制是适当受限的。
为了安装 fbchat 库,我们将使用pip安装程序,以下是命令示例:
语法:
$ pip3 install fbchat
为了验证库是否正确安装,我们可以创建一个新文件,并添加 import 语句,看它是否返回任何错误。
文件:verify.py
import fbchat
现在,保存Python文件并使用命令提示符运行执行命令:
语法:
$ python verify.py
如果上述Python文件没有引发任何导入错误,我们可以继续进行Facebook Messenger机器人的构建过程。然而,如果引发了异常,则建议重新安装该库并参考官方文档。
现在,让我们了解一下 fbchat 库的基础知识。
登录
我们可以简单地创建 fbchat 库的 Client 类的实例。如果我们启用了两步验证,我们需要在终端提示中输入代码(如果我们想以其他方式提供代码,可以重写 Client.on2FACode 函数。
现在让我们看看以下语法:
示例:
# importing the required modules
from fbchat import Client
from fbchat.models import *
# input username and password of the Facebook account
username = "example@website.com"
password = "password2email"
# creating an object of the Client class
clientObj = Client(username, password)
解释:
在上面的代码片段中,我们从fbchat库中导入了Client类以及fbchat.models中的函数。我们定义了Facebook账户的用户名和密码。最后,我们创建了一个指定用户名和密码的Client类的对象,这样我们就可以访问Facebook账户了。
上面提供的用户名和密码只是为了演示Client类的工作原理,并不实际使用。然而,替换变量字符串为实际的电子邮件ID和密码是必要的。
如果连接到Facebook账户时提供了错误的用户名和密码,可能会导致异常。
在整个代码中,如果我们想检查是否仍然登录,可以使用Client类的isLoggedIn()函数。
我们可以使用Client类的login()函数来登录Facebook账户。
让我们考虑下面的示例,如果登出了,我们想要重新登录。
示例:
# importing the required modules
from fbchat import Client
from fbchat.models import *
# input username and password of the Facebook account
username = "example@website.com"
password = "password2email"
# creating an object of the Client class
clientObj = Client(username, password)
# checking if we are logged in or not
if not clientObj.isLoggedIn():
# logging in using the login() function
clientObj.login(username, password)
解释:
在上面的代码片段中,我们使用 if 语句来检查是否已登录到Facebook帐户,使用 isLoggedIn() 函数。如果我们已经注销,我们还使用 login() 函数指定 username 和 password 再次登录。
一旦我们完成了客户端的使用并希望安全退出,我们将使用 logout() 函数。
其语法如下所示:
示例:
# importing the required modules
from fbchat import Client
from fbchat.models import *
# input username and password of the Facebook account
username = "example@website.com"
password = "password2email"
# creating an object of the Client class
clientObj = Client(username, password)
# logging out
clientObj.logout()
解释:
在上面的代码片段中,我们使用了Client类的logout()函数以及Client类的对象来登出。
理解线程
线程可以被看作是两种东西:一个Messenger群聊或一个单一的Facebook用户。
ThreadType 是一个枚举器,有两个值。第一个值是 USER ,另一个值是 GROUP 。这些值指定了线程是单一用户还是群聊。这在 fbchat 库的多个函数中是必需的,因为Facebook可以在内部区分这两者。
我们可以使用 Client 类的searchForGroups方法来搜索群聊并找到它们的ID。我们也可以使用searchForUsers方法来搜索用户。我们将在本教程的后面详细了解这个方法。
我们可以使用Client类的uid方法来获取我们的用户ID。
我们也可以获取群聊的ID。但是,这个过程非常简单。我们只需要转到 https://www.facebook.com/messages/ ,然后点击我们要找到ID的群聊,然后从浏览器的地址栏中读取ID。URL会显示类似于这样的内容:https://www.facebook.com/messages/t/123456789,其中123456789是群聊的ID。
我们可以将相同的方法应用于多个用户账户,不过只有在他们设置了自定义URL时才能看到这个URL。
让我们考虑下面这段代码片段,演示了如何使用线程ID和线程类型。
示例:
# importing the required modules
from fbchat import Client
from fbchat.models import *
# input username and password of the Facebook account
username = "example@website.com"
password = "password2email"
# creating an object of the Client class
clientObj = Client(username, password)
# sending some message to user and group
clientObj.send(Message(text = 'some message'), thread_id = '', thread_type = ThreadType.USER)
clientObj.send(Message(text = 'some message'), thread_id = '', thread_type = ThreadType.GROUP)
# logging out
clientObj.logout()
说明:
在上面的代码片段中,我们开始导入所需的库并提供 用户名 和 密码 。然后我们创建了一个 Client 类的对象。接下来,我们使用 send() 函数指定文本消息以及线程ID和线程类型,如 USER 和 GROUP 。最后,我们使用 logout() 函数登出。
我们可以观察到,我们提供了线程ID和线程类型来启动函数。然而,有些函数根本不需要线程类型。一个这样的函数可以是 changeThreadColor 。在这种情况下,我们需要提供线程ID。
让我们考虑下面这个示例来演示相同的情况:
示例:
# importing the required modules
from fbchat import Client
from fbchat.models import *
# input username and password of the Facebook account
username = "example@website.com"
password = "password2email"
# creating an object of the Client class
clientObj = Client(username, password)
# changing the Thread Colors
clientObj.changeThreadColor(ThreadColor.BRIGHT_TURQUOISE, thread_id = '')
clientObj.changeThreadColor(ThreadColor.DARK_TANGERINE, thread_id = '')
# logging out
clientObj.logout()
解释:
在上面的代码片段中,我们导入了所需的模块并提供了 用户名 和 密码 。然后我们创建了一个 Client 类的对象。接下来,我们使用 Client 类的 changeThreadColor 函数来改变线程的颜色。我们在函数中指定了线程颜色和线程ID。最后,我们使用 logout() 函数登出账号。
理解消息ID
我们在Facebook上发送的每条消息都包含一个唯一的ID,而我们在线程中执行的每个操作,例如更改昵称或添加人员,都有一个唯一的ID。
一些 fbchat 库的函数需要这些ID,例如 reactToMessage ,而有些函数则提供这些ID,例如 sendMessage 。
让我们来看一个使用这些函数的示例。
示例:
# importing the required modules
from fbchat import Client
from fbchat.models import *
# input username and password of the Facebook account
username = "example@website.com"
password = "password2email"
# creating an object of the Client class
clientObj = Client(username, password)
# getting the message ID
messageID = clientObj.send(Message(text = 'message'), thread_id = clientObj.uid, thread_type = '')
# using the message ID to react to message
clientObj.reactToMessage(messageID, MessageReaction.LOVE)
# logging out
clientObj.logout()
解释:
在上面的代码片段中,我们已经导入了所需的方法,并提供了 用户名 和 密码 。然后,我们创建了一个 Client 类的对象。然后,我们使用 send() 函数获取了消息ID。然后,我们使用消息ID来通过 reactToMessage() 函数对消息进行回应,并指定了 messageID 以及 MessageReaction 为 LOVE 表情。
与聊天线程的交互
fbchat 库提供了不同的函数,以便我们与聊天线程进行交互。
大多数功能适用于所有聊天线程,尽管一些操作,例如将用户添加到和从群聊中删除用户,逻辑上仅适用于群聊。
与聊天线程交互的一些函数在下表中描述:
序号 | 功能 | 描述 |
---|---|---|
1 | send | 这个函数用于向用户或群组发送消息。 |
2 | sendLocalImage | 这个函数用于发送本地图片。 |
3 | sendRemoteImage | 这个函数用于下载URL上的图片并发送。 |
4 | addUsersToGroup | 这个函数用于将一个或多个用户添加到群组中。 |
5 | removeUserFromGroup | 这个函数用于将用户从群组中移除。 |
6 | changeNickname | 这个函数用于更改用户的昵称。 |
7 | changeThreadTitle | 这个函数用于修改线程的标题。 |
8 | setTypingStatus | 这个函数用于设置输入状态为输入中或停止输入。 |
9 | changeThreadColor | 这个函数用于更改线程的颜色。 |
10 | changeThreadEmoji | 这个函数用于更改线程中的表情符号。 |
11 | reactToMessage | 这个函数用于对一条消息进行反应。 |
让我们考虑以下示例,演示如何使用上述功能与线程交互。
示例:
# importing the required modules
from fbchat import Client
from fbchat.models import *
# input username and password of facebook account
username = "example@website.com"
password = "password2email"
# creating an object of Client class
clientObj = Client(username, password)
# specifying the thread ID and type
threadID = "1234567890"
threadType = ThreadType.GROUP
# sending a message to the thread
clientObj.send(
Message(text = "some text message"),
thread_id = threadID,
thread_type = threadType
)
# sending the emoji `👍`
clientObj.send(
Message(text = "👍", emoji_size = EmojiSize.LARGE),
thread_id = threadID,
thread_type = threadType
)
# sending the sticker with ID `767334476626295`
clientObj.send(
Message(sticker = Sticker("767334476626295")),
thread_id = threadID,
thread_type = threadType
)
# sending a message with a mention
clientObj.send(
Message(
text = "An example of @mention",
mentions = [Mention(
threadID,
offset = 10,
length = 8
)]),
thread_id = threadID,
thread_type = threadType
)
# sending the image located at `<path_to_image_file>`
clientObj.sendLocalImage(
"<path_to_image_file>",
message = Message(text = "This is a local image"),
thread_id = threadID,
thread_type = threadType
)
# downloading the image at the URL `<url_to_image_file>`, and then sending it
clientObj.sendRemoteImage(
"<url_to_image_file>",
message = Message(text = "This is a remote image"),
thread_id = threadID,
thread_type = threadType
)
# Only do these actions if the thread is a group
if threadType == ThreadType.GROUP:
# removing the user with ID `<user_id>` from the thread
clientObj.removeUserFromGroup("<user_id>", thread_id = threadID)
# adding the user with ID `<user_id>` to the thread
clientObj.addUsersToGroup("<user_id>", thread_id = threadID)
# adding the users with IDs `<First_user_id>`, `<Second_user_id>` and `<Third_user_id>` to the thread
clientObj.addUsersToGroup(
["<First_user_id>", "<Second_user_id>", "<Third_user_id>"], thread_id = threadID
)
# changing the nickname of the user `<user_id>` to `<new_nickname>`
clientObj.changeNickname(
"<new_nickname>", "<user_id>", thread_id = threadID, thread_type = threadType
)
# changing the title of the thread to `<title>`
clientObj.changeThreadTitle("<some_title>", thread_id = threadID, thread_type = threadType)
# setting the typing status of the thread to `TYPING`
clientObj.setTypingStatus(
TypingStatus.TYPING,
thread_id = threadID,
thread_type = threadType
)
# changing the thread color to `RADICAL_RED`
clientObj.changeThreadColor(ThreadColor.RADICAL_RED, thread_id = threadID)
# changing the thread emoji to `👍`
clientObj.changeThreadEmoji("👍", thread_id = threadID)
# reacting to a message with a 😍 emoji
clientObj.reactToMessage("<messageID>", MessageReaction.LOVE)
解释:
在上面的代码片段中,我们导入了所需的模块并提供了 username 和 password 。我们创建了一个 Client 类的实例,并指定了线程 ID 和类型。然后,我们使用不同的函数来与线程进行交互,包括发送文本消息和表情符号,更改线程颜色和表情符号。由于我们正在处理一个 GROUP 聊天,我们还使用了添加和删除群组成员的操作。我们还使用了用于发送本地和特定 URL 上可用的图像的函数。
现在,让我们了解如何使用 fbchat 库来获取信息。
获取信息
我们可以利用 fbchat 库来获取有关用户的基本信息,例如他们的用户名、个人资料图片、线程名称和用户 ID。
我们可以使用 Client 类的 searchForUsers 函数来检索用户的 ID。让我们考虑以下示例,演示可用于获取用户信息的函数的工作原理。
示例:
# importing the required modules
from fbchat import Client
from fbchat.models import *
# input username and password of facebook account
username = "example@website.com"
password = "password2email"
# creating an object of Client class
clientObj = Client(username, password)
# retrieving the User IDs
the_users = clientObj.searchForUsers('')
the_user = the_users[0]
# printing the information of the User
print("User ID: {}".format(the_user.uid))
print("Name of the User: {}".format(the_user.name))
print("Profile picture URL of the User: {}".format(the_user.photo))
print("Main URL of the URL: {}".format(the_user.url))
解释:
在上面的代码片段中,我们导入了所需的模块并创建了 Client 类的一个实例。然后,我们使用 searchForUsers 函数检索用户ID。然后,我们将第一个用户的值存储在一个变量中。最后,我们使用 uid、name、photo、url 函数打印用户的信息。
由于此示例使用了Facebook的搜索功能,因此我们无需指定完整的名称;通常只需要名字即可。
现在让我们了解会话(Sessions)。
了解会话
fbchat库提供了函数来检索和设置会话cookie。此函数允许我们将会话cookie存储在单独的文件中,这样我们就不必每次开始脚本时都需要登录。
我们可以使用Client类的 getSession 函数检索cookie。其语法如下所示:
语法:
sessionCookies = clientObj.getSession()
然后我们可以使用 Client 类中的 setSession 函数来设置会话。语法如下所示:
语法:
clientObj.setSession(sessionCookies)
或者我们可以在初始登录时设置 session_cookies (如果会话cookie无效,则使用电子邮件和密码进行登录):
语法:
clientObj = Client('<email_ID>', '<password>', session_cookies = sessionCookies)
警告: 会话cookie的价值可能与密码等同,因此应同等小心地存储它们。
监听和事件
fbchat 库还提供了像 Client 类的 listen 函数一样的监听功能,我们需要定义在发生某些事件时应执行的操作。默认情况下,大多数事件只是一个 logging.info 语句,意味着当事件发生时,它只会将详细信息打印到控制台。
注意:我们可以通过它们的前缀来识别事件方法。例如,onMessage。
通过子类化 Client ,然后像下面所示覆盖事件方法,我们可以更改事件操作:
语法:
# creating a subclass of the Client class
class Custom_Client(Client):
def onMessage(self, mid, author_id, message_object, thread_id, thread_type, ts, metadata, msg, **kwargs):
# Perform something with message_object here
pass
# creating an instance of Custom_Client class
clientObj = Custom_Client('<email_ID>', '<password>')
解释:
我们在上述语法中定义了一个名为Custom_Client的Client子类。在这个类内部,我们定义了一个名为onMessage的方法,该方法接受多个参数,如self、mid、author_id、message_object、thread_id、thread_type、ts、metadata、msg和**kwargs。可以在这个方法中编写一些功能。最后,我们实例化了Custom_Client类,将username和password作为参数传递给它。
即使我们修改了方法的参数,onMessage方法仍然可以工作;但是,我们必须在其中包含**kwargs
。
注意:因此,为了向后和向前兼容,API要求我们将**kwargs作为最后一个参数包含其中。