使用Slack bot的Python asyncio [英] Python asyncio with Slack bot

查看:56
本文介绍了使用Slack bot的Python asyncio的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用asyncio创建一个简单的Slack机器人,主要使用示例

I'm trying to make a simple Slack bot using asyncio, largely using the example here for the asyncio part and here for the Slack bot part.

这两个示例都可以单独工作,但是当我将它们放在一起时,我的循环似乎没有循环:它经历了一次,然后消失了.如果 info 是一个长度等于1的列表,这种情况发生在在聊天室中键入带有bot的聊天室中键入消息时,协程应该被触发,但永远不会触发.(协程现在正在尝试做的所有事情就是打印消息,如果消息中包含"/time",它将使机器人在所要求的聊天室中打印时间).键盘中断也不起作用,我每次都必须关闭命令提示符.

Both the examples work on their own, but when I put them together it seems my loop doesn't loop: it goes through once and then dies. If info is a list of length equal to 1, which happens when a message is typed in a chat room with the bot in it, the coroutine is supposed to be triggered, but it never is. (All the coroutine is trying to do right now is print the message, and if the message contains "/time", it gets the bot to print the time in the chat room it was asked in). Keyboard interrupt also doesn't work, I have to close the command prompt every time.

这是我的代码:

import asyncio
from slackclient import SlackClient
import time, datetime as dt

token = "MY TOKEN"
sc = SlackClient(token)

@asyncio.coroutine
def read_text(info):
    if 'text' in info[0]:
        print(info[0]['text'])
        if r'/time' in info[0]['text']:
            print(info)
            resp = 'The time is ' + dt.datetime.strftime(dt.datetime.now(),'%H:%M:%S')
            print(resp)
            chan = info[0]['channel']
            sc.rtm_send_message(chan, resp)


loop = asyncio.get_event_loop()
try:
    sc.rtm_connect()
    info = sc.rtm_read()
    if len(info) == 1:
        asyncio.async(read_text(info))
    loop.run_forever()

except KeyboardInterrupt:
    pass
finally:
    print('step: loop.close()')
    loop.close()

我认为是循环部分坏了,因为它似乎从未进入协程.因此,也许问这个问题的一种更简短的方式是关于try:语句的作用是什么,它可以防止它像我遵循的asyncio示例中那样发生循环?关于 sc.rtm_connect()的东西,它不喜欢吗?

I think it's the loop part that's broken, since it never seems to get to the coroutine. So maybe a shorter way of asking this question is what is it about my try: statement that prevents it from looping like in the asyncio example I followed? Is there something about sc.rtm_connect() that it doesn't like?

我是asyncio的新手,所以我可能在做一些愚蠢的事情.这甚至是尝试解决此问题的最佳方法吗?最终,我希望该机器人执行一些需要花很长时间才能进行计算的事情,并且希望它在这段时间内保持响应能力,因此我认为我需要使用异步或各种线程,但是我愿意接受更好的建议.

I'm new to asyncio, so I'm probably doing something stupid. Is this even the best way to try and go about this? Ultimately I want the bot to do some things that take quite a while to compute, and I'd like it to remain responsive in that time, so I think I need to use asyncio or threads in some variety, but I'm open to better suggestions.

非常感谢,亚历克斯

推荐答案

我将其更改为以下内容,并且有效:

I changed it to the following and it worked:

import asyncio
from slackclient import SlackClient
import time, datetime as dt

token = "MY TOKEN"    
sc = SlackClient(token)

@asyncio.coroutine
def listen():
    yield from asyncio.sleep(1)
    x = sc.rtm_connect()
    info = sc.rtm_read()
    if len(info) == 1:
        if 'text' in info[0]:
            print(info[0]['text'])
            if r'/time' in info[0]['text']:
                print(info)
                resp = 'The time is ' + dt.datetime.strftime(dt.datetime.now(),'%H:%M:%S')
                print(resp)
                chan = info[0]['channel']
                sc.rtm_send_message(chan, resp)

    asyncio.async(listen())


loop = asyncio.get_event_loop()
try:
    asyncio.async(listen())
    loop.run_forever()

except KeyboardInterrupt:
    pass
finally:
    print('step: loop.close()')
    loop.close()

不能完全确定为什么要修复它,但是我更改的关键是将 sc.rtm_connect()调用放入协程并使其成为 x = sc.rtm_connect().最后,我还从自身调用了 listen()函数,这似乎使它永远循环,因为如果我将其取出,机器人将不响应.我不知道这是不是应该设置这种方式,但是在处理较早的命令时,它的确似乎继续接受命令,我的闲聊看起来像这样:

Not entirely sure why that fixes it, but the key things I changed were putting the sc.rtm_connect() call in the coroutine and making it x = sc.rtm_connect(). I also call the listen() function from itself at the end, which appears to be what makes it loop forever, since the bot doesn't respond if I take it out. I don't know if this is the way this sort of thing is supposed to be set up, but it does appear to continue to accept commands while it's processing earlier commands, my slack chat looks like this:

me [12:21 AM] 
/time

[12:21] 
/time

[12:21] 
/time

[12:21] 
/time

testbotBOT [12:21 AM] 
The time is 00:21:11

[12:21] 
The time is 00:21:14

[12:21] 
The time is 00:21:16

[12:21] 
The time is 00:21:19

请注意,它不会丢失我的任何/time 请求,如果不是异步执行此操作,则会丢失该请求.另外,如果有人尝试复制此内容,您会注意到,如果键入"/",则松弛会弹出内置命令菜单.我通过在前面输入一个空格来解决这个问题.

Note that it doesn't miss any of my /time requests, which it would if it weren't doing this stuff asynchronously. Also, if anyone is trying to replicate this you'll notice that slack brings up the built in command menu if you type "/". I got around this by typing a space in front.

感谢您的帮助,如果您知道这样做的更好方法,请告诉我.这似乎不是一个非常优雅的解决方案,并且在我使用cntrl-c键盘中断来结束它之后,无法重新启动该机器人-它说

Thanks for the help, please let me know if you know of a better way of doing this. It doesn't seem to be a very elegant solution, and the bot can't be restarted after I use the a cntrl-c keyboard interrupt to end it - it says

Task exception was never retrieved
future: <Task finished coro=<listen() done, defined at asynctest3.py:8> exception=AttributeError("'NoneType' object has no attribute 'recv'",)>
Traceback (most recent call last):
  File "C:\Users\Dell-F5\AppData\Local\Programs\Python\Python35-32\Lib\asyncio\tasks.py", line 239, in _step
    result = coro.send(None)
  File "asynctest3.py", line 13, in listen
    info = sc.rtm_read()
  File "C:\Users\Dell-F5\Envs\sbot\lib\site-packages\slackclient\_client.py", line 39, in rtm_read
    json_data = self.server.websocket_safe_read()
  File "C:\Users\Dell-F5\Envs\sbot\lib\site-packages\slackclient\_server.py", line 110, in websocket_safe_read
    data += "{0}\n".format(self.websocket.recv())
AttributeError: 'NoneType' object has no attribute 'recv'

我想这意味着它没有很好地关闭websocket.无论如何,那只是一个烦恼,至少主要问题已经解决.

Which I guess means it's not closing the websockets nicely. Anyway, that's just an annoyance, at least the main problem is fixed.

亚历克斯

这篇关于使用Slack bot的Python asyncio的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