attzonko / mmpy_bot Goto Github PK
View Code? Open in Web Editor NEWA python-based chatbot for Mattermost (http://www.mattermost.org).
License: MIT License
A python-based chatbot for Mattermost (http://www.mattermost.org).
License: MIT License
It is currently not possible (or documented) to remove emojis sent using e.g.: message.react("pizza")
@response_to(r"(?P<first_name>.+) (?P<last_name>.+)")
def get_name(message, first_name, last_name):
message.reply(f"Your name is {first_name} {last_name}.")
>>> "Your name is Lena Smith."
or
@response_to(r"(?P<first_name>.+) (?P<last_name>.+)")
def get_name(message, *args):
message.reply(f"Your name is {args[0]} {args[1]}.")
>>> "Your name is Lena Smith."
or
@response_to(r"(?P<first_name>.+) (?P<last_name>.+)")
def get_name(message, *args):
keys = ["first_name", "last_name"]
kwargs = dict(zip(keys, args))
message.reply(f"Your name is {kwargs["first_name"]} {kwargs ["last_name"]}.")
>>> "Your name is Lena Smith."
@response_to(r"(?P<first_name>.+) (?P<last_name>.+)")
def get_name(message, **kwargs):
message.reply(f"Your name is {kwargs['first_name']} {kwargs['last_name']}.")
>>> "Your name is Lena Smith."
Hi,
I can't figure this out: How do I send a arbitrary file to a channel?
I want to post an image (test.png) as a message, but the example in the readme seems to fail for non-txt files. Could you provide me with an example?
We have a fun need of sending a kick command if a message gets a fixed number of a defined reaction (let's say hammer)
I don't see any get_reaction method, is there a way to do this already ?
Hello,
I have a feature request: The bot responds to help
with the implemented respond_to
functions, parsing the documentation string of these. This is very nice, but would it be possible to extend this functionality to listen_to
functions aswell?
My bot mostly uses listen_to
, with a defined prefix, e.g. !mybot <command>
, it would be nice if the help function could show the info for those too.
If you provide me the steps necessary for this, I could try to send a PR.
Describe the bug
message.react creates a new message in the channel with the specified emoji shown in quote block styling.
How To Reproduce
message.react(':joy:')
Expected behavior
Expected behaviour is that the message that triggered the event would have an attached reaction from the mmpy_bot.
Operating Environment (please complete the following information):
Additional context
Example of the bug in action: https://cl.ly/3I0f20222I2A
Hi,
I'm feeling totally idiot, but I just can't get this BOT running.
According to the README, I've created two files:
I have filled the required credentials to the *settings.py file, changed the API resource URL to v4 to use the new API. I set every information correctly, but there's a hole in the README.
How do I pass this information to run.py?
I tried importing it
from mattermost_bot_settings import *
and I also tried copying all the vars with their values to the run.py itself, but still nothing.
Reading through the traceback (which is quite long) I feel like my provided settings are completely ignored.
Here's a few interesting lines from the traceback:
requests.exceptions.ConnectionError: HTTPConnectionPool(host='mm.example.com', port=80): Max retries exceeded with url: /api/v4/users/login (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x000001D2B500A5F8>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed',))
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='mm.example.com', port=80): Max retries exceeded with url: /api/v4/users/login (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x000001D2B500A5F8>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed',))
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x000001D2B500A5F8>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed
It has to be something trivial, but I just can't get my head around it.
Any help, please?
Hi All,
I have two questions:
In mattermost I just created a bot but it did not require any email. ALl it asked was name and at the end it gave me a token so what should I place for bot_email?
where do I create the mmpy_bot_settings.py file?
Describe the bug
Calling a function that uses respond_to and message.reply, the bot adds an extra "@" at the beginning of the response.
For example, if I send @bot roll 100
The bot responds: @@gravufo 35
How To Reproduce
Use any respond_to function with a message.reply.
Expected behavior
No double @
Operating Environment (please complete the following information):
Additional context
Mattermost api version: v4
I am implementing a remind feature through the chat bot. Till now I am able to use listen_to and respond_to to set up reminders for myself using the scheduler.
What I want to do is something like : remind @xyz "check in your code" at October 19 6 pm.
I haven't found any documentation on how to automate sending of DMs to other users.
Hi,
I was wondering if anyone has discovered any function to get the username of the person who is communicating with the bot. For example: If there are bunch of people in a channel talking to a bot; the bot could spit out the usernames or USER_ID ... ?
I completed the function of uploading files and sending messages with attached files, and manually tested them. But I don't know how to write a test case. Is there a test writing guide?
Hey @seLain , what do you think about renaming this repo to be able to release to pypi as a new package. I was thinking that we can remove v3 support completely and push a new pypi package which only supports v4.
Name proposal: mmpy_bot
Thoughts?
Hello,
I am trying to start the bot and connect it to my mattermost server. I followed the directions on the main github page (the README) and have configured my mmpy_bot_settings.py file with the correct values. I cannot get the bot to start and I think it might be due to being behind a corporate proxy - however, I do have the appropriate {http,https}_proxy
env vars set.
mmpy_bot_settings config:
SSL_VERIFY = False
BOT_URL = 'https://myurl.example.com/api/v4'
BOT_LOGIN = '[email protected]'
BOT_PASSWORD = 'password'
BOT_TEAM = 'testing'
When I run the command: MATTERMOST_BOT_SETTINGS_MODULE=mmpy_bot_settings mmpy_bot
, the following output appears:
[04/04/2019 16:19:36] connected to mattermost
[04/04/2019 16:19:36] loading plugin "mmpy_bot.plugins"
[04/04/2019 16:19:36] registered listen_to plugin "help_request" to "^!help$"
[04/04/2019 16:19:36] registered respond_to plugin "help_request" to "^!help$"
[04/04/2019 16:19:36] registered respond_to plugin "hello_reply" to "hello$"
[04/04/2019 16:19:36] registered listen_to plugin "hello_reply_formatting" to "hello_formatting$"
[04/04/2019 16:19:36] registered respond_to plugin "hello_reply_formatting" to "hello_formatting"
[04/04/2019 16:19:36] registered listen_to plugin "hello_send" to "hello$"
[04/04/2019 16:19:36] registered respond_to plugin "hello_decorators" to "hello_decorators"
[04/04/2019 16:19:36] registered listen_to plugin "hello_decorators" to "hello_decorators"
[04/04/2019 16:19:36] registered respond_to plugin "web_api_reply" to "hello_web_api"
[04/04/2019 16:19:36] registered listen_to plugin "hello_comment" to "hello_comment"
[04/04/2019 16:19:36] registered listen_to plugin "hello_react" to "hello_react"
[04/04/2019 16:19:36] registered listen_to plugin "hello_reply_threaded" to "hello_reply_threaded"
[04/04/2019 16:19:36] registered respond_to plugin "busy_reply" to "^busy|jobs$"
[04/04/2019 16:19:36] registered listen_to plugin "info_request" to "^!info$"
[04/04/2019 16:19:36] registered respond_to plugin "info_request" to "^!info$"
[04/04/2019 16:19:36] registered respond_to plugin "sleep_reply" to "sleep (.*)"
[04/04/2019 16:19:36] registered respond_to plugin "users_access" to "^admin$"
[04/04/2019 16:19:36] registered respond_to plugin "ping_reply" to "^ping$"
[04/04/2019 16:19:36] job running thread started
[04/04/2019 16:19:36] keep active thread started
After about a minute or so, the following exception occurs:
Traceback (most recent call last):
File "/usr/local/bin/mmpy_bot", line 11, in <module>
sys.exit(main())
File "/usr/local/lib/python2.7/dist-packages/mmpy_bot/cli.py", line 18, in main
b.run()
File "/usr/local/lib/python2.7/dist-packages/mmpy_bot/bot.py", line 41, in run
self._dispatcher.loop()
File "/usr/local/lib/python2.7/dist-packages/mmpy_bot/dispatcher.py", line 133, in loop
'user_removed']):
File "/usr/local/lib/python2.7/dist-packages/mmpy_bot/mattermost.py", line 250, in messages
if not self.connect_websocket():
File "/usr/local/lib/python2.7/dist-packages/mmpy_bot/mattermost.py", line 237, in connect_websocket
self._connect_websocket(url, cookie_name='MMAUTHTOKEN')
File "/usr/local/lib/python2.7/dist-packages/mmpy_bot/mattermost.py", line 246, in _connect_websocket
else ssl.CERT_NONE})
File "/usr/local/lib/python2.7/dist-packages/websocket/_core.py", line 514, in create_connection
websock.connect(url, **options)
File "/usr/local/lib/python2.7/dist-packages/websocket/_core.py", line 223, in connect
options.pop('socket', None))
File "/usr/local/lib/python2.7/dist-packages/websocket/_http.py", line 122, in connect
sock = _tunnel(sock, hostname, port, auth)
File "/usr/local/lib/python2.7/dist-packages/websocket/_http.py", line 289, in _tunnel
raise WebSocketProxyException(str(e))
websocket._exceptions.WebSocketProxyException: Connection is already closed.
I am running the following version of mmpy_bot: 1.3.4
And the following version of mattermost: Version: 5.8.0
I am also running my mattermost behind an NGINX reverse proxy if that matters at all.
Describe the bug
If settings module contains non-ASCII characters, Bot will fail to start.
How To Reproduce
In the settings module, set DEFAULT_REPLY = "سلام"
.
Operating Environment:
Trace
Traceback (most recent call last):
File "src\bot.py", line 5, in <module>
from mmpy_bot.bot import Bot, MattermostClient, PluginsManager,\
File "%PROJECT_PATH%\assistant-bot\venv\src\mmpy-bot\mmpy_bot\bot.py", line 15, in <module>
from mmpy_bot import settings
File ""%PROJECT_PATH%\assistant-bot\venv\src\mmpy-bot\mmpy_bot\settings.py", line 62, in <module>
exec(open(filename).read())
File "C:\Program Files\Python36\lib\encodings\cp1252.py", line 23, in decode
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 303: character maps to <undefined>
Describe the bug
The message.update() method seems to be broken.
How To Reproduce
I'm using the following snippet and expect the message "I'm waiting" to change after two seconds.
@listen_to('hello', re.IGNORECASE)
def hello_reply(message):
timeout_message = message.send("I'm waiting.")
import time
time.sleep(2)
message.update("Timeout.", timeout_message['id'])
However nothing changes. I did look up the API and it seems that a PUT
should be used for this kind of request: https://api.mattermost.com/#tag/posts%2Fpaths%2F~1posts~1%7Bpost_id%7D%2Fput. mmpy_bot
currently uses a POST
request.
I did a quick test to try and fix it in knedlsepp@2e2ad50, but this didn't resolve the issue.
Message.get_username() without a parameter should return the Message's sender username, the current behavior is returning the username for the owner of the web-hook. The difference is in _body['data']['post']['user_id'] vs _body['data'].get('sender_name', '').strip()
When I try to define a plugin using a single python module: custom_plugin.py
, without using a python package (dir + __init__.py
), using PLUGINS = [ 'custom_plugin' ]
does not work. The log shows loading plugin "custom_plugins"
, but no plugin is actually registered.
Operating Environment:
I am adding this issue based on getting a direct e-mail contact. Will ask the submitter to provide additional information here, so we can track it. I decided to add this myself as it seemed like a good first issue someone might have.
Describe the bug
I switched from Slack to Mattermost and like to use this bot to archive some tasks.
But sadly i failed to add a command. (I just did some basic stuff in python right automation.)
How To Reproduce
import re
from mmpy_bot.bot import listen_to
from mmpy_bot.bot import respond_to
@respond_to('^\!introduce$')
@listen_to('^\!introduce$')
def introduce(message):
message.reply('Hello i am a bot.')
Start the Bot, with cd ~/mmpy_bot; MATTERMOST_BOT_SETTINGS_MODULE=local_settings mmpy_bot
Got this Error
[08/06/2018 15:04:58] registered listen_to plugin "hello_react" to "hello_react"
[08/06/2018 15:04:58] No module named 'mmpy_bot.plugins.intro'
Traceback (most recent call last):
File "/usr/lib/python3.4/site-packages/mmpy_bot/bot.py", line 82, in _load_plugins
_module = importlib.import_module(module)
File "/usr/lib64/python3.4/importlib/__init__.py", line 109, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 2254, in _gcd_import
File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
File "<frozen importlib._bootstrap>", line 2224, in _find_and_load_unlocked
ImportError: No module named 'mmpy_bot.plugins.intro'
[08/06/2018 15:04:58] keep active thread started
hello.py
i get an error: Bad command "!introduce", Here is what I currently know how to do:
Expected behavior
The bot to listen and respond to the keyword 'introduce' and respond with "Hello i am a bot."
Operating Environment (please complete the following information):
Using multiple decorators as specified in this doc breaks the automatic documentation using __doc__
strings for the "help" default message.
Code:
# file: 'plugins/My_Plugin.py'
@respond_to('my command', re.IGNORECASE)
@allowed_users(*ALLOWED_USER_LIST)
def my_command(message):
"""Description of 'my command'."""
message.reply("Result of running 'my command'.")
Command:
@bot_name my command
Result:
Bad command "help", Here is what I currently know how to do:
Plugin: **Plugins.My_Plugin**
- `my job` - None
...
Command:
@bot_name my command
Expected Result:
Bad command "help", Here is what I currently know how to do:
Plugin: **Plugins.My_Plugin**
- `my job` - Description of 'my command'.
...
@allowed_users
decorator.@allowed_users(*ALLOWED_USER_LIST)
@respond_to('my command', re.IGNORECASE)
@allow_only_direct_message
decorator as illustrated in the documentation the "help" default answer erroneously prints the command under Plugin: Mmpy_Bot.Utils
.Code:
# file: 'plugins/My_Plugin.py'
@respond_to('^selfupdate')
@allow_only_direct_message()
@allowed_users(*settings.ADMIN_USERS)
def self_update(message):
# some code
message.reply('Update was done')
Command:
@bot_name my command
Result:
Bad command "help", Here is what I currently know how to do:
Plugin: **Plugins.Utils**
- `^selfupdate` - None
...
Expected Result:
Bad command "help", Here is what I currently know how to do:
Plugin: **Plugins.My_Plugin**
- `^selfupdate` - None
...
@Sebastien-Meiffren Reported the following issue:
Traceback (most recent call last):
File "C:/Users/chuiv/PycharmProjects/bot_mattermost/run.py", line 5, in <module>
Bot().run()
File "C:\Users\chuiv\PycharmProjects\bot_mattermost\mattermost_bot\bot.py", line 29, in __init__
settings.SSL_VERIFY)
File "C:\Users\chuiv\PycharmProjects\bot_mattermost\mattermost_bot\mattermost_v4.py", line 110, in __init__
self.login(team, email, password)
File "C:\Users\chuiv\PycharmProjects\bot_mattermost\mattermost_bot\mattermost.py", line 184, in login
self.user = self.api.login(team, email, password)
File "C:\Users\chuiv\PycharmProjects\bot_mattermost\mattermost_bot\mattermost_v4.py", line 25, in login
self.load_initial_data()
File "C:\Users\chuiv\PycharmProjects\bot_mattermost\mattermost_bot\mattermost_v4.py", line 34, in load_initial_data
self.default_team_id = self.teams[0]['id']
IndexError: list index out of range
If I print self.teams = self.get('/teams')
, I get an empty array []
If I connect to the webclient like a normal person / user, everything works fine.
including examples to send message via webhook with webhook_id parameter. ( #74 )
This is a Feature Request
I really don't found a prper feature request place, so i took this path.
So, is it possible ( technically speaking ) to have plugins reload in runtime ?
When dealing with external auths and multiple plugin developers, sometimes would be useful rehash the plugin in runtime, at least in development mode.
Hi,
I tried a basic example, but I get error for some messages.
Unhandled exception in thread started by <bound method WorkerPool.do_work of <mmpy_bot.utils.WorkerPool object at 0x7f963c061d30>>
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/mmpy_bot/utils.py", line 31, in do_work
self.func(msg)
File "/usr/local/lib/python3.7/site-packages/mmpy_bot/dispatcher.py", line 103, in dispatch_msg
self._default_reply(msg)
File "/usr/local/lib/python3.7/site-packages/mmpy_bot/dispatcher.py", line 151, in _default_reply
key = v.__module__.title().split('.')[1]
IndexError: list index out of range
My code:
import re
from mmpy_bot.bot import Bot
from mmpy_bot.bot import listen_to
from mmpy_bot.bot import respond_to
@respond_to('hi', re.IGNORECASE)
def hi(message):
message.reply('I can understand hi or HI!')
@respond_to('I love you')
def love(message):
message.reply('I love you too!')
@listen_to('Can someone help me?')
def help_me(message):
message.reply('Yes, I can!')
if __name__ == "__main__":
Bot().run()
What am I missing?
Thanks
Hello!
According to the docs an IGNORE_NOTIFIES
parameter can be defined in the settings wich stablishes wich users will the bot ignore. In our case, this is not working.
With the original mattermost bot module I could override this behaviour by using message.get_username()
, but this doesn't seem to be working with mmpy_bot
, at least when the message comes from a post made by an "Incoming Webhook" (has the "bot" flag next to the username).
Let me know if you need more information!
Cheers!
can send Multiple instructions in one message
Mattermost v5.15.0
Name: mmpy-bot Version: 1.3.4
CentOS Linux release 7.6.1810 (Core
The "@@andy" which is returned with the listen_to may be breaking the format. I did try a blank line at the start of the payload string.
The bot code:
# -*- encoding: utf-8 -*-
from mmpy_bot.bot import respond_to, listen_to
@respond_to('^!test$')
@listen_to('^!test$')
def help_request(message):
payload = """ | Component | Tests Run | Tests Failed |
|:-----------|:-----------:|:-----------------------------------------------|
| Server | 948 | :white_check_mark: 0|
| Web Client | 123 | :warning: 2 [(see details)](http://linktologs) |
| iOS Client | 78 | :warning: 3 [(see details)](http://linktologs) | """
message.reply(payload)
Andy
Describe the bug
Error while trying to reply using reply_webapi()
method.
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/mmpy_bot/dispatcher.py", line 89, in dispatch_msg
func(Message(self._client, msg, self._pool), *args)
File "/home/administrator/haitiano/it_plugins/epec_plugin.py", line 46, in cortes_epec
icon_url='https://www.epec.com.ar/favicon.ico',
File "/usr/local/lib/python3.5/dist-packages/mmpy_bot/dispatcher.py", line 255, in reply_webapi
self.send_webapi(self._gen_reply(text), *args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/mmpy_bot/dispatcher.py", line 258, in send_webapi
url = self._get_webhook_url_by_id(self._get_first_webhook())
File "/usr/local/lib/python3.5/dist-packages/mmpy_bot/dispatcher.py", line 247, in _get_first_webhook
return hooks[0].get('id')
KeyError: 0
How To Reproduce
Create a plugin that replys to some keyword, try to answer with an attachment as shown in the readme:
from mmpy_bot.bot import respond_to
@respond_to('webapi')
def webapi_reply(message):
attachments = [{
'fallback': 'Fallback text',
'author_name': 'Author',
'author_link': 'http://www.github.com',
'text': 'Some text here ...',
'color': '#59afe1'
}]
message.reply_webapi(
'Attachments example', attachments,
username='Mattermost-Bot',
icon_url='https://goo.gl/OF4DBq',
)
# Optional: Send message to specified channel
# message.send_webapi('', attachments, channel_id=message.channel)
Expected behavior
The message should be answered with an attachment.
Operating Environment (please complete the following information):
Additional context
Add any other context about the problem here [e.g. Settings for your bot, API Version]
Hi, is there some way to have mmpy_bot read email content and post in a channel?
This may be unintended functionality, but right now we have a few reminders that get posted by a webhook. It would be nice if we could just get that integrated into our bot so we're managing that all in one place.
Is it acceptable to wire into the dispatcher directly? And, if so, what would that look like?
If this is beyond the scope of the module, let me know and we'll stick to webhooks.
Just wanted to get some opinions. I think we should completely remove support for API V3.
Any strong objections why we should not do it?
Describe the bug/question
Hi,
I want to use Unicode character like äöü, but I get an error:
UnicodeEncodeError: 'ASCII' codec can't encode character u'\xfc' in position 64: ordinal not in range(128)
Because it wants to convert it to ASCII.
How To Reproduce
send a message to your bot with öäü or other.
Expected behavior
working?
Operating Environment (please complete the following information):
Is it possible to use non-ASCII characters?
If a bot tries to login before it joins any team, there will be error in MattermostAPIv4.load_initial_data
Should mmpy_bot
allows this bot to login ?
A possible way to do that :
def load_initial_data(self):
! self.teams = self.get('/users/me/teams')
+ self.teams_channels_ids = {}
+ if len(self.teams) == 0:
+ return
self.default_team_id = self.teams[0]['id']
- self.teams_channels_ids = {}
for team in self.teams:
self.teams_channels_ids[team['id']] = []
# get all channels belonging to each team
for channel in self.get_channels(team['id']):
self.teams_channels_ids[team['id']].append(channel['id'])
Or should mmpy_bot
throws defined exception ?
I don't know if I'm doing anything wrong, but the same config that used to work with the main repo doesn't work with the fork here. Here's the settings I use with it
SSL_VERIFY = True # Whether to perform SSL cert verification
BOT_URL = 'http://chat.domain.org/api/v4' # with 'http://' and with '/api/v3' path. without trailing slash. '/api/v1' - for version < 3.0
BOT_LOGIN = '[email protected]'
BOT_PASSWORD = 'botpassword'
BOT_TEAM = 'botteam' # possible in lowercase
Anything I could try? Thanks!
edit: This might not be related to your fork, but we've updated mattermost recently and I can't really test master for this as it simply doesn't support api/v4 I think.
mmpy_bot v1.3.2 does not appear to depend on schedule, which came into being with #68.
Reproduction is fairly straight forward. Create a new virtualenv, pip install mmpy_bot, and try to import a symbol from mmpy_bot.bot
.
$ pip install mmpy_bot
$ python -c 'from mmpy_bot.bot import listen_to'
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/tristan/tmp/repo/.pyenv/local/lib/python2.7/site-packages/mmpy_bot/bot.py", line 18, in <module>
from mmpy_bot.scheduler import schedule
File "/home/tristan/tmp/repo/.pyenv/local/lib/python2.7/site-packages/mmpy_bot/scheduler.py", line 1, in <module>
import schedule
ImportError: No module named schedule
(This should be reproducible anywhere, but in case it matters, I'm running on Ubuntu 16.04.)
Maybe add ability to login with a Personal access token?
https://github.com/Vaelor/python-mattermost-driver python driver if needed.
Similar blocks of code found in 2 locations. Consider refactoring.
Mattermost 5.12 has recently been released, including Bot Accounts.
short version:
longer version:
I managed to configure mmpy_bot to use a bot account, using the token instead of the password, and it connects and answers direct messages.
However, in another channel where the bot can talk, it does not answer to messages including a mention (e.g. @bot
). I suspect that it could be related to the impossibility to really "add to channel" the bot in the Mattermost interface.
Describe the bug
socket.error websocket exception isn't handled
How To Reproduce
Take down the mattermost server unexpectedly, I think.
Expected behavior
A clear and concise description of what you expected to happen.
Operating Environment (please complete the following information):
Additional context
Unhandled exception in thread started by <bound method Bot._keep_active of <mmpy_bot.bot.Bot object at 0x7f1482553d90>>
--
Traceback (most recent call last):
File "/var/tmp/src/mmpy-bot/mmpy_bot/bot.py", line 45, in _keep_active
self._client.ping()
File "/var/tmp/src/mmpy-bot/mmpy_bot/mattermost.py", line 262, in ping
self.websocket.ping()
File "/usr/local/lib/python2.7/dist-packages/websocket/_core.py", line 281, in ping
self.send(payload, ABNF.OPCODE_PING)
File "/usr/local/lib/python2.7/dist-packages/websocket/_core.py", line 240, in send
return self.send_frame(frame)
File "/usr/local/lib/python2.7/dist-packages/websocket/_core.py", line 265, in send_frame
l = self._send(data)
File "/usr/local/lib/python2.7/dist-packages/websocket/_core.py", line 430, in _send
return send(self.sock, data)
File "/usr/local/lib/python2.7/dist-packages/websocket/_socket.py", line 117, in send
return sock.send(data)
File "/usr/lib/python2.7/ssl.py", line 687, in send
v = self._sslobj.write(data)
socket.error: [Errno 32] Broken pipe
Hello,
First, thank you for this bot, it's a so nice work :)
I'm trying to add an interactive button to my bot and I'm wondering how to catch the answer (meaning button pressed by user)…. I used attachments, It works fine to print buttons but what to do next ? Should I develop a webservice to deal with action response (to url of integration in attachment) ? So how to keep context of current message ?
To explain, my bot is searching some information in a database for a given query written by the user. When answers from database are ambigous, the bot asks the user to choose correct answer using buttons (It could be menu). So, I would like to give back the good answer but I don't understand what to do next… An input ?
Thank you in advance !
Describe the bug
reply
doesn't expose any way to configure the pid
or parent_id
of the message being replied to: https://github.com/attzonko/mmpy_bot/blob/master/mmpy_bot/dispatcher.py#L267
By itself this isn't unreasonable, as it would be a clumsy developer experience to always have to plumb that around. However, the method doesn't automatically infer pid
/parent_id
either, and following the call chain from reply
to send
to channel_msg
shows pid
is never correctly populated:
https://github.com/attzonko/mmpy_bot/blob/master/mmpy_bot/mattermost.py#L223
Expected behavior
I would expect message.reply
and message.reply_webhook
to preserve the chat thread by automatically populating the correct parent_id
in the POST
request.
Additional context
This is accurate as of 1.3.3.
Describe the bug
Traceback (most recent call last): File "/bin/mmpy_bot", line 10, in <module> sys.exit(main()) File "/usr/lib/python2.7/site-packages/mmpy_bot/cli.py", line 17, in main b = bot.Bot() File "/usr/lib/python2.7/site-packages/mmpy_bot/bot.py", line 31, in __init__ settings.WS_ORIGIN) File "/usr/lib/python2.7/site-packages/mmpy_bot/mattermost.py", line 200, in __init__ self.api = MattermostAPI(url, ssl_verify, token) File "/usr/lib/python2.7/site-packages/mmpy_bot/mattermost.py", line 21, in __init__ requests.packages.urllib3.disable_warnings( AttributeError: 'module' object has no attribute 'urllib3'
I have SSL_Verify disabled (False) because I have certificate problems.
MMPY will not start.
How To Reproduce
run mmpy
WEBHOOK_ID = 'ner9...f3ad'
and other normal settings.
Expected behavior
mmpy started
Operating Environment (please complete the following information):
Hopefully, you can work with that and can help me.
This is a proposal for supporting multiple plugins listening to the same regex. Previous discussion can be found in #24 (comment) .
This is not an emergent proposal. Further discussion on actual needs, implementation details, and trade-off are welcomed.
If there are two plugin functions listening to the same regexp pattern, only the latest loaded function will be kept in PluginsManager
. Details can be found in Bot.listen_to()
.
Bot.listen()
decorator function will keep only one function for one regex pattern.
def listen_to(regexp, flags=0):
def wrapper(func):
r = re.compile(regexp, flags | re.DEBUG)
PluginsManager.commands['listen_to'][r] = func
logger.info(
'registered listen_to plugin "%s" to "%s"', func.__name__, regexp)
return func
return wrapper
In some cases, if we need two unrelated plugins being used which listen to the same regex, this can be an issue.
A workaround solution can be made by delegation :
@listen_to('hello$')
def hello_dispatcher(message):
hello_send(message)
hello_louder(message)
def hello_send(message):
message.send('hello channel!')
def hello_louder(message):
message.send('HELLO CHANNEL!!!')
If you need hello_send
and hello_louder
to execute concurrently, simply executing them in different subprocesses.
Enabling PluginsManager
to keep multiple plugins listening to the same regex provides a direct solution to this issue. In this solution, we can have :
@listen_to('hello$')
def hello_send(message):
message.send('hello channel!')
@listen_to('hello$')
def hello_louder(message):
message.send('HELLO CHANNEL!!!')
And both hello_send
and hello_louder
will be loaded.
Pros
Cons
Hello guys!
Just to let you know that I'm seeing a lot of debug messages in the logs, like this:
Jul 19 09:15:59 localhost systemd[1]: Started MyBot Bot.
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] Starting new HTTP connection (1): mm.sanitized.domain:80
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] http://mm.sanitized.domain:80 "POST /api/v4/users/login HTTP/1.1" 200 None
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] Starting new HTTP connection (1): mm.sanitized.domain:80
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] http://mm.sanitized.domain:80 "GET /api/v4/users/me/teams HTTP/1.1" 200 None
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] Starting new HTTP connection (1): mm.sanitized.domain:80
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] http://mm.sanitized.domain:80 "GET /api/v4/users/me/teams/r7ya5p1ou3dzmfthgzg1mmxj7o/channels HTTP/1.1"
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] utf-8 confidence = 0.99
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] SHIFT_JIS Japanese confidence = 0.01
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] EUC-JP Japanese confidence = 0.01
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] GB2312 Chinese confidence = 0.01
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] EUC-KR Korean confidence = 0.01
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] CP949 Korean confidence = 0.01
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] Big5 Chinese confidence = 0.01
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] EUC-TW Taiwan confidence = 0.01
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] windows-1251 Russian confidence = 0.01
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] KOI8-R Russian confidence = 0.01
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] ISO-8859-5 Russian confidence = 0.03650638685916099
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] MacCyrillic Russian confidence = 0.01
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] IBM866 Russian confidence = 0.01
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] IBM855 Russian confidence = 0.0
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] ISO-8859-7 Greek confidence = 0.0
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] windows-1253 Greek confidence = 0.0
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] ISO-8859-5 Bulgairan confidence = 0.07417675668362249
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] windows-1251 Bulgarian confidence = 0.0
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] TIS-620 Thai confidence = 0.13267655059192984
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] ISO-8859-9 Turkish confidence = 0.5548939726869081
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] windows-1255 Hebrew confidence = 0.0
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] windows-1255 Hebrew confidence = 0.0
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] windows-1255 Hebrew confidence = 0.0
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] utf-8 confidence = 0.99
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] SHIFT_JIS Japanese confidence = 0.01
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] EUC-JP Japanese confidence = 0.01
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] GB2312 Chinese confidence = 0.01
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] EUC-KR Korean confidence = 0.01
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] CP949 Korean confidence = 0.01
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] Big5 Chinese confidence = 0.01
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] EUC-TW Taiwan confidence = 0.01
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] Starting new HTTP connection (1): mm.sanitized.domain:80
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] http://mm.sanitized.domain:80 "GET /api/v4/users/me HTTP/1.1" 200 None
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] connected to mattermost
Jul 19 09:16:00 localhost python3[7672]: [07/19/2018 09:16:00] loading plugin "asc_plugins"
Jul 19 09:16:00 localhost python3[7672]: LITERAL 33
Jul 19 09:16:00 localhost python3[7672]: LITERAL 99
Jul 19 09:16:00 localhost python3[7672]: LITERAL 108
Jul 19 09:16:00 localhost python3[7672]: LITERAL 105
Jul 19 09:16:00 localhost python3[7672]: LITERAL 109
Jul 19 09:16:00 localhost python3[7672]: LITERAL 97
Jul 19 09:16:00 localhost python3[7672]: MAX_REPEAT 0 MAXREPEAT
Jul 19 09:16:00 localhost python3[7672]: IN
Jul 19 09:16:00 localhost python3[7672]: CATEGORY CATEGORY_SPACE
Jul 19 09:16:00 localhost python3[7672]: SUBPATTERN 1
Jul 19 09:16:00 localhost python3[7672]: MAX_REPEAT 1 MAXREPEAT
Jul 19 09:16:00 localhost python3[7672]: ANY None
I'm using this code to start the bot (via a systemd service):
from mmpy_bot.bot import Bot
import logging
import sys
logging.basicConfig(**{
'format': '[%(asctime)s] %(message)s',
'datefmt': '%m/%d/%Y %H:%M:%S',
'level': logging.DEBUG,
'stream': sys.stdout,
})
if __name__ == "__main__":
Bot().run()
Feature request:
To introduce a decorator @allowed_channels
that takes a list of white-listed channels, similarly to the @allowed_users
decorator.
Something similar to the following pseudocode:
def allowed_channels(*channels):
"""Decorator that limits the bot to the specified list of channels."""
def plugin(func):
def wrapper(message, *args, **kw):
is_direct_message = message.is_direct_message()
is_in_allowed_channel = message.get_channel_name() in channels
if not is_direct_message and not is_in_allowed_channel:
return message.reply(f'This bot can only be used inside the following channel(s): {", ".join(channels)}.')
return func(message, *args, **kw)
return wrapper
return plugin
I have an interaction with the bot working, however sometimes the bot returns more characters than my channel will allow. Is there a decorator I can use, or a certain syntax I can use to have the bot wait for a response from the user in the same function? Or does this require a DB etc.. due to being stateful?
I make a plugin which use the reply_webapi function, but it failed when call MattermostAPI.hooks_list.
I found that the api link('/teams/%s/hooks/incoming/list') is version 3, so I change the link to version 4 ('/hooks/incoming'), but it returned 403 error.
How to use the api? I have tried to use Postman or Chrome to test the "List incoming webhooks" api, but I got 401 or 403 error.
I've found that deprecated function or module are used(imp module and execfile function). I have replaced these in my own project (Python 3). Does the project consider python version compatibility issues?
Hi, using MattermostAPIv4, I have an issue when using the info plugin as the get_team_id()
method defined in the dispatcher is trying to use an undefined attribute team_id
:
mmpy_bot/mmpy_bot/dispatcher.py
Line 212 in e273636
Stacktrace:
Traceback (most recent call last):
File "/home/user/src/mmpy_bot/dispatcher.py", line 89, in dispatch_msg
func(Message(self._client, msg, self._pool), *args)
File "/home/user/src/mmpy_bot/plugins/info.py", line 9, in info_request
message.send('TEAM-ID: `%s`' % message.get_team_id())
File "/home/user/src/mmpy_bot/dispatcher.py", line 212, in get_team_id
return self._client.api.team_id
AttributeError: 'MattermostAPIv4' object has no attribute 'team_id'
Have I missed something or is there something to fix ?
Thank you.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.