Skip to content

Commit 13c8f81

Browse files
committed
initial commit
0 parents  commit 13c8f81

File tree

7 files changed

+169
-0
lines changed

7 files changed

+169
-0
lines changed

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2018 Dennis Mellican
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# SlackMQ
2+
3+
Enables a common Message Queue mechanism for "message locking" within Slack.
4+
When a message is sent to a channel, a Slack bot can acknowledge the message
5+
and “lock” it for processing. This keeps other worker bots from processing the
6+
message simultaneously.
7+
8+
SlackMQ leverages the Slack API method for pinning, reactions and starring of
9+
messages, where only one is allowed per post per user (or bot) account.
10+
11+
A Slack worker bot can use the same API token to connect to Slack up to 16
12+
times. This is a restriction imposed by Slack.
13+
14+
SlackMQ is not a replacement for dedicated Message Brokers and Queue systems. It
15+
only does simple message locking and is suitable for managing low bandwidth
16+
tasks or applications. For those use cases, it's one less moving part and makes
17+
Slack do the heavy lifting.
18+
19+
To install:
20+
```
21+
pip install SlackMQ
22+
```
23+
24+
## Message Locking Anatomy
25+
26+
A star and pin action are both used to "lock" a message.
27+
28+
The star is not seen in the Slack channel, as it is only visible by the user
29+
creating the star.
30+
31+
Pins and reactions are visible to everyone in the channel.
32+
33+
To avoid race conditions, where two or more bots simultaneously star the
34+
same message (the Slack API says it shouldn't but it can happen), a second
35+
action (the star) is invoked. An optional third action (a reaction emoji) for
36+
extra protection can also be invoked.
37+
38+
## Example: The Slack Worker Bot
39+
40+
For high availability and scalability reasons, multiple worker bots could be
41+
deployed through out a network. Using the Slackbot python library to listen and
42+
respond to certain Slack posts, all the bots will receive the message, but the
43+
first to acknowledge the message will be able to process it.
44+
45+
```
46+
from slackmq import slackmq
47+
from slackbot.bot import listen_to
48+
import socket
49+
50+
API_TOKEN = 'YOUR-BOT-API-TOKEN'
51+
52+
@listen_to('hostname')
53+
def myhostname(message):
54+
post = slackmq(API_TOKEN,
55+
message.body['channel'],
56+
message.body['ts'])
57+
if post.ack():
58+
message.send('I am running on {}.'.format(socket.gethostname()))
59+
# Removes the visible pin (and hidden star) from the channel.
60+
post.unack()
61+
```
62+
63+
## Example: Continuous Delivery with SlackMQ
64+
65+
Watch Continuous Delivery with SlackMQ in action, deploying a home automation
66+
application across several hosts. From Continuous Integration to an automated
67+
canary deployment. Once approved, a rolling deployment occurs with zero
68+
downtime.
69+
70+
Video has no audio:
71+
72+
[![Continuous Delivery with SlackMQ](http://img.youtube.com/vi/YW6IdsvdxXI/0.jpg)](http://www.youtube.com/watch?v=YW6IdsvdxXI "Continuous Delivery with SlackMQ")

VERSION

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0.1.0

requirements

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Slacker

setup.cfg

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[bdist_wheel]
2+
universal=1
3+
4+
[metadata]
5+
description-file = README.md

setup.py

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from os.path import join, dirname
2+
from setuptools import setup
3+
4+
__version__ = open(join(dirname(__file__), 'VERSION')).read().strip()
5+
6+
install_requires = (
7+
'slacker>=0.9.50'
8+
)
9+
10+
with open("README.md", "r") as fh:
11+
long_description = fh.read()
12+
13+
setup(
14+
name='slackmq',
15+
py_modules=['slackmq'],
16+
version=__version__,
17+
description='A Slack Message Queue system',
18+
long_description=long_description,
19+
long_description_content_type='text/markdown',
20+
author='Dennis Mellican',
21+
author_email='[email protected]',
22+
url='https://github.com/meltaxa/slackmq',
23+
license='MIT',
24+
include_package_data=True,
25+
install_requires=install_requires,
26+
classifiers=['Development Status :: 4 - Beta',
27+
'License :: OSI Approved :: MIT License',
28+
'Operating System :: OS Independent',
29+
'Programming Language :: Python',
30+
'Programming Language :: Python :: 2',
31+
'Programming Language :: Python :: 2.7',
32+
'Programming Language :: Python :: 3',
33+
'Programming Language :: Python :: 3.4',
34+
'Programming Language :: Python :: 3.5',
35+
'Programming Language :: Python :: 3.6'])

slackmq.py

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from slacker import Slacker
2+
from time import sleep
3+
4+
class slackmq(object):
5+
def __init__(self, api_token, channel, timestamp):
6+
self.api_token = api_token
7+
self.channel = channel
8+
self.timestamp = timestamp
9+
10+
def ack(self, emoji=None):
11+
try:
12+
slack = Slacker(self.api_token)
13+
slack.stars.add(channel = self.channel, timestamp = self.timestamp)
14+
15+
if emoji != None:
16+
slack.reactions.add(emoji, channel = self.channel, timestamp = self.timestamp)
17+
18+
slack.pins.add(channel = self.channel, timestamp = self.timestamp)
19+
except:
20+
return False
21+
22+
return True
23+
24+
def unack(self, emoji=None):
25+
try:
26+
slack = Slacker(self.api_token)
27+
slack.pins.remove(channel = self.channel, timestamp = self.timestamp)
28+
sleep(3)
29+
if emoji != None:
30+
slack.reactions.remove(emoji, channel = self.channel, timestamp = self.timestamp)
31+
sleep(5)
32+
slack.stars.remove(channel = self.channel, timestamp = self.timestamp)
33+
except:
34+
return False

0 commit comments

Comments
 (0)