Code Monkey home page Code Monkey logo

mattermost-poll's Introduction

Mattermost Poll

Build Status codecov

Provides a slash command to create polls in Mattermost.

Example

By default, a poll will only offer the options Yes and No. However, users can also specify an arbitrary number of choices:

Example

Choices are separated by --.

Additional options

  • --noprogress: Do not display the number of votes until the poll is ended
  • --public: Show who voted for what at the end of the poll
  • --votes=X: Allows users to place a total of X votes. Default is 1. Each individual option can still only be voted once.
  • --bars: Show results as a bar chart at the end of the poll.
  • --locale=X: Use a specific locale for the poll. Supported values are en and de. By default it's the users language.

Help

/poll help will display full usage options. Only visible to you.

Set the "Autocomplete Hint" in the Slash Command settings to See "/poll help" for full usage options

Requirements

  • Python >= 3.6
  • Flask
  • Tornado
  • A WSGI server (e.g. gunicorn or uWSGI)

Setup

Copy settings.py.example to settings.py and customise your settings.

Start the server:

gunicorn --workers 4 --bind :5000 app:app
  1. In Mattermost go to Main Menu -> Integrations -> Slash Commands and add a new slash command with the URL of the server including the configured port number, e.g. http://localhost:5000.
  2. Choose POST for the request method.
    • Optionally add the generated token to your settings.py (requires server restart).
  3. Edit your Mattermost config.json to include "localhost" in the "AllowedUntrustedInternalConnections" setting, e.g. "AllowedUntrustedInternalConnections": "localhost"

To resolve usernames in --public polls and to provide localization, the server needs access to the Mattermost API. For this a personal access token must be provided in your settings.py. Which user provides the token doesn't matter, e.g. you can create a dummy account. If no token is provided --public polls will not be available and all texts will be english.

Docker

To integrate with mattermost-docker:

cd mattermost-docker
git submodule add [email protected]:M-Mueller/mattermost-poll.git poll

and add the following to the services section:

  poll:
    build:
      context: poll
      args:
        - mattermost_url="http://web"
        - mattermost_tokens=['<mattermost-token-1>', '<mattermost-token-2>']
        - mattermost_pa_token="<personal-access-token>"
    ports:
      - "5000:5000"
    restart: unless-stopped
    volumes:
      - ./volumes/poll:/app/volume:rw
  1. In Mattermost go to Main Menu -> Integrations -> Slash Commands and add a new slash command with the URL of the server including the configured port number, e.g. http://poll:5000.
  2. Choose POST for the request method.
  3. Edit your Mattermost config.json to include "poll" in the "AllowedUntrustedInternalConnections" setting, e.g. "AllowedUntrustedInternalConnections": "poll"

mattermost-poll's People

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

mattermost-poll's Issues

Option to make votes public

The should be an option to show who voted for what at the end of the poll. Useful when ordering food for example.

local bars are not shown

Leaving BAR_IMG_URL at its default value (None) leads to a broken image, as it unsuccessfully tries to serve http://localhost:5001/img/bar.png:

bildschirmfoto-20190214181338-889x702

Am I doing something wrong here?

allow team- or system-admins to end all polls

Right now, only the user who started the poll can close it, others (even if system administrator) get a message that they are not allowed to do so.
Could you add an option that allows to end other user's polls at least for system- or team-admins?
Thanks!

Listen on IP address other than 0.0.0.0

Thanks for writing this. I was kinda waiting for someone to.

I'd like to make some integrations to run on 127.0.0.2 so that I can run the integrations locally but limit MM to connect to 127.0.0.2, and not the default loopback:

https://github.com/mattermost/docs/blob/master/source/administration/config-settings.rst#allow-untrusted-internal-connections-to

Tornado needs this specified as
http_server.listen(settings.WEBSERVER_PORT, address='127.0.0.2')

Do you want me to make a PR for this, i.e. to add another setting?

Polls create but all options return 400

Just set up the integration and it's half-working.

I can create polls which show up as expected, but no users are able to add responses, and the "End Poll" button is unresponsive as well.

