跳转到主要内容

一个服务器端框架,使管理发布到社交媒体的艺术机器人变得容易。

项目描述

Botfriend

Botfriend是一个Python框架,用于管理大量发布到不同服务的创意机器人。

我认为Botfriend的主要功能包括这些

  • 最小化的Python编码 —— 只需编写您的机器人有趣的部分。
  • 基于YAML的简单配置。
  • 轻松安排发布。
  • 每个机器人都可以发布到Twitter和/或Mastodon。(计划支持Tumblr。)
  • 通过Olipy内置访问艺术用品。

Botfriend是一个运行在服务器上的Python库。如果您不熟悉设置cron作业或编写Python代码,我建议您查看快速完成廉价机器人甜蜜的廉价机器人,作为表达您创造力的更简单方式。

故事

我编写Botfriend来管理我创建的约三十个不同的Twitter机器人。我发现自己不断地复制粘贴,一遍又一遍地编写相同的代码。每个机器人都做不同的事情,但它们都有某些基本需求:连接到各种服务和API、决定何时发布某物、管理内容队列等等。没有必要每个机器人都有自己的代码版本。需要新代码的机器人只有创意部分。

我另一个大问题是,我开始不喜欢Twitter了。它是一个创意机器人的伟大平台,但每次我创建一个机器人,我都会感到内疚,因为我增加了我认为正在使世界变得更糟的平台的价值。(此外,Twitter开始无缘无故地暂停我的机器人。)

