Twitter回复生成颜色网格的机器人
#教程 #twitter #python #tweepy

又是另一个曲折的教程,但我们没有抱怨。

一点背景:我喜欢创建随机分形艺术(任何人),我可以花几个小时盯着一个人看所有不同的东西。那么,分享我的创作的更好方法是什么?当然是一个Twitter机器人,但还可以让它做其他事情。

Preview

您可以通过在Twitter上发推文给@machineation来尝试一下自己的自我。该机器人将使用您的用户名放置,然后将其用作种子,以基于用户名生成唯一的颜色网格。让我们开始。

要求:

  • python> = 3.10
  • Twitter开发人员帐户(教程未涵盖)
  • Twepy
  • numpy
  • 枕头

如果您不熟悉Twitter开发人员帐户,请Check this,因为创建开发人员帐户,应用程序和获得身份验证。

让我们首先安装所需的软件包。

pip install tweepy numpy pillow

安装了所有内容后,让我们创建一个称为“ bot.py”的文件,但是您可以将其命名为您喜欢的任何东西,然后让我们导入我们需要的内容。

import tweepy, random, time, os, pathlib, numpy, hashlib
from PIL import Image

之后,我们需要添加身份验证并使用Tweepy创建API对象。您可以在docs中阅读有关曲折的身份验证

您的密钥是秘密的。不要将它们包括在脚本中,而将它们上传到任何公开可见的云中。使用.env或其他一些方法来保留秘密。为简单起见,本教程不涵盖

auth = tweepy.OAuthHandler("xxxx", "xxxx")
auth.set_access_token("xxxx", "xxxx")

#create API object
api = tweepy.API(auth, wait_on_rate_limit=True)
  • WAIT_ON_RATE_LIMIT是否要自动等待速率限制

为了不多次回复相同的推文,也只会提到机器人尚未看到的提及,我们将确保保存最后一提的推文ID。我们将其保存到文件中,以便即使我们停止了机器人,然后恢复了,我们将从尚未看到的提及开始,而不是从一开始就开始。
让我们创建2个函数。一个用于从文件中读取ID的一个,一个用于存储ID。

def read_last_seen(FILE_NAME):
  file_read = open(FILE_NAME,'r')
  last_seen_id = int(file_read.read().strip())
  file_read.close()
  return last_seen_id

def store_last_seen(FILE_NAME, last_seen_id):
  file_write = open(FILE_NAME,'w')
  file_write.write(str(last_seen_id))
  file_write.write("\n")
  file_write.close()
  return

请注意,读取ID的第一个功能采用一个参数,即文件名,并且存储ID的功能采用2个参数,文件名和ID。将来,如果您想拥有更多存储和读取不同内容的功能,则可以调用相同的函数并更改参数,我们将用“ data”更改“ last_seen_id”。

现在,让我们创建功能以创建用户名创建颜色网格。我选择将其编码为单独的函数。

def make_grid(handle):
    hash = int(hashlib.sha256(handle.encode('utf-8')).hexdigest(), 16) % 10**8
    numpy.random.seed(hash)
    # Generate 100x100 grid of random colours
    grid = numpy.random.randint(0,256, (100,100,3), dtype=numpy.uint8)
    im = Image.fromarray(grid).resize((1600,1600), resample=Image.Resampling.NEAREST)

    im.save(os.path.join(os.path.dirname(__file__), "grids/") + handle + '.png')
  • “ hander”:我们将传递给函数的用户名的参数。
  • “ hash”:我们将使用SHA256用作用户名将其用作Numpy的随机种子。
  • “网格”:使用numpy,我们创建一个带有随机颜色的网格(用用户名哈希播种)。您可以将其制成任何想要的尺寸。
  • “ im”:使用枕头从数据中创建1600x1600图像。您可以使用任何想要的尺寸。

然后,我们将png图像保存在同一目录中的文件夹中,称为“网格”,用户名为文件名。

下一步,让我们创建将:

的功能
  1. 自上次存储的Tweet ID以来提到的提及。
  2. 提及的循环。
  3. 存储Tweet ID。
  4. 检查该推文是否不是我们的机器人。
  5. 检查推文是否包含特定单词。
  6. 检查该推文是否不包含额外的单词,并带有消息。
  7. 根据匹配的单词来回复推文。

这意味着您可以根据推文内容(命令)扩展机器人来完成其他操作。但是首先,我们需要设置一些变量。

def grid_tweet():
    bot_id = xxxxxxxxxxxx
    FILE_NAME = os.path.join(os.path.dirname(__file__), "grid_last_seen.txt")
    words = ["make grid"]
    message = "Here is your unique color grid, @{}"
    grid_unknown = "@{} If you want a grid, You just need to tweet 'make grid' to Me without any other words and I will create and send You one."

让我们浏览它们:

bot_id

我们设置此变量,以便我们可以检查推文作者是否不是我们的机器人。这样,我们确保如果我们的机器人发推文我们要寻找的相同单词,则该机器人不会回复自身。您可以通过不同的方式获得机器人ID,但这是一个简单的

通过浏览器
您可以转到Twitter上的“机器人”页面,右键单击页面内的任何地方,然后单击“检查”,然后在元素中搜索“标识符”,看起来像This

"identifier": "1572580999673831426"

文件名

这是我们将用来读取和存储最后一个提及推文ID的文件。这将用于调用我们已经创建的功能并将变量传递给它们。然后,如果需要,我们可以为不同的功能提供不同的文件。

我们正在寻找的单词列表。您可以使用逗号添加更多分离。对于我们的示例,我们只使用“ Make Grid”。

信息

我们将在答复中包含的消息。我们最终使用{}以后将其格式化并添加用户名。

grid_unknown

