Git Product home page Git Product logo

limbo's Introduction

Limbo

A Slack chatbot

Status

At the moment, I consider limbo to be feature complete, and the project is in maintenance mode. Every once in a while I come in and update the dependencies.

Contributions will be considered and may be accepted, you may want to email me because I might not notice your PR.

Installation

  1. Clone the repo
  2. Create a bot user if you don't have one yet, and copy the API Token
  3. export SLACK_TOKEN="your-api-token"
  4. make run (or make repl for local testing)
  5. Invite Limbo into any channels you want it in, or just message it in #general. Try typing !gif dubstep cat to test it out

kitten mittens

I recommend that you always run limbo in a virtualenv so that you are running in a clean environment.

Command Arguments

  • --test, -t: Enter command line mode to enter a limbo repl.
  • --hook: Specify the hook to test. (Defaults to "message").
  • -c: Run a single command.
  • --database, -d: Where to store the limbo sqlite3 database. Defaults to limbo.sqlite3.
  • --pluginpath, -pp: The path where limbo should look to find its plugins (defaults to /plugins).
  • --version, -v: Print a version number and exit

Environment Variables

  • SLACK_TOKEN: Slack API token. Required.
  • LIMBO_LOGLEVEL: The logging level. Defaults to INFO.
  • LIMBO_LOGFILE: File to log info to. Defaults to none.
  • LIMBO_LOGFORMAT: Format for log messages. Defaults to %(asctime)s:%(levelname)s:%(name)s:%(message)s.
  • LIMBO_PLUGINS: Comma-delimited string of plugins to load. Defaults to loading all plugins in the plugins directory (which defaults to "limbo/plugins")

Note that if you are getting an error message about not seeing environment variables, you may be running limbo as sudo, which will clear the environment. Use a virtualenv and always run limbo as a user process!

Commands

It's super easy to add your own commands! Just create a python file in the plugins directory with an on_message function that returns a string.

You can use the !help command to print out all available commands and a brief help message about them. !help <plugin> will return just the help for a particular plugin.

By default, plugins won't react to messages from other bots (just messages from humans). Define an on_bot_message function to handle bot messages too. See the example plugins for an easy way to define these functions.

These are the current default plugins:

Docker

  • How do I try out Limbo via docker?
    • @PeterGrace maintains a public build of limbo, available from the docker registry. Executing make docker_run will start the default bot.
    • make docker_stop will stop the bot
  • When I start the docker container, I see an error about unable to source limbo.env. Is this a problem?
    • No. The limbo.env file only exists when using Kubernetes with the included opaque secret recipe for storing your environment variables.
  • I'd like to develop plugins for Limbo, but would still like to use Docker to run the bot. Is there a quick way to add plugins to the bot?
    • Yes! Use the included Dockerfile.dev as a template, and simply build via make docker_build You'll then need to start the bot with your new_image_name, for example docker run -d -e SLACK_TOKEN=<your_token> new_image_name

Contributors

limbo's People

Contributors

adamghill avatar autoferrit avatar brandoncruz3 avatar esoares avatar fenwar avatar fsalum avatar hugovk avatar joegermuska avatar llimllib avatar markolson avatar mattfora avatar noise avatar petergrace avatar rod-dot-codes avatar stewpoll avatar stopspazzing avatar topher200 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

limbo's Issues

Support handling messages from other bots

We have a bunch of scenarios where we would like to monitor the output of other integrations (like jenkins build notifications) and it looks like out of the box limbo is filtering those out from ever reaching the plugins. I can understand scenarios where this might not be desirable, maybe it could be a config option?

twitter plugin

you should be able to have slask auto-post tweets from a list of users. Probably ought to have options to post all tweets and/or tweets that aren't @ mentions

Bot crashes

I've been getting this error occasionally with the bot crashing after a couple of days:

screen shot 2015-07-29 at 1 27 47 pm

Any reason why or how to fix this?

Better error message when no token found

The usual cause for an issue like #33 is that the environment variable either hasn't been set or hasn't been exported.

Handle the token KeyError better, and inform the user of what they can do to try and fix it.

