Giter Site home page Giter Site logo

ph-slack's Introduction

ph-slack

Phabricator notification Slack integration. Instantly receive Phabricator notification in Slack.

Features

  • Instant.
  • Customizable.
  • Togglable.

Usage

Your team members can receive Phabricator notification and can easily disable/enable it in Slack at anytime, like:

/your-slash-cmd [enable | disable]

Deploy

In order to deploy ph-slack, you need to prepare these things:

  • A Slack API Authentication Token.
  • A Phabricator user (bot user is much better).
  • The administation privileges of your Phabricator and Slack.
  • A new Slack slash command.
  • A server that can be accessed from Slack server.

The last two things are optional if you don't want to your user to disable ph-slack.

Here we go.

First, clone code and build:

$ git clone [email protected]:psjay/ph-slack.git
$ cd ph-slack
$ python bootstrap.py
$ bin/buildout

You don't need a virtual environment with Buildout.

Create a configuration file with sample:

$ cp config_sample.py config.py

Modify config.py like this:

PHABRICATOR_HOST = 'http://ph.your.domain/api/'

PHABRICATOR_USER = 'ph-bot-name'

PHABRICATOR_CERT = 'ph-bot-cert'

SLACK_AUTH_TOKEN = 'slack api token'

# optional
SLACK_COMMAND_TOKEN = 'slack slash command token'

EMAIL_DOMAIN = 'business-domain.com'

Full explanation of configuration, see config_sample.py.

Run the server on 5000 port behind Gunicorn:

$ bin/gunicorn -w 4 -b 0.0.0.0:5000 'ph_slack:app' --log-file - --access-logfile -

Then, add http://ph-slack.domain:5000/handle to your Phabricator feed http hooks on http://your-ph.domain/config/edit/feed.http-hooks/ page.

Configure http://ph-slack.domain:5000/switch as the URL of the Slack slash command you just created for ph-slack.

Done!

Limitations

By now, it only supports two kinds of Phabricator object:

  • Task
  • Revision

Pull request is welcome!

ph-slack's People

Contributors

maiki avatar psjay 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

Watchers

 avatar  avatar  avatar  avatar

ph-slack's Issues

README.md says to point Slack's slash command at /handle instead of /switch

After following the original instructions, I wound up seeing an "Unsupported story" exception whenever I did a /slashcommand enable in Slack. From what little I understand from digging around in the code, it looks like Slack should be pointed at /switch instead of /handle. That seems to have worked for me, anyway.

General questions

I've gone through the full setup of and have gnunicorn launched, slack slash command setup, etc... I see the feed driving notices into the ph_slack app, but then I never see anything in slack:

bin/gunicorn -w 4 -b 0.0.0.0:5000 'ph_slack:app' --log-file - --access-logfile -
[2015-07-13 17:02:48 +0000] [8461] [INFO] Starting gunicorn 19.3.0
[2015-07-13 17:02:48 +0000] [8461] [INFO] Listening at: http://0.0.0.0:5000 (8461)
[2015-07-13 17:02:48 +0000] [8461] [INFO] Using worker: sync
[2015-07-13 17:02:48 +0000] [8466] [INFO] Booting worker with pid: 8466
[2015-07-13 17:02:48 +0000] [8467] [INFO] Booting worker with pid: 8467
[2015-07-13 17:02:48 +0000] [8472] [INFO] Booting worker with pid: 8472
[2015-07-13 17:02:48 +0000] [8473] [INFO] Booting worker with pid: 8473
Got story #110 on #PHID-TASK-jkhao6kqfzkhe5lhe76c: colby created T16: TESTTESTTES.
Refreshing slack members.
18.85.45.198 - - [13/Jul/2015:17:03:06 -0400] "POST /handle HTTP/1.1" 200 7 "-" "-"
Got story #111 on #PHID-TASK-sp4ipovskpnsecprlflb: colby created T17: TESTESTSETESTEST.
18.85.45.198 - - [13/Jul/2015:17:04:30 -0400] "POST /handle HTTP/1.1" 200 7 "-" "-"
^C[2015-07-13 17:06:22 +0000] [8461] [INFO] Handling signal: int

Any suggestions?

Issues with POST from Phabricator?