除了“ Make Grid”之外,该推文还没有额外的单词,

另一个消息。还使用{}以后使用用户名进行格式。

现在让我们创建其余的代码。

    while True:
        # Finding tweets that mention our bot
        mentions = api.mentions_timeline(since_id=read_last_seen(FILE_NAME)) 
        # Iterating through each mention tweet
        for mention in mentions:
            # Save the tweet id in the file
            store_last_seen(FILE_NAME, mention.id)
            # Check to see if the tweet author is not our bot
            if mention.author.id != bot_id:
                # Check if the tweet has any of the words we defined in our list after converting the tweet to lower case
                if True in [word in mention.text.lower() for word in words]:
                    # Removes the first part of the mention which is our bot username like so @username
                    command = mention.text.lower().split(' ',1)[1]
                    # Act based on the matched word/command. can later be used to add more functionality.
                    match command:
                        case "make grid":
                            try:
                                # Prints the username and tweet
                                print(f"{mention.author.screen_name} - {mention.text}")
                                print('Creating Grid')
                                # Calls our make_grid function and passing the username.
                                make_grid(mention.author.screen_name)
                                # Set the media to the image created by our function
                                media = os.path.join(os.path.dirname(__file__), "grids/") + mention.author.screen_name + '.png'
                                print("Attempting to reply...")
                                # Reply with the message after formatting to include username and the media
                                api.update_status_with_media(message.format(mention.author.screen_name), media, in_reply_to_status_id=mention.id_str)
                                print("Successfully replied :)")
                            # Error handling. for now it just prints the error.
                            except Exception as exc:
                                print(exc)
                        # If the tweet contains extra words in addition to our command
                        case other:
                            try:
                                print('tweet contains other words')
                                # Reply with the grid_unknown message
                                api.update_status(grid_unknown.format(mention.author.screen_name), in_reply_to_status_id=mention.id_str)
                                print("Successfully replied with explaination :)")
                            except Exception as exc:
                                print(exc)
        # Sleep for 2 minutes
        time.sleep(120)

所以最后,我们的文件看起来像这样:

import tweepy, random, time, os, pathlib, numpy, hashlib
from PIL import Image

auth = tweepy.OAuthHandler("xxxx", "xxxx")
auth.set_access_token("xxxx", "xxxx")

#create API object
api = tweepy.API(auth, wait_on_rate_limit=True)

def read_last_seen(FILE_NAME):
  file_read = open(FILE_NAME,'r')
  last_seen_id = int(file_read.read().strip())
  file_read.close()
  return last_seen_id

def store_last_seen(FILE_NAME, last_seen_id):
  file_write = open(FILE_NAME,'w')
  file_write.write(str(last_seen_id))
  file_write.write("\n")
  file_write.close()
  return    

def make_grid(handle):
    hash = int(hashlib.sha256(handle.encode('utf-8')).hexdigest(), 16) % 10**8
    numpy.random.seed(hash)
    # Generate 100x100 grid of random colours
    grid = numpy.random.randint(0,256, (100,100,3), dtype=numpy.uint8)
    im = Image.fromarray(grid).resize((1600,1600), resample=Image.Resampling.NEAREST)

    im.save(os.path.join(os.path.dirname(__file__), "grids/") + handle + '.png')
def grid_tweet():
    bot_id = xxxxxxxxxxxx
    FILE_NAME = os.path.join(os.path.dirname(__file__), "grid_last_seen.txt")
    words = ["make grid"]
    message = "Here is your unique color grid, @{}"
    grid_unknown = "@{} If you want a grid, You just need to tweet 'make grid' to Me without any other words and I will create and send You one."
    while True:
        # Finding tweets that mention our bot
        mentions = api.mentions_timeline(since_id=read_last_seen(FILE_NAME)) 
        # Iterating through each mention tweet
        for mention in mentions:
            # Save the tweet id in the file
            store_last_seen(FILE_NAME, mention.id)
            # Check to see if the tweet author is not our bot
            if mention.author.id != bot_id:
                # Check if the tweet has any of the words we defined in our list after converting the tweet to lower case
                if True in [word in mention.text.lower() for word in words]:
                    # Removes the first part of the mention which is our bot username like so @username
                    command = mention.text.lower().split(' ',1)[1]
                    # Act based on the matched word/command. can later be used to add more functionality.
                    match command:
                        case "make grid":
                            try:
                                # Prints the username and tweet
                                print(f"{mention.author.screen_name} - {mention.text}")
                                print('Creating Grid')
                                # Calls our make_grid function and passing the username.
                                make_grid(mention.author.screen_name)
                                # Set the media to the image created by our function
                                media = os.path.join(os.path.dirname(__file__), "grids/") + mention.author.screen_name + '.png'
                                print("Attempting to reply...")
                                # Reply with the message after formatting to include username and the media
                                api.update_status_with_media(message.format(mention.author.screen_name), media, in_reply_to_status_id=mention.id_str)
                                print("Successfully replied :)")
                            # Error handling. for now it just prints the error.
                            except Exception as exc:
                                print(exc)
                        # If the tweet contains extra words in addition to our command
                        case other:
                            try:
                                print('tweet contains other words')
                                # Reply with the grid_unknown message
                                api.update_status(grid_unknown.format(mention.author.screen_name), in_reply_to_status_id=mention.id_str)
                                print("Successfully replied with explaination :)")
                            except Exception as exc:
                                print(exc)
        # Sleep for 2 minutes
        time.sleep(120)

if __name__ == "__main__":
    print('The mighty Machineation is starting...')
    grid_tweet()

就是这样..现在您要做的就是从:
开始 pyhton bot.py
并从不同的帐户到您的机器人说“ Make Grid”,它应该在几分钟内用颜色网格进行答复。