(Possibly point them to filing a new issue on this repo?)

message length is not properly limited

The server will die if you cause a plugin to send a very long response. Slack docs say:

Clients should limit messages sent to channels to 4000 characters, which will always be under 16k bytes even with a message comprised solely of non-BMP Unicode characters at 4 bytes each.

Better documentation

The README is huge and unwieldy ATM. Find a better place and method to document plugins.

Module not loaded

On a basic installation I have many modules which do not work with some of the default plugins.

Example : !youtube madonna

Server logs :

myserver limbo # ./bin/limbo --pluginpath limbo/plugins/
2016-03-01 14:15:34,498:INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): www.youtube.com
2016-03-01 14:15:34,817:WARNING:limbo.limbo:Failed to run plugin <function on_message at 0x7f053e893f50>, module not loaded
2016-03-01 14:15:34,817:WARNING:limbo.limbo:<type 'exceptions.TypeError'>
2016-03-01 14:15:34,820:WARNING:limbo.limbo:Traceback (most recent call last):
  File "/usr/lib64/python2.7/site-packages/limbo-3.8.0-py2.7.egg/limbo/limbo.py", line 103, in run_hook
    h = hook(*args)
  File "limbo/plugins/youtube.py", line 30, in on_message
    return youtube(searchterm.encode("utf8"))
  File "limbo/plugins/youtube.py", line 15, in youtube
    r = requests.get(url)
  File "/usr/lib64/python2.7/site-packages/requests/api.py", line 65, in get
    return request('get', url, **kwargs)
  File "/usr/lib64/python2.7/site-packages/requests/api.py", line 49, in request
    response = session.request(method=method, url=url, **kwargs)
  File "/usr/lib64/python2.7/site-packages/requests/sessions.py", line 461, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib64/python2.7/site-packages/requests/sessions.py", line 573, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib64/python2.7/site-packages/requests/adapters.py", line 370, in send
    timeout=timeout
  File "/usr/lib64/python2.7/site-packages/requests/packages/urllib3/connectionpool.py", line 544, in urlopen
    body=body, headers=headers)
  File "/usr/lib64/python2.7/site-packages/requests/packages/urllib3/connectionpool.py", line 344, in _make_request
    self._raise_timeout(err=e, url=url, timeout_value=conn.timeout)
  File "/usr/lib64/python2.7/site-packages/requests/packages/urllib3/connectionpool.py", line 314, in _raise_timeout
    if 'timed out' in str(err) or 'did not complete (read)' in str(err):  # Python 2.6
TypeError: __str__ returned non-string (type Error)

Heroku config crashes

Here's what I get when I try to run what's in the Procfile on slask. The same thing happens when I push all the code to Heroku. Any help debugging this would be appreciated!

$ gunicorn slask:app
plugin: plugins/calc.py
attaching calc.<function on_message at 0x107084488> to message
plugin: plugins/emoji.py
attaching emoji.<function on_message at 0x1070f3668> to message
plugin: plugins/emojicodedict.py
plugin: plugins/flip.py
attaching flip.<function on_message at 0x1070f3758> to message
plugin: plugins/genesis.py
attaching genesis.<function on_message at 0x1070f3848> to message
plugin: plugins/gif.py
attaching gif.<function on_message at 0x1070f3938> to message
plugin: plugins/google.py
attaching google.<function on_message at 0x1070f3aa0> to message
plugin: plugins/help.py
attaching help.<function on_message at 0x1070f3b90> to message
plugin: plugins/image.py
attaching image.<function on_message at 0x1070f3cf8> to message
plugin: plugins/map.py
attaching map.<function on_message at 0x1070f3e60> to message
plugin: plugins/stock.py
attaching stock.<function on_message at 0x10710d050> to message
plugin: plugins/stockphoto.py
attaching stockphoto.<function on_message at 0x10710d140> to message
plugin: plugins/weather.py
attaching weather.<function on_message at 0x10710d230> to message
plugin: plugins/wiki.py
attaching wiki.<function on_message at 0x10710d320> to message
plugin: plugins/youtube.py
attaching youtube.<function on_message at 0x10710d488> to message
Failed to find application: 'slask'

