使用 Python 的 Facebook Messenger 自动化
像 Python 这样的编程语言之所以强大,是因为它为用户提供了广泛的模块和库。这次我们将探索其中的一个。可能会有这样或那样的时候,我们每个人都希望收到我们的 Facebook 朋友发来的消息(或垃圾邮件)。能够在 Facebook Messenger 中自动化活动并制作支持机器人似乎很有趣。在下面的教程中,我们将了解如何使用 Python 编程语言在 Facebook Messenger 中进行连接,并执行各种令人惊叹的事情。
这一声明暗示我们将执行相同的获取/发布请求,并欺骗 Facebook 认为它正在正常访问网站。我们将需要一个名为 fbchat
的 Python 库,它允许程序员为这个操作模拟浏览器。所以这个 API 不是官方的,不需要任何 API 密钥。但是,它需要 Facebook 帐户的凭据。
那么,让我们开始吧。
Python fbchat
库简介
Python 编程语言中的 fbchat
库利用电子邮件标识和密码与 Facebook 服务器通信。这种说法意味着,如果有人在编写代码时偷偷进入密码,我们应该始终将密码存储在单独的文件中。我们还应该确保文件的访问控制受到适当的限制。
为了安装 fbchat
库,我们将使用 pip 安装程序执行如下所示的命令:
语法:
$ pip3 install fbchat
为了验证库安装是否正确,我们可以创建一个新文件,并添加 import 语句,看看它是否返回任何错误。
文件: 验证.py
import fbchat
现在,保存 Python 文件,并使用命令提示符运行执行命令:
语法:
$ python verify.py
如果上面的 Python 文件没有引起任何导入错误,我们就可以进入 Facebook Messenger 机器人构建程序了。但是,如果它确实引发了异常,建议重新安装库并参考其官方文档。
现在,让我们了解一下 fbchat
库的基础知识。
登录
我们可以简单地创建一个 fbchat
库的客户端类的实例。如果我们启用了双因素身份验证,我们需要在终端提示中键入代码(如果我们想以另一种方式提供代码,我们可以覆盖客户端的 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
库中导入了客户端类以及 fbchat.models
中的函数。我们已经定义了 Facebook 账户的用户名和密码。最后,我们创建了一个客户端类的对象,指定用户名和密码作为其参数,允许我们访问 Facebook 帐户。
以上提供的用户名和密码仅演示了客户端类的工作情况,并未达到真正的目的。但是,需要分别用实际的电子邮件标识和密码替换变量字符串。
不正确的用户名和密码可能会导致连接到 Facebook 帐户时出现异常。
在整个代码中,如果我们想检查我们是否仍然登录,我们可以使用客户端类的 isLoggedIn()
功能。
我们可以使用客户端类的 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 语句来检查我们是否使用了 isLoggedIn()
功能登录了 Facebook 帐户。我们还使用了 login()
功能,指定用户名和密码如果我们注销了,可以再次登录。
一旦我们使用完客户端并想要安全注销,我们将使用 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()
说明:
在上面的代码片段中,我们使用了客户端类的 logout()
功能以及客户端的对象来注销。
理解线程
一个线程可以被认为是两件事:一个 Messenger 群聊或一个单一的 Facebook 用户。
线程类型是一个有两个值的枚举器。第一个值是 User
,另一个值是 Group
。这些将指定该线程是单用户聊天还是群聊。这是 fbchat
库的多种功能所必需的,因为 Facebook 可以在内部区分这两种功能。
我们可以使用客户端类的 searchForGroups
方法搜索群聊并找到他们的 ID。我们也可以使用 searchForUsers
方法来搜索用户。我们将在本教程的后面讨论它。
我们可以在客户端类的 uid
方法的帮助下检索我们的用户标识。
我们还可以检索群聊 ID。然而,同样的程序相当琐碎。因为我们只需要导航到 https://www.facebook.com/messages/
,然后我们将不得不点击我们想要找到的组的 ID,然后从地址栏读取 ID。网址将显示如下:https://www.facebook.com/messages/t/123456789
,其中 123456789
将是群聊的标识。
我们可以对几个用户帐户应用相同的方法,尽管如果他们设置了自定义的网址,我们将只看到那个网址。
让我们考虑下面的代码片段,演示线程标识和线程类型的使用。
示例:
# 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 = '<group_id>', thread_type = ThreadType.GROUP)
# logging out
clientObj.logout()
说明:
在上面的代码片段中,我们已经开始导入所需的库并提供用户名和密码。然后我们创建了一个客户端类的对象。之后,我们使用 send()
功能,将文本消息连同线程 ID 和线程类型指定为 USER
和 GROUP
。最后,我们已经使用 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)
# changing the Thread Colors
clientObj.changeThreadColor(ThreadColor.BRIGHT_TURQUOISE, thread_id = '')
clientObj.changeThreadColor(ThreadColor.DARK_TANGERINE, thread_id = '<group_id>')
# logging out
clientObj.logout()
说明:
在上面的代码片段中,我们已经导入了所需的模块,并提供了用户名和密码。然后我们创建了一个客户端类的对象。然后我们使用了客户端类的 changeThreadColor
功能来更改线程的颜色。我们已经在函数中指定了线程颜色和线程标识。最后,我们已经使用 logout()
功能注销了。
了解消息标识
我们在 Facebook 上发送的每条消息都由一个唯一的标识组成,我们在一个线程中执行的每项活动,例如更改昵称或添加个人,都有一个唯一的标识。
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()
说明:
在上面的代码片段中,我们已经导入了所需的方法,并提供了用户名和密码。然后我们创建了一个客户端类的对象。然后,我们使用 send()
功能检索消息标识。然后,我们使用了消息标识,以便在 reactToMessage()
的帮助下对消息做出反应,其中我们将消息标识和消息反应一起指定为爱情表情符号。
与线程的交互
fbchat
库提供了不同的功能,以便我们与线程进行交互。
大多数功能适用于所有线程,但有些功能,如在群聊中添加用户和删除用户,逻辑上只适用于群聊。
下表描述了用于与线程交互的一些函数:
编号 | 功能 | 描述 |
---|---|---|
1 | send |
此功能用于向用户或组发送消息。 |
2 | sendLocalImage |
此功能用于发送位于本地的图像。 |
3 | sendRemoteImage |
该功能用于从网址下载并发送图像。 |
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)
说明:
在上面的代码片段中,我们已经导入了所需的模块,并提供了用户名和密码。我们创建了一个客户端类的实例,并指定了线程标识和类型。然后,我们使用了不同的功能来与线程进行交互,从发送文本消息和表情符号到更改线程颜色和表情符号。由于我们正在进行群组聊天,我们还使用了在群组中添加和删除用户的操作。我们还使用了在本地和特定的网址上发送图像的功能。
现在,让我们了解如何使用 fbchat
库获取信息。
获取信息
我们可以利用 fbchat
库来获取关于用户的基本信息,例如他们的用户名、个人资料图片、线程名称和用户标识。
我们可以使用客户端类的searchForUsers功能来检索用户标识。让我们考虑下面的例子,它演示了允许我们获取用户信息的函数的工作原理。
示例:
# 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 Client class
clientObj = Client(username, password)
# retrieving the user
the_users = clientObj.searchForUsers('')
the_user = the_users[0]
# printing the user information
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功能来检索用户标识。然后,我们将第一个用户的值存储在一个变量中。最后,我们使用 uid
、name
、photo
、url
功能打印了用户信息。
由于这个例子利用了 Facebook 的搜索功能,我们不需要指定完整的名称;名字通常就足够了。
现在让我们了解会话。
理解会话
fbchat
库提供了检索和设置会话 cookies 的功能。这个函数将允许我们将会话 cookies 存储在一个单独的文件中,这样我们就不必每次开始脚本时都登录。
我们可以使用客户端类的getSession功能来检索 cookies。其语法如下所示:
语法:
sessionCookies = clientObj.getSession()
然后我们可以使用客户端类的setSession功能来设置会话。其语法如下所示:
语法:
clientObj.setSession(sessionCookies)
或者我们可以在首次登录时设置 session_cookies
。(如果会话 cookies 无效,将使用电子邮件和密码登录):
语法:
clientObj = Client('', '', session_cookies = sessionCookies)
警告: 会话 cookies 可以和密码一样有价值,所以存储时要同样小心。
倾听和事件
fbchat
库还提供了类似于客户端类的listen功能的监听功能,我们需要定义当某些事件发生时应该执行什么。默认情况下,(大多数)事件将只是一个 logging.info
语句,这意味着当事件发生时,它将简单地向控制台打印细节。
注意: 我们可以通过前缀识别事件方法。例如,onMessage
。
我们可以通过子类化客户端然后覆盖事件方法来改变事件动作,如下所示:
语法:
class Custom_Client(Client):
def onMessage(self, mid, author_id, message_object, thread_id, thread_type, ts, metadata, msg, **kwargs):
pass
clientObj = Custom_Client('', '')
说明:
在上面的语法中,我们已经将客户端类的子类定义为Custom_Client。在类中,我们定义了一个方法为 onMessage
,它接受多个参数,如 self
、mid
、author_id
、message_object
、thread_id
、thread_type
、ts
、metadata
、msg
和 **kwargs
。人们可以在这个方法中编写一些功能。最后,我们通过用户名和密码作为参数实例化了 Custom_Client
类。
onMessage
方法即使在我们更改方法的参数时也可以工作;然而,我们必须把 **kwargs
包括在内。
注意: 因此,为了向后和向前兼容,API 要求我们包含 **kwargs
作为最终参数。
更多信息见官方文件,网址为: https://fbchat.readthedocs.io/en/stable/intro.html