我不想放弃我的机器人制作爱好,因此我开始研究Mastodon机器人世界。[Mastodon](https://joinmastodon.org/)。这又带来了另一个问题:重写三十个机器人以发布到不同的服务是非常痛苦的。如果我要做这么多工作,我希望最终产品是一个可重用的库,这样可以为每个人节省时间。

所以我审查了我的三十个机器人,重写了所有内容,并将所有可重用的代码移动到Botfriend中。现在我的机器人要小得多,也更易于管理。所有繁琐的代码都在一个地方,我可以专注于机器人编写的有趣部分。

考虑一下像A Dull Bot([源代码](https://github.com/leonardr/botfriend/tree/master/bots.sample/a-dull-bot))这样的机器人。创建这个机器人需要相当多的工作。但所有的工作都集中在有趣的部分:创建《闪灵》中打字机的准确软件模型。没有代码来确保机器人每小时发布一次,也没有代码通过Twitter或Mastodon API推送打印的文本。Botfriend会处理所有这些事情。

如果您想在自己的机器人项目中节省代码、将机器人从Twitter迁移到Mastodon,或者只是扩大机器人的覆盖范围,我希望您会考虑Botfriend。

设置

我建议您在Python虚拟环境中运行Botfriend。以下是创建名为env的虚拟环境并将Botfriend安装到其中的方法。

$ virtualenv env
$ source env/bin/activate
$ pip install botfriend

您将通过命令行脚本与Botfriend进行交互。从现在起,我将给出很多示例命令行。所有示例都假设您已经通过运行以下命令进入Botfriend虚拟环境

$ source env/bin/activate

简单示例:数字笑话

默认情况下,Botfriend期望您将机器人的源代码放在与虚拟环境相同的目录下的bots/目录中。所以如果您的虚拟环境位于/home/myusername/botfriend/env,则Botfriend将期望您的机器人位于/home/myusername/botfriend/bots下。

Botfriend数据库本身将存储在机器人目录中,文件名为botfriend.sqlite

如果您想将Botfriend数据存储在除bots/之外的地方,每个Botfriend脚本都接受一个指向您的机器人目录的--config参数。但大多数情况下,bots/就足够了。

每个机器人将位于您的机器人目录的子目录中,目录名与机器人同名。让我们从一个简单的示例开始,称为number-jokes

$ mkdir bots
$ mkdir bots/number-jokes

每个机器人都需要包含两个特殊文件:用于源代码的__init__.py和用于配置的bot.yaml

__init__.py:想出一个笑话

想象一下走到一个喜剧演员面前说“给我讲个笑话!”一个人类喜剧演员可能不会喜欢这样,但这正是机器人的生存之道。对于Botfriend机器人来说,__init__.py是喜剧演员想出笑话的地方。

为了开始,我们将创建一个简单的机器人,它可以生成关于数字的观察性幽默。

为了开始,请使用文本编辑器打开bots/number-jokes/__init__.py,并写入以下内容

import random
from botfriend.bot import TextGeneratorBot

class NumberJokes(TextGeneratorBot):

    def generate_text(self):
        """Tell a joke about numbers."""
        num = random.randint(1,10)
        arguments = dict(
            num=num,
            plus_1=num+1,
            plus_3=num+3
        )
        setup = "Why is %(num)d afraid of %(plus_1)d? "
        punchline = "Because %(plus_1)d ate %(plus_3)d!"
        return (setup + punchline) % arguments

Bot = NumberJokes

Botfriend提供了许多实用工具来帮助您编写好的__init__.py,但有唯一一条铁的规则:文件末尾必须有一个名为Bot的类。Botfriend脚本将加载您的Bot类、实例化它并使用它来完成...机器人所做的一切。

一些机器人为了想出一个单一的“笑话”会做很多工作。他们可能会画图、进行数据库查询、进行API调用,等等复杂的事情。作为示例,这里的NumberJokes几乎不做任何工作。它只是随机选择一个数字并将其放入一个字符串中。

bot.yaml:讲笑话

像大多数喜剧演员一样,机器人会不断地想出笑话。但如果没有人听到这个笑话,那还有什么意义呢?bot.yaml 文件解释了机器人应该如何向公众讲述它的笑话。

打开文件 bots/number-jokes/bot.yaml 并写入以下内容

name: "Number Jokes"
schedule: 60
publish:
    file:
      filename: "number-jokes.txt"

__init__.py 类似,bot.yaml 可能会变得非常复杂,但大多数时候它相当简单。这个文件表示

  • 机器人的名称是 "Number Jokes"。

  • 机器人应该每小时讲一个笑话。

  • 这个机器人通过将笑话写入文件 number-jokes.txt 来讲笑话。(这是相对于机器人目录的,所以它将在 bots/number-jokes/number-jokes.txt。)

现在你准备好让你的机器人讲一些笑话了,使用一些基本的Botfriend脚本。

基本脚本

botfriend.post

botfriend.post 脚本会让每个机器人想出一个笑话并讲述它。现在运行它

$ botfriend.post
# Number Jokes | file | Published 2019-01-20 | Why is 4 afraid of 5… 

现在看看你在 bot.yaml 中配置的文件。你告诉 Number Jokes 将其笑话发布到 bots/number-jokes/number-jokes.txt。在你运行 botfriend.post 之前,该文件不存在,但现在它存在了,并且里面有一个笑话

$ cat bots/number-jokes/number-jokes.txt
2019-01-20 10:23:44 | Why is 4 afraid of 5? Because 5 ate 7!

很有趣,对吧?你可能需要频繁地运行这个脚本,可能作为自动化流程的一部分。在我的网站上,我每五分钟运行一次 botfriend.post。(我在本文档的末尾展示了如何进行此操作。)

如果你的机器人没有安排讲笑话,botfriend.post 将不会执行任何操作。现在再次运行它 -- 没有任何操作。

$ botfriend.post

Number Jokes 第一次运行时讲了一个笑话,并且(正如你在 bot.yaml 中告诉它的那样)它只应该每小时讲一个笑话。所以,没有新的笑话。

如果你等待一小时并再次运行 botfriend.post,你会得到另一个笑话。但不要等待 -- 继续进行这个教程!

在单个机器人上运行脚本

通过在命令行上指定目录名称,你可以使 botfriend.post(以及大多数其他Botfriend脚本)仅对一个机器人而不是所有机器人进行操作。目前,这没有区别,因为你只有一个机器人,但以下是如何做到这一点的方法

$ botfriend.post number-jokes

强制机器人发布

你可以使用 --force 来使机器人即使在其日程安排通常不允许的情况下也能讲笑话。

$ botfriend.post number-jokes --force
# LOG 2019-01-20 | Number Jokes | file | Published 2019-01-20 | Why is 9 afraid of 10… 

现在 bots/number-jokes/number-jokes.txt 中包含两个笑话。

$ cat bots/number-jokes/number-jokes.txt
2019-01-20 10:23:44 | Why is 4 afraid of 5? Because 5 ate 7!
2019-01-20 10:26:12 | Why is 9 afraid of 10? Because 10 ate 11!

botfriend.dashboard

这个脚本非常适合查看你的机器人。它显示了它们最近在忙什么,以及它们下一次发布的时间。

$ botfriend.dashboard number-jokes
# Number Jokes | Most recent post: Why is 9 afraid of 10? Because 10 ate 12!
# Number Jokes | file posted 0m ago (2019-01-20 10:26:12)
# Number Jokes | Next post in 59m

botfriend.bots

如果你有很多机器人,记住它们的所有名称可能会很烦人。botfriend.bots 脚本会列出 Botfriend 所知道的机器人。

$ botfriend.bots
# number-jokes

到目前为止,只有一个机器人。

botfriend.test.stress

测试一个做随机事情的机器人是困难的。你可能有一个使机器人崩溃的漏洞,但这只会发生一千次中的一次。或者,你的机器人可能永远不会崩溃,但有时运行时间会很长。

这就是为什么我们有 botfriend.test.stress 脚本的原因,它会要求机器人连续想出一万个笑话。笑话不会被发布到任何地方;目标只是测试机器人内部可能发生的所有可能情况。

由于 Number Jokes 非常简单,它可以毫无问题地生成一万个笑话,尽管其中一些是重复的

$ botfriend.test.stress number-jokes
# Why is 2 afraid of 3? Because 3 ate 5!
# Why is 7 afraid of 8? Because 8 ate 10!
# Why is 1 afraid of 2? Because 2 ate 4!
# Why is 4 afraid of 5? Because 5 ate 7!
# Why is 4 afraid of 5? Because 5 ate 7!
# Why is 7 afraid of 8? Because 8 ate 10!
# ... etc. etc. ...

如果你的机器人很复杂,在使用它之前,运行 botfriend.test.stress 几次可能是个好主意。

如何发布

Botfriend 还有一些有趣的功能,但让我们花一点时间来谈谈无聊的功能。让机器人将帖子写入文件很容易,但没有人会看到。你真正需要的是获取一些 Twitter 或 Mastodon 凭证。(具体说明见下文。)

一旦您拥有了某些凭证,打开您机器人的bot.yaml文件,将您的凭证添加到publish配置设置中。这将给您的机器人提供更多发布帖子的方式。

以下是一个示例。这是如果Number Jokes配置了Twitter和Mastodon连接,并且将所有内容写入文件时的配置示例。

name: Number Jokes
schedule: 60
publish:
  file:
    filename: number-jokes.txt
  mastodon:
    api_base_url: 'https://botsin.space/'
    client_id: cc13bf3de67fb399475c315e4a9bf5dd4dfb7ea0f3a521fca72a9c8bf02075ab
    client_secret: 0946d2634d7b6aa1ea93af4b183fccf14e9df2e2b55db8fcdb0c8a5f267ff312
    access_token: c76eb18c5c0dc7c1fe09b53ac175b3b9ed081b0e43ea4d60e94ee721b83c1eda
  twitter:
    consumer_key: t7CfbbNLB3jfoAKI
    consumer_secret: 2teOyqqgFpFpytFanuOXzfjvR3vEmYH3
    access_token: 3341062559-SbUlEDFCDn6k6vHHDWGwqlK0wyZ0fKRegaZMyS9lwBa4L5VXY5fdl
    access_token_secret: ALc2CPkkrSBf33swYluxEgdC0GNueQK3x6D4pEr8GGDpqrmed

(这些凭证无效——我编造了一些看起来像真实Twitter和Mastodon凭证的凭证。)

发布到文件

这是最简单的发布技术,它主要用于测试和记录日志。file发布者接受一个配置设置:filename,写入的文件名。

publish:
    file:
        filename: "anniversary.txt"

发布到Twitter

要将您的机器人上传到Twitter,您需要为机器人创建一个Twitter账户,以机器人的身份登录,然后获取四个不同的值:consumer_keyconsumer_secretaccess_tokenaccess_token_secret。这四个值在bot.yaml中插入后,您将能够使用Twitter API向特定Twitter账户发布帖子。

获取这四个值可能很棘手,并且Twitter定期更改规则和流程。Bot Wiki提供了各种教程链接,用于设置这些内容。

一旦您有了这四个值,将它们放入bot.yaml中,您的机器人将能够发布到其Twitter账户。

发布到Mastodon实例

要将您的机器人连接到Mastodon,您需要为机器人创建一个Mastodon账户,以机器人的身份登录,然后获取四个值。

首先,api_base_url——这很简单,就是您创建账户时使用的Mastodon实例的URL。我喜欢使用botsin.space,这是一个专门为机器人创建的Mastodon实例。

然后您需要获取client_idclient_secretaccess_token。您可以通过以机器人的身份登录,转到设置页面,点击“开发”,并创建一个新的应用程序来获取这些值。(如果不起作用,请尝试Darius Kazemi的说明。)

一旦您有了这四个值,将它们放入bot.yaml中,您的机器人将能够发布到其Mastodon账户。

好的,现在回到您可以用Botfriend编写的酷炫机器人。

botfriend.test.publisher:测试您的发布凭证

botfriend.test.publisher脚本尝试测试您所有机器人的发布凭证以确保它们有效。如果一个机器人发布有问题,问题将在这里显示。

对于每个使用有效发布技术的机器人,您将得到一条以GOOD开头的行。对于每个损坏的发布技术,您将得到一条以FAIL开头的行。

在这个例子中,写入文件正常,但由于Twitter和Mastodon凭证是编造的,Twitter和Mastodon实际上不会接受它们。

$ botfriend.test.publisher
# GOOD Number Jokes file
# FAIL Number Jokes twitter: [{u'message': u'Bad Authentication data.', u'code': 215}]
# FAIL Number Jokes mastodon: {u'error': u'The access token is invalid'}

保留历史记录的机器人:船名

一些喜剧演员可以一次又一次即兴创作原创笑话。其他人则保留一个私人笑话文件:一个预先编制的笑话列表,他们可以根据需要从中抽取。

您不必在Botfriend机器人中编写大量生成代码,您可以根据自己的喜好生成一个历史记录。创建一个简单地按顺序逐个发布其历史记录项的机器人很容易。

如果您更擅长写作而不是编程,您可以直接在文本编辑器中编写历史记录。这样,您就可以创建一个Botfriend机器人而无需编写任何代码。

让我们创建一个简单的待办事项机器人,它将从网站 万艘船名 上抓取有趣的船名。(以下我将描述的正是我的真实机器人 船名 的工作方式。)

首先,为机器人创建一个目录

$ mkdir bots/boat-names

这个机器人非常简单,你不需要编写任何代码来编程其行为。只需创建一个空的 __init__.py 文件,这样 Botfriend 就知道这是一个机器人,而不是一个随机的目录。

$ touch bots/boat-names/__init__.py

就像数字笑话一样,船名机器人需要一个 bot.yaml 文件来告诉它在哪里发布以及多久发布一次。创建 bots/boat-names/bot.yaml 并将以下文本放入其中

name: Boat Names
publish:
    file: boat-names.txt
schedule:
    mean: 480
    stdev: 15

这里的计划与第一个示例机器人略有不同。第一个示例的帖子将每隔一小时发布一次。这个机器人每八小时(480分钟)平均发布一次,但也有一些随机变化——通常在十五或三十分钟之内。

现在,运行 botfriend.bots 将列出你所有的机器人。

$ botfriend.bots
# boat-names
# number-jokes

运行 botfriend.post 将告诉两个机器人如果它们想要的话就发布一些内容,但船名机器人永远不会发布任何内容,因为它没有任何待办事项和生成新帖子的逻辑。它不能自己想出笑话——你需要帮助它。

botfriend.backlog.load

botfriend.backlog.load 脚本允许你从文件中添加项目到机器人的待办事项中。最简单的方法是使用每行一个帖子的文本文件。

让我们创建一个待办事项文件。这可以放在任何地方,但我建议将其放在机器人的其余部分的同一目录中,以防万一出现错误并需要重新创建它。打开文件 bots/boat-names/backlog.txt 并在其中放入一些船名

Honukele
LA PARISIENNE
Stryss
Cozy Cat
Hull # 14
Always On Vacation
Sea Deuce
Bay Viewer
Tanden
Clean Livin'
Goodnight Moon
SPECIAL OCASSION
Innocent Dream

现在你可以加载待办事项了

$ botfriend.backlog.load boat-names --file=bots/boat-names/backlog.txt
# LOG | Backlog load script | Appended 13 items to backlog.
# LOG | Backlog load script | Backlog size now 13 items

一旦待办事项中有项目,botfriend.post 就会工作

# botfriend.post
# LOG | Boat Names | file | Published 2019-01-20 03:15 | Honukele

botfriend.backlog.show

botfriend.backlog.show 脚本将总结机器人的当前待办事项。它会显示待办事项中有多少个项目以及下一个是什么。

$ botfriend.backlog.show boat-names
# Boat Names | 12 posts in backlog
# Boat Names | LA PARISIENNE

botfriend.backlog.clear

botfriend.backlog.clear 脚本将完全清除机器人的待办事项。

$ bin/backlog.clear boat-names
# Boat Names | About to clear the backlog for Boat Names.
# Boat Names | Sleeping for 2 seconds to give you a chance to Ctrl-C.

$ bin/backlog.show boat-names
#  Boat Names | No backlog.

保持状态的机器人:Web Words

有时机器人需要做一些需要很长时间的事情,或者一些如果频繁发生可能会令人讨厌的事情。Botfriend 允许这些困难或令人讨厌的事情很少发生。结果将被存储在机器人的 状态 中,以供以后参考。

让我们创建另一个示例机器人。这个机器人的名字叫做 "Web Words"。它的任务是下载随机的网页并从中选择随机的短语。

$ mkdir bots/web-words

我们将把机器人的 "下载随机网页" 部分与 "选择随机短语" 部分分开。"选择随机短语" 部分将在机器人被要求发布内容时运行。"下载随机网页" 部分将每天运行一次,因为它涉及到向随机域名发送大量的 HTTP 请求。但是一旦你下载了一个网页,从中抽取随机片段就变得既快又简单。

这次让我们从 bot.yaml 文件开始

name: "Web Words"
schedule: 60
state_update_schedule: 1440
publish:
    file:
      filename: "web-words.txt"

这个机器人将根据其 schedule 发布,每小时一次(60分钟)。但是还有另一件事会在每天发生一次(每 1440 分钟):状态更新。

这是 Web Words 的代码。将其放入 bots/web-words/__init__.py

import random
import re
from olipy import corpora
import requests
from botfriend.bot import TextGeneratorBot

class WebWords(TextGeneratorBot):
    """A bot that pulls random words from a random webpage."""

    def update_state(self):
        """Choose random domain names until we find one that hosts a web page
        larger than ten kilobytes.
        """
        new_state = None
        while not new_state:

            # Make up a random URL.
            word = random.choice(corpora.words.english_words['words'])
            domain = random.choice(["com", "net", "org"])
            url = "http://www.%s.%s/" % (word, domain)

            try:
                self.log.info("Trying to get new state from %s" % url)
                response = requests.get(url, timeout=5)
                potential_new_state = response.content
                if len(potential_new_state) < 1024 * 10:
                    # This is probably a generic domain parking page.
                    self.log.info("That was too small, trying again.")
                    continue
                new_state = response.content
                self.log.info("Success!")
            except Exception as e:
                self.log.info("That didn't work, trying again.")
        return new_state

    def generate_text(self):
        """Choose some words at random from a webpage."""
        webpage = self.model.state

        # Choose a random point in the web page that's not right at the end.
        total_size = len(webpage)
        near_the_end = int(total_size * 0.9)
        starting_point = random.randint(0, near_the_end)

        # Find some stuff in the webpage that looks like words, rather than HTML.
        some_words = re.compile("([A-Za-z\s]{10,})")
        match = some_words.search(webpage[starting_point:])

        if not match:
            # Because we didn't find anything, we're choosing not to post
            # anything right now.
            return None
        data = match.groups()[0].strip()
        return data

Bot = WebWords

第一次告诉 Botfriend 为此机器人发布内容时,Botfriend 将调用 update_state() 方法。此方法可能尝试多次找到可用的网页,但最终会成功。

$ botfriend.post web-words
Web Words | Trying to get new state from http://www.stenographical.com/
Web Words | That was too small, trying again.
Web Words | Trying to get new state from http://www.bronchologic.org/
Web Words | That didn't work, trying again.
Web Words | Trying to get new state from http://www.dentonomy.org/
Web Words | That was too small, trying again.
Web Words | Trying to get new state from http://www.crummy.com/
Web Words | Success!
Web Words | file | Published 2019-01-10 01:45 | e experimental group

一旦状态建立,再次运行botfriend.post将不会每次都下载整个新网页。相反,Web Words将从它已经下载的网页中随机选择另一个字符串。

$ botfriend.post web-words --force
Web Words | file | Published 2019-01-10 01:46 an old superstition

这个机器人的状态在一天后过期(这在它的bot.yaml中设置)。在第一次调用update_state()后的24小时内,运行botfriend.post将导致Botfriend再次调用该方法。将下载全新的网页,在接下来的24小时内,所有Web Words的帖子都将来自这个新网页。

botfriend.state.show - 显示状态

此脚本简单地打印出一个机器人的当前状态。

$ botfriend.state.show web-words

botfriend.state.refresh - 刷新状态

您可以使用此脚本通过调用update_state()强制刷新机器人的状态,即使机器人的配置state_update_schedule表示尚未到调用该方法的时间。

$ botfriend.state.refresh web-words
# Web Words | Trying to get new state from http://www.choristoblastoma.org/
# ...

botfriend.state.set - 设置特定状态值

您可以使用此脚本将机器人的状态设置为一个特定值,而不是通过调用update_state()方法来设置状态。在这里,我们不是告诉Web Words从网页中随机选择字符串,而是告诉它从其自己的源代码中随机选择字符串。

$ bin/state.set web-words --file=bots/web-words/__init__.py

$ bin/post web-words --force
Web Words | file | Published 2019-01-21 1:56 | olipy import corpora

botfriend.state.clear - 清除状态

此脚本将完全删除机器人的脚本,使其看起来就像update_state()从未被调用过。

$ bin/state.clear web-words

更多示例

botfriend的源代码仓库包含了大约十个机器人的完整源代码,包括本文中涵盖的三个以及我运行的几个实际机器人。要尝试它们,请查看仓库,并将其bots.sample目录的内容复制到您的bots目录中。

$ git clone git@github.com:leonardr/botfriend.git
$ cp -r botfriend/bots.sample/* bots
$ ls bots
# a-dull-bot   boat-names         frances-daily   postcards
# ama          botfriend.sqlite   __init__.py     roller-derby
# anniversary  crowd-board-games  link-relations  serial-entrepreneur
# best-of-rhp  euphemism          number-jokes    web-words

每个机器人目录都包含一个README.md文件,解释该机器人的工作原理以及它使用的Botfriend的特殊功能(如果有的话)。

以下是一些示例机器人

  • 一个无聊的机器人 - 一个简单的文本生成机器人。
  • 我是机器人。AMA! - 一个机器人,为了不重复笑话而保持复杂的状态。
  • 周年纪念材料 - 一个使用大量不同类型输入的文本生成机器人。
  • RHP最佳 - 一个专门针对Twitter的机器人,除了选择性地转发另一个账户的内容外,什么都不做。
  • 船名 - 一个简单的机器人,从备份中发布。本文中描述的第二个示例机器人。
  • 群众桌游 - 一个解析RSS源并为每个条目创建帖子的机器人。
  • 委婉语机器人 - 一个从语法构建帖子的文本生成机器人。
  • 弗朗西斯每日 - 一个帖子计划在特定日期和时间的机器人,而不是随机或偶尔。在某些日子里,根本就没有帖子。
  • 垃圾邮件 - 一个跟踪网络档案馆中新增收藏的机器人,并随机从该收藏中的随机文本中选择页面进行发布。
  • 链接关系 - 一个定期抓取网页并发布关于它找到的新内容的机器人。
  • 数字笑话 - 本帮助文档中描述的第一个示例机器人,一个简单的文本生成机器人。
  • 播客轮盘 - 一个生成由其他播客集锦组成的RSS播客源文件的机器人。
  • 罗伊的明信片 - 一个发布图像和文本的机器人。
  • 死亡机器人3000 - 一个基于待办事项列表的机器人,它会以自定义格式加载待办事项列表,并动态格式化它,而不是加载字符串并发布字符串。
  • 连续企业家 - 一个复杂的文本生成机器人。
  • 网页词汇 - 本帮助文档中描述的第三个示例机器人。一个保存随机选择的网页状态信息的机器人。

定期发布

拥有几个机器人后,您需要定期运行 botfriend.post 脚本来保持新内容的流动。最好的方法是设置一个cron作业来安排每几分钟运行一次 botfriend.post 脚本。不要担心发布太频繁。需要发布内容的机器人将在准备好的时候发布。当 botfriend.post 运行时不需要立即发布内容的机器人会保持安静,等待时机。

以下是我的cron脚本的样子

#!/bin/bash
source $HOME/scripts/botfriend/env/bin/activate
botfriend.post

以下是如何使用cron作业每五分钟运行一次

*/5 * * * * /home/leonardr/scripts/botfriend/cron 2> /home/leonardr/scripts/botfriend_err

运行期间发生的任何错误都会附加到文件 botfriend_err 中,我可以定期检查。

这就差不多。本文件的其余部分只是在谈论Botfriend的一些高级功能,您可能第一次使用时不需要这些功能。

复杂的配置

让我们再次查看“数字笑话”机器人的 bot.yaml 文件。

name: Number Jokes
schedule: 60
publish:
  file:
    filename: number-jokes.txt

name 选项应该很容易理解——它是机器人的可读名称。现在让我们详细看看其他两个选项。

schedule

schedule 配置选项控制您的机器人应该多久发布一次。基本上有三种策略。

  1. schedule 设置为分钟数。(这是数字笑话所做的。)您的机器人将以确切的间隔发布,每次发布之间有这么多分钟。
  2. schedule 一个平均的分钟数。您的机器人将在随机确定的间隔发布,每次发布之间大约有这么多分钟,但有一定的随机变化。
  3. 为了微调随机性,您可以指定一个与平均值一起使用的 stdev。这设置了在计算下一次发布时应使用的标准偏差。将其设置为低数字,发布将在几乎 mean 分钟之间。将其设置为高数字,发布计划将有很大的变化。

如果您的机器人事先安排了所有发布(如 Frances Daily 所做的那样),则可以省略 schedule

state_update_schedule

还有一个相关的选项, state_update_schedule,您只有在机器人保持内部状态时才需要设置(如网页词汇所做的)。此选项与 schedule 的工作方式相同,但它不是控制机器人应该多久发布一次,而是控制您的 update_state() 方法被调用的频率。

其他配置设置

某些类型的机器人有其他特定的配置设置。例如,RetweetBot 的子类,如 Best of RHP,将使用一个特殊的配置设置,称为 retweet-user。它控制机器人转推哪个Twitter账户。播客轮盘 有许多配置设置,如 description,这些设置被复制到RSS源中。

您的机器人可以定义自己的自定义配置选项——配置对象被解析为YAML,并作为config参数传递给Bot构造函数。您可以在那里挑选出您想要的信息。

默认值

如果您在Botfriend目录中(位于botfriend.sqlite旁边)放置一个名为default.yaml的文件,则所有机器人将继承该文件中的值。

我几乎所有机器人都使用相同的Mastodon和Twitter客户端密钥(但应用密钥不同),并且我所有的Mastodon机器人都托管在botsin.space。我将这些配置设置保存在default.yaml中,这样我就不必在每个bot.yaml文件中重复它们。我的default.yaml看起来像这样

publish:
  mastodon: {api_base_url: 'https://botsin.space/', client_id: a, client_secret: b}
  twitter: {consumer_key: c, consumer_secret: d}

这样,在特定的bot.yaml文件中,我只需要填写在default.yaml中未指定的信息

name: My Bot
publish:
 mastodon:
  access_token: efg
 twitter:
  access_token: hij
  access_token_secret: klm
schedule:
 mean: 120

对API的编程访问

有时您需要使用一个网站的API来做的事情不仅仅是发帖。每个机器人都通过其publish设置配置了多个发布者,相应的Publisher对象可以从Bot对象内部通过self.publishers访问。一旦您有一个Publisher对象,原始API客户端始终可以通过Publisher.api访问。

请参阅IAmABot构造函数的示例。这个机器人需要一个Twitter API客户端来获取数据,所以它通过self.publishers查找Twitter发布者,并获取其.api,以供以后使用。

结论

Botfriend有很多功能我几乎没有触及或根本没有提到:重发其他Twitter账户的机器人,通过抓取网页内容来获取帖子内容的机器人,用于重新发布第一次未能正确发布的帖子的脚本。

但我所介绍的是您开始使用并看到Botfriend强大功能的主要功能。希望您喜欢它!

项目详情


下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分布

botfriend-0.7.0.tar.gz (106.5 kB 查看散列)

上传时间

构建分布

botfriend-0.7.0-py3-none-any.whl (111.3 kB 查看散列)

上传时间 Python 3

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面