Requests on button press are made to /api/v4/posts/some26characterstring/actions/someother26characterstring

Button clicks return an HTTP 400 and a response like

{
  "id":"api.post.do_action.action_integration.app_error",
  "message":"Action integration error",
  "detailed_error":"",
  "request_id":"hsn5igzp6frndkyrchjzf4ssra",
  "status_code":400
}

Turning on file logging in settings.py shows no output whatsoever on button press so I'd imagine the posts are not hitting the app.

Any ideas on where to start looking for further debugging would be appreciated.

Command with a trigger of 'poll' failed

Hey,

I have problems starting a poll. I have installed all requirements and updated everything. Mattermost is also running on the newest version. Mattermost-poll is installed on the same server as Mattermost. The error I get in the mattermost.log is [EROR] /api/v4/commands/execute:command code=500 rid=cu9cbomk83rjbdf8scunptoghr uid=jh5y7phshbgu7qa8xwfj3uro6h ip='MyIPaddress' Command with a trigger of 'poll' failed [details: Post http://localhost:5001: address forbidden]
I also checked the Mattermost-poll error.log but no error is logged, except I try opening http://'Serveraddress':5001 then I get WARNING:tornado.access:405 GET / (192.168.33.1) 2.33ms

I hope you have an idea what the problem could be...

Best,
Max

Allow multiple mattermost tokens

If you want this MM integration to be added to more than one MM team you need the ability to specify more than just one token in the config file. As for now you have to add a slash command manually to each MM team which generates an individual token. You would have to run the same mattermost-poll python web application several times. One for each MM team.

I think it would make sense most to amend the code so that you can specify several MM tokens MATTERMOST_TOKEN argument in settings.py. Has anyone already implemented such thing and cares for a pull request? Otherwise I would change the code and publish it here in case you are interested for merge?

translations

I'd like to have this nice poll plugin in languages different than English (in particular: in German). Happy to translate it to German but not sure if and how this works. It would be great if the poll can "just" use the same mattermost's language setting. Thanks!

Dockerfile - configuration by environment variables.

Hello @M-Mueller, thank You for maintaining this project!
My issue is a kind of feature request - in present setup, Dockerfile contains ARG sections for setting configuration of mattermost-poll. It's not the best way of doing that, because builded image isn't universal. Maybe better idea will be making environmental variables placeholders in app.py, so after building an image, we could provide configuration dynamically.
Please, share Your opinion about this idea.

show participant's votes while poll is running

Using the --public option one can see who voted for which option after the poll is closed. It would be great if this information is already available while the poll is still running (e.g., to easily see who hasn't yet voted). Thanks!

Show error if poll is invalid

If a poll id is not in the database any more, clicking the poll buttons doesn't produce any feedback. Instead an error message should be displayed.

Poll ends after one vote

Hey,

we now have the problem that after one person votes, the vote is ended immediately and not even the voting summary is shown. The error.log and the mattermost.log do not show any errors ..

I hope you have an idea what the problem could be...

Best,
Max

again Failed to resolve usernames

hi!
Again have a problem
the error is written in the log:

[2018-03-27 10:20:31,751] ERROR in app: Username query failed: HTTPConnectionPool(host='web', port=8000): Max retries exceeded with url: /api/v4/users/ids (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f7cd472d780>: Failed to establish a new connection: [Errno 111] Connection refused',))

Mattermost API v4

We are planning on updating to Mattermost Server v5.0. On step on a successfull migration is to make sure that all integrations use Mattermost API v4 endpoints. It is described here: https://api.mattermost.com/#tag/APIv3-Deprecation. I have looked through the code and can find only on api endpoint call which already goes to v4:

/api/v4/users/ids

So I'd guess that the integration is good to go for Mattermost 5.0. Would be much appreciated if you could confirm that?

mattermost-poll as docker image

I have tried to use the mattermost-poll directly and it was working fine but when i have created as docker image and try to run it was not giving any output could you please let me know if i need to do anything extra or missing something.

ModuleNotFoundError: No module named 'werkzeug.contrib'

Hi,
so i was trying to build this image of yours yesterady, and it failed with this error(s):

[2020-04-30 14:31:22 +0000] [1] [INFO] Starting gunicorn 20.0.4
[2020-04-30 14:31:22 +0000] [1] [INFO] Listening at: http://172.27.0.4:5001 (1)
[2020-04-30 14:31:22 +0000] [1] [INFO] Using worker: sync
[2020-04-30 14:31:22 +0000] [7] [INFO] Booting worker with pid: 7
[2020-04-30 14:31:22 +0000] [8] [INFO] Booting worker with pid: 8
[2020-04-30 14:31:22 +0000] [9] [INFO] Booting worker with pid: 9
[2020-04-30 14:31:22 +0000] [10] [INFO] Booting worker with pid: 10
[2020-04-30 14:31:22 +0000] [7] [ERROR] Exception in worker process
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker
    worker.init_process()
  File "/usr/local/lib/python3.8/site-packages/gunicorn/workers/base.py", line 119, in init_process
    self.load_wsgi()
  File "/usr/local/lib/python3.8/site-packages/gunicorn/workers/base.py", line 144, in load_wsgi
    self.wsgi = self.app.wsgi()
  File "/usr/local/lib/python3.8/site-packages/gunicorn/app/base.py", line 67, in wsgi
    self.callable = self.load()
  File "/usr/local/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 49, in load
    return self.load_wsgiapp()
  File "/usr/local/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 39, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "/usr/local/lib/python3.8/site-packages/gunicorn/util.py", line 358, in import_app
    mod = importlib.import_module(module)
  File "/usr/local/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 783, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/app/app.py", line 24, in <module>
    from werkzeug.contrib.fixers import ProxyFix
ModuleNotFoundError: No module named 'werkzeug.contrib'
[2020-04-30 14:31:22 +0000] [7] [INFO] Worker exiting (pid: 7)
[2020-04-30 14:31:22 +0000] [8] [ERROR] Exception in worker process
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker
    worker.init_process()
  File "/usr/local/lib/python3.8/site-packages/gunicorn/workers/base.py", line 119, in init_process
    self.load_wsgi()
  File "/usr/local/lib/python3.8/site-packages/gunicorn/workers/base.py", line 144, in load_wsgi
    self.wsgi = self.app.wsgi()
  File "/usr/local/lib/python3.8/site-packages/gunicorn/app/base.py", line 67, in wsgi
    self.callable = self.load()
  File "/usr/local/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 49, in load
    return self.load_wsgiapp()
  File "/usr/local/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 39, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "/usr/local/lib/python3.8/site-packages/gunicorn/util.py", line 358, in import_app
    mod = importlib.import_module(module)
  File "/usr/local/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 783, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/app/app.py", line 24, in <module>
    from werkzeug.contrib.fixers import ProxyFix
ModuleNotFoundError: No module named 'werkzeug.contrib'
[2020-04-30 14:31:22 +0000] [8] [INFO] Worker exiting (pid: 8)
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/gunicorn/arbiter.py", line 202, in run
    self.manage_workers()
  File "/usr/local/lib/python3.8/site-packages/gunicorn/arbiter.py", line 545, in manage_workers
    self.spawn_workers()
  File "/usr/local/lib/python3.8/site-packages/gunicorn/arbiter.py", line 617, in spawn_workers
    time.sleep(0.1 * random.random())
  File "/usr/local/lib/python3.8/site-packages/gunicorn/arbiter.py", line 242, in handle_chld
    self.reap_workers()
  File "/usr/local/lib/python3.8/site-packages/gunicorn/arbiter.py", line 525, in reap_workers
    raise HaltServer(reason, self.WORKER_BOOT_ERROR)
gunicorn.errors.HaltServer: <HaltServer 'Worker failed to boot.' 3>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/bin/gunicorn", line 8, in <module>
    sys.exit(run())
  File "/usr/local/lib/python3.8/site-packages/gunicorn/app/wsgiapp.py", line 58, in run
    WSGIApplication("%(prog)s [OPTIONS] [APP_MODULE]").run()
  File "/usr/local/lib/python3.8/site-packages/gunicorn/app/base.py", line 228, in run
    super().run()
  File "/usr/local/lib/python3.8/site-packages/gunicorn/app/base.py", line 72, in run
    Arbiter(self).run()
  File "/usr/local/lib/python3.8/site-packages/gunicorn/arbiter.py", line 229, in run
    self.halt(reason=inst.reason, exit_status=inst.exit_status)
  File "/usr/local/lib/python3.8/site-packages/gunicorn/arbiter.py", line 342, in halt
    self.stop()
  File "/usr/local/lib/python3.8/site-packages/gunicorn/arbiter.py", line 393, in stop
    time.sleep(0.1)
  File "/usr/local/lib/python3.8/site-packages/gunicorn/arbiter.py", line 242, in handle_chld
    self.reap_workers()
  File "/usr/local/lib/python3.8/site-packages/gunicorn/arbiter.py", line 525, in reap_workers
    raise HaltServer(reason, self.WORKER_BOOT_ERROR)
gunicorn.errors.HaltServer: <HaltServer 'Worker failed to boot.' 3>

I think it might be related to this, seems like same problem. Downgrading might fix it?

pip uninstall werkzeug
pip install werkzeug==0.16.0

Failed to resolve usernames

in "--public" polls have error "Failed to resolve usernames"
MATTERMOST_PA_TOKEN is provided in settings.py
what else could be the problem?

Official image

First of all I like this project, very neat and pretty easy to setup.

Did you think about publishing an "official" image of this to Docker Hub? It would probably require to read the tokens and Mattermost URL config from environment variables at runtime, but that should not be hard to do in Python.
This way I would not have to build the image myself in the docker-compose.yml and get rid of the git submodule, setup would be even easier I think :).

bars are too big

As can be seen in this screenshot from a desktop PC, the bars are too big to be a useful visualization.
bildschirmfoto-20190214180152-1428x825

Could you make them smaller? Thanks!

Add help text

Add a command that prints a help text explaining all options.

is there installation manual for idiots?

I have followed instructions, but poll is not working for me. I am getting poll finished with error.
Question is about settings.py
I have a mattermost on xx.xx.xx.xx:8065
WEBSERVER_ADDRESS shall I use my IP xx.xx.xx.xx
on WEBSERVER_PORT shall I leave 5000 - or use 865 instead
What about MATTERMOST_URL - I am using xx.xx.xx.xx:8065 - is it correct?
And in mattermost integration section shall i use
http://xx.xx.xx.xx:5000
or http://xx.xx.xx.xx:8065
Please addvice.
Thank you

Bars are broken with mattermost 5.18.0

After updating to mattermost 5.18.0, the bars of existing and new pooll do not appear (or more precisely they are all 1 pixel wide regardless of the result).

Command with a trigger of 'poll' failed

I've installed Poll according to the document. But I couldn't run the command. No matter what configuration, it keeps saying Command with a trigger of 'poll' failed. I've tested both localhost way and docker way but, no luck.

However, Poll server seems working well because it returns "Poll server is running" when I execute "curl http://localhost:5002". Also, in the MatterMost container, command ping poll respond well, too. Any ideas about this trouble?

docker-compose.yml

  web:
    build: web
    ports:
      - "8866:80"
      - "8867:443"
    read_only: true
    restart: unless-stopped
    volumes:
      # This directory must have cert files if you want to enable SSL
      - ./volumes/web/cert:/cert:ro
      - /etc/localtime:/etc/localtime:ro
    # Uncomment for SSL
    # environment:
    #  - MATTERMOST_ENABLE_SSL=true

poll:
    build:
      context: poll
      args:
	- mattermost_url="http://web:8866"
        - mattermost_tokens=['qnz93keghpycp8ckx3wspw34eo']
        - mattermost_pa_token="<personal-access-token>"
    ports:
      - "5002:5000"
    restart: unless-stopped
    volumes:
      - ./volumes/poll:/app/volume:rw

config.json

...
"AllowedUntrustedInternalConnections": "poll" # "localhost"
...

The slash commands configuration on MatterMost

Request URL: http://poll:5002 # Port 5000 is already in use so I changed it
Request Method: POST

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.