Cleverbot integration (for lonely days)

What good is a bot if you can't talk to it!?

As discussed in #45 we determined how to figure out if a channel was a DM or a in a group/channel

I propose that we write a plugin that when a person mentions the bot in a group or channel, it defaults to a cleverbot plugin utilising this little library. (Only if no other response is being sent)

If it's in a DM, we default to that plugin if no response is being sent.

With that being said... it does make it a bit more difficult if group DMs have a similar ID to one-on-one DMs.... Group DMs you'd want to handle the same as groups

make run: KeyError: 'token' error

Sorry if this is on my end but I'm not sure why this is failing.
The make run command is failing with a KeyError: 'token' error. My ~/.bashrc file has the export line setup correctly I believe. That being said, after running make install limbo runs just fine ;)

Adding beautifulsoup4 4.3.2 to easy-install.pth file

Using /usr/local/lib/python2.7/dist-packages
Searching for importlib==1.0.3
Best match: importlib 1.0.3
Adding importlib 1.0.3 to easy-install.pth file

Using /usr/local/lib/python2.7/dist-packages
Searching for websocket-client==0.22.0
Best match: websocket-client 0.22.0
Adding websocket-client 0.22.0 to easy-install.pth file

Using /usr/local/lib/python2.7/dist-packages
Searching for requests==2.5.2
Best match: requests 2.5.2
Processing requests-2.5.2-py2.7.egg
requests 2.5.2 is already the active version in easy-install.pth

Using /usr/local/lib/python2.7/dist-packages/requests-2.5.2-py2.7.egg
Searching for backports.ssl-match-hostname==3.4.0.2
Best match: backports.ssl-match-hostname 3.4.0.2
Adding backports.ssl-match-hostname 3.4.0.2 to easy-install.pth file

Using /usr/local/lib/python2.7/dist-packages
Searching for six==1.8.0
Best match: six 1.8.0
Adding six 1.8.0 to easy-install.pth file

Using /usr/local/lib/python2.7/dist-packages
Finished processing dependencies for limbo==3.0.0a2
make clean
make[1]: Entering directory `/home/ubuntu/slask'
rm -rf build dist limbo.egg-info
make[1]: Leaving directory `/home/ubuntu/slask'
bin/limbo
Traceback (most recent call last):
  File "bin/limbo", line 17, in <module>
    main(args)
  File "/usr/local/lib/python2.7/dist-packages/limbo-3.0.0a2-py2.7.egg/limbo/limbo.py", line 165, in main
    server = init_server(args)
  File "/usr/local/lib/python2.7/dist-packages/limbo-3.0.0a2-py2.7.egg/limbo/limbo.py", line 154, in init_server
    slack = Client(config["token"])
KeyError: 'token'
make: *** [run] Error 1
ubuntu@ip-172-31-28-218:~/slask$ echo $SLACK_TOKEN
xoxb-REDACTED28-REDACTEDREDACTEDREDACTEDT

Create an emoji translator

i.e. if you type "I love to eat bananas", the plugin does something to try and convert that into a string of emoji. It probably involves a list of synonyms? Maybe even a word model? Or it does something really simple? I don't know, but it would be an awesome feature.

figlet plugin

create a plugin to generate text banners with pyfiglet. This will be an interesting test because we will have to create an attachment rather than just return the text (right?)

In [4]: pyfiglet.print_figlet("bananas")
 _