Getting a stack trace regarding JSON:

Got story #xxxx on #xxxxx: x created x: x.
Refreshing slack members.
Exception on /handle [POST]
Traceback (most recent call last):
File "/home/centos/phab-slack/ph-slack/eggs/Flask-0.10.1-py2.7.egg/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/home/centos/phab-slack/ph-slack/eggs/Flask-0.10.1-py2.7.egg/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/centos/phab-slack/ph-slack/eggs/Flask-0.10.1-py2.7.egg/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/centos/phab-slack/ph-slack/eggs/Flask-0.10.1-py2.7.egg/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/home/centos/phab-slack/ph-slack/eggs/Flask-0.10.1-py2.7.egg/flask/app.py", line 1461, in dispatch_request
return self.view_functionsrule.endpoint
File "/home/centos/phab-slack/ph-slack/ph_slack/web.py", line 62, in handle
subscribers = [s for s in ph_obj.subscribers if s.phid != author_phid]
File "/home/centos/phab-slack/ph-slack/ph_slack/phabricator.py", line 99, in subscribers
obj for obj in self.cc_objs if isinstance(obj, Project)
File "/home/centos/phab-slack/ph-slack/ph_slack/phabricator.py", line 116, in cc_objs
self.sync()
File "/home/centos/phab-slack/ph-slack/ph_slack/phabricator.py", line 27, in sync
datadict = self.query_data_by_phids(self.phabricator, self.phid)
File "/home/centos/phab-slack/ph-slack/ph_slack/phabricator.py", line 154, in query_data_by_phids
r = phabricator.client.differential.query(phids=phids)
File "/home/centos/phab-slack/ph-slack/eggs/phabricator-0.4.0-py2.7.egg/phabricator/init.py", line 212, in call
return self._request(**kwargs)
File "/home/centos/phab-slack/ph-slack/eggs/phabricator-0.4.0-py2.7.egg/phabricator/init.py", line 246, in _request
self.api.connect()
File "/home/centos/phab-slack/ph-slack/eggs/phabricator-0.4.0-py2.7.egg/phabricator/init.py", line 319, in connect
client=self.client, clientVersion=self.clientVersion)
File "/home/centos/phab-slack/ph-slack/eggs/phabricator-0.4.0-py2.7.egg/phabricator/init.py", line 212, in call
return self._request(**kwargs)
File "/home/centos/phab-slack/ph-slack/eggs/phabricator-0.4.0-py2.7.egg/phabricator/init.py", line 270, in _request
data = self._parse_response(response.read())
File "/home/centos/phab-slack/ph-slack/eggs/phabricator-0.4.0-py2.7.egg/phabricator/init.py", line 276, in _parse_response
parsed = self.api.formatsself.api.response_format
File "/home/centos/phab-slack/ph-slack/eggs/phabricator-0.4.0-py2.7.egg/phabricator/init.py", line 287, in
'json': lambda x: json.loads(x),
File "/usr/lib64/python2.7/json/init.py", line 338, in loads
return _default_decoder.decode(s)
File "/usr/lib64/python2.7/json/decoder.py", line 365, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib64/python2.7/json/decoder.py", line 383, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded

This is running on AWS Linux, if that makes any difference.

Getting ERR-INVALID-SESSION error after some time

Looks like session expires. If I redeploy the app, it works again. How can we handle this?

Got story #389 on #PHID-TASK-qv6aa7ag3bulebb6gbyy: yun_man_ger edited the description of T57: asdasd.
Exception on /handle [POST]
Traceback (most recent call last):
  File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/app/.heroku/python/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "ph_slack/web.py", line 64, in handle
    for s in ph_obj.subscribers
  File "/app/ph_slack/phab.py", line 99, in subscribers
    obj for obj in self.cc_objs if isinstance(obj, Project)
  File "/app/ph_slack/phab.py", line 116, in cc_objs
    self.sync()
  File "/app/ph_slack/phab.py", line 27, in sync
    datadict = self.query_data_by_phids(self.phabricator, self.phid)
  File "/app/ph_slack/phab.py", line 131, in query_data_by_phids
    r = phabricator.client.maniphest.query(phids=phids)
APIError: ERR-INVALID-SESSION: Session key is invalid.

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.