| |__   __ _ _ __   __ _ _ __   __ _ ___
| '_ \ / _` | '_ \ / _` | '_ \ / _` / __|
| |_) | (_| | | | | (_| | | | | (_| \__ \
|_.__/ \__,_|_| |_|\__,_|_| |_|\__,_|___/



In [5]: pyfiglet.print_figlet("bananas", font="slant")
    __
   / /_  ____ _____  ____ _____  ____ ______
  / __ \/ __ `/ __ \/ __ `/ __ \/ __ `/ ___/
 / /_/ / /_/ / / / / /_/ / / / / /_/ (__  )
/_.___/\__,_/_/ /_/\__,_/_/ /_/\__,_/____/

Adding new plugin just gives me errors?

When i add my own plugin, running '!help' just tried to run every single plugin and prints a bunch of errors similar to the below:

2015-10-29 10:04:08,502:INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): secure.flickr.com
2015-10-29 10:04:10,017:INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): encrypted.google.com
2015-10-29 10:04:10,581:INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): en.wikipedia.org
2015-10-29 10:04:10,852:INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): www.google.com
2015-10-29 10:04:11,114:INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): www.youtube.com
2015-10-29 10:04:11,415:INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): www.google.com
usage: limbo [-h] [--font FONT] [-l] [bannertext [bannertext ...]]
limbo: error: unrecognized arguments: option to list available fonts
2015-10-29 10:04:11,678:WARNING:limbo.limbo:Failed to run plugin <function on_message at 0x7f1d28ee8938>, module not loaded
2015-10-29 10:04:11,678:WARNING:limbo.limbo:<type 'exceptions.SystemExit'>
2015-10-29 10:04:11,679:WARNING:limbo.limbo:Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/limbo-3.7.0-py2.7.egg/limbo/limbo.py", line 99, in run_hook
    h = hook(*args)
  File "/usr/local/lib/python2.7/dist-packages/limbo-3.7.0-py2.7.egg/limbo/plugins/banner.py", line 40, in on_message
    return make_banner(match[0])
  File "/usr/local/lib/python2.7/dist-packages/limbo-3.7.0-py2.7.egg/limbo/plugins/banner.py", line 20, in make_banner
    ns = ARGPARSE.parse_args(query.split(" "))
  File "/usr/lib/python2.7/argparse.py", line 1704, in parse_args
    self.error(msg % ' '.join(argv))
  File "/usr/lib/python2.7/argparse.py", line 2374, in error
    self.exit(2, _('%s: error: %s\n') % (self.prog, message))
  File "/usr/lib/python2.7/argparse.py", line 2362, in exit
    _sys.exit(status)
SystemExit: 2

2015-10-29 10:04:11,681:INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): www.shutterstock.com
2015-10-29 10:04:12,276:INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): encrypted.google.com
2015-10-29 10:04:12,764:INFO:requests.packages.urllib3.connectionpool:Starting new HTTP connection (1): whatthecommit.co

Don't swallow message_changed messages

I'd like to see updates to messages as users edit them, but the core looks specifically for "message_changed" subtypes and ignores them. Why is this one subtype special enough to hide from me? :(

Easier way to send slack-formatted messages?

Right now it's possible to send slack-formatted messages via server.slack.post_message, as in the github plugin.

Messages sent via returns are sent with parse=full, which means that slack auto-links URLs, but also that plugins can't send formatted responses. Is there any easier way to allow plugins to send slack-formatted messages? Should there be more bandwidth between plugins and the kernel? Can it be done without adding too much complexity?

Sparked by #56

Avoid slack parsing when getting message

Do you know if it's possible to avoid slack parsing the message when you recieve a message? Ie a message like honshuu-api-lb1.wdc.sl will be parsed as <http://honshuu-api-lb1.wdc.sl|honshuu-api-lb1.wdc.sl> which isn't desirable.

please add a "time" or a "delayed" indicator to the stock plugin

for example when i get a quote for WBC.AX google returns this:

Westpac Banking Corp Fully Paid Ord. Shrs
ASX: WBC - 5 Jul., 10:24 am AEST
28.56AUDPrice decrease0.42 (1.47%)

limbo formats it very nicely - BUT - the actual quote provided by google is 20 minutes lag to current time. I just want to be reminded that it is a quote from the past -- "DELAYED QUOTE - 20MINS" or just show the time.. However is easiest to do it -- please.

Also - Thank you for a great product - am loving limbo ! :)

Heroku compatibility

It's a bad practice to store keys in source control and Heroku typically recommends (via the 12factor guidelines) to store them and other application configuration in environment variables. I modified the config.py to contain the following as a result:

import os
config = {
   "token": os.environ.get('TOKEN'),

Plugin to log chat history

Free Slack groups don't get unlimited history; slask should have the ability to save all chat history

Potential problem with private chats?

I haven't fully investigated this bug yet, but I think this happens when I invite the bot to a private channel and try interacting with it.

2015-01-26T23:05:19.055547+00:00 app[worker.1]: Traceback (most recent call last):
2015-01-26T23:05:19.055569+00:00 app[worker.1]:   File "slask.py", line 117, in <module>
2015-01-26T23:05:19.055590+00:00 app[worker.1]:     main(config)
2015-01-26T23:05:19.055626+00:00 app[worker.1]:   File "slask.py", line 108, in main
2015-01-26T23:05:19.055665+00:00 app[worker.1]:     client.rtm_send_message(event["channel"], response)
2015-01-26T23:05:19.055721+00:00 app[worker.1]:     return self.server.channels.find(channel).send_message(message)
2015-01-26T23:05:19.055696+00:00 app[worker.1]:   File "/app/slackclient/_client.py", line 36, in rtm_send_message
2015-01-26T23:05:19.055825+00:00 app[worker.1]: AttributeError: 'NoneType' object has no attribute 'send_message'

msg.get("text", "")

Why do the standard plugins use msg.get("text", "") instead of just referencing msg["text"]. They're DICT type objects after all and indexing in that manner would be more Pythonic as far as I can tell.

Create an RSS plugin

We should be able to tell slask, "follow this RSS feed and send a message when it's updated".

e.g. it would great if slask would monitor the Heroku status blog and send us a notification when Heroku has issues

slackrtm vs python-slackclient

Just out of curiousity I was wondering why you forked the python-slackclient and use that rather than the one that is officially maintained. Any particular reason?

Scheduler?

Is there any way to schedule jobs using limbo?

Kick channel lurkers and implement anti-idle

Our slack room has a problem with lurker ghosts, and I need to deal with them in a polite way. I propose the following:

For channels:

  1. Detect lurkers which have been idle (i.e. not said anything in the channel) for x number of days
  2. Send a DM and check to make sure they still have email, electricity, etc.
  3. Kick them from the channel if they haven't responded to the DM with "still alive" or some other response, and tell them why

For the team:

  1. Detect lurkers which have been idle (i.e. not said anything in any channel) for x number of days
  2. Publicly mention them in the default channel by making a joke about their inactivity
  3. Send a DM and inform their membership will be revoked if they don't wish to participate

I can begin working on this myself, but much time will pass before I'll be able to make a pull request, so thought I would put the idea out there for now.

command "!search/!google what is something" raise IndexError

Platform: OSX 10.11.3
Python version: Python 2.7.11

Problem:
All the following chats raise IndexError: list index out of range
!search what is apple
!search what is banana
!search what is slack
!google what is apple
!google what is banana
!google what is slack

But not all these pattern chatting raise IndexError. For instance, this is okay:
!search what is abc123
!google what is abc123

can't connect proxy

Hi,
i tryed to launch your bot under proxy but i can't connect,
i can't find where define it in the code.

can you help me please?
this is the error i have:
Traceback (most recent call last):
File "bin/limbo", line 17, in
main(args)
File "/Library/Python/2.7/site-packages/limbo-3.5.1-py2.7.egg/limbo/limbo.py", line 247, in main
server.slack.rtm_connect()
File "/Library/Python/2.7/site-packages/slackrtm-0.2.1-py2.7.egg/slackrtm/client.py", line 14, in rtm_connect
self.server.rtm_connect()
File "/Library/Python/2.7/site-packages/slackrtm-0.2.1-py2.7.egg/slackrtm/server.py", line 61, in rtm_connect
self.connect_slack_websocket(self.ws_url)
File "/Library/Python/2.7/site-packages/slackrtm-0.2.1-py2.7.egg/slackrtm/server.py", line 80, in connect_slack_websocket
raise SlackConnectionError
slackrtm.server.SlackConnectionError
make: *** [run] Error 1

Create a "stats" plugin

Can create graphs of channel statistics. Ideas for statistics:

  • Activity per room/person
  • links submitted, duplicate links submitted, % thereof

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.