Created
February 19, 2018 20:27
-
-
Save gtmanfred/3d02b0ee179a886bb8cd88b6c01e7731 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import irc3 | |
import json | |
import re | |
@irc3.plugin | |
class Slack: | |
def __init__(self, bot): | |
self.web = irc3.utils.maybedotted('aiohttp') | |
self.bot = bot | |
self.config = self.bot.config.get(__name__, {}) | |
self.channels = self.bot.config.get(f'{__name__}.channels', {}) | |
self.slack_channels = {} | |
if 'token' not in self.config: | |
self.bot.log.warning('No slack token is set.') | |
async def api_call(self, method, data=None): | |
"""Slack API call.""" | |
async with self.web.ClientSession() as session: | |
form = self.web.FormData(data or {}) | |
form.add_field('token', self.config['token']) | |
async with session.post('https://slack.com/api/{0}'.format(method), data=form) as response: | |
assert 200 == response.status, ('{0} with {1} failed.'.format(method, data)) | |
return await response.json() | |
def server_ready(self): | |
irc3.asyncio.ensure_future(self.connect()) | |
''' | |
def parse_text(self, message): | |
matches = [ | |
(r'\n|\r\n|\r', ''), | |
(r'<!channel>', '@channel'), | |
(r'<!group>', '@group'), | |
(r'<!everyone>', '@everyone'), | |
] | |
.replace(/<#(C\w+)\|?(\w+)?>/g, (match, channelId, readable) => { | |
const { name } = dataStore.getChannelById(channelId); | |
return readable || `#${name}`; | |
}) | |
.replace(/<@(U\w+)\|?(\w+)?>/g, (match, userId, readable) => { | |
const { name } = dataStore.getUserById(userId); | |
return readable || `@${name}`; | |
}) | |
.replace(/<(?!!)([^|]+?)>/g, (match, link) => link) | |
.replace(/<!(\w+)\|?(\w+)?>/g, (match, command, label) => | |
`<${label || command}>` | |
) | |
.replace(/:(\w+):/g, (match, emoji) => { | |
if (emoji in emojis) { | |
return emojis[emoji]; | |
} | |
return match; | |
}) | |
.replace(/<.+?\|(.+?)>/g, (match, readable) => readable) | |
.replace(/</g, '<') | |
.replace(/>/g, '>') | |
.replace(/&/g, '&'); | |
''' | |
async def connect(self): | |
channels = await self.api_call('channels.list') | |
groups = await self.api_call('groups.list') | |
for channel in channels.get('channels', []): | |
self.slack_channels[channel['id']] = channel | |
if channel['name'] in self.channels: | |
self.channels[channel['id']] = self.channels.pop(channel['name']) | |
for channel in groups.get('groups', []): | |
self.slack_channels[channel['id']] = channel | |
if channel['name'] in self.channels: | |
self.channels[channel['id']] = self.channels.pop(channel['name']) | |
rtm = await self.api_call('rtm.start') | |
if not rtm['ok']: | |
raise Exception('Error connecting to RTM') | |
while True: | |
async with self.web.ClientSession() as session: | |
async with session.ws_connect(rtm['url']) as ws: | |
async for msg in ws: | |
if msg.type == self.web.WSMsgType.TEXT: | |
message = json.loads(msg.data) | |
self.bot.log.debug(f'Sending message to irc: {message}') | |
if message['type'] == 'message' and message.get('subtype') != 'bot_message': | |
user = await self.api_call('users.info', {'user': message['user']}) | |
for channel in self.channels.get(message['channel'], []): | |
await self.bot.privmsg(channel, f"<{user['user']['name']}> {message['text']}") | |
elif msg.type == self.web.WSMsgType.CLOSED: | |
break | |
elif msg.type == self.web.WSMsgType.ERROR: | |
break | |
@irc3.event(irc3.rfc.MY_PRIVMSG) | |
def on_message(self, target=None, nick=None, data=None, **kwargs): | |
self.bot.log.info(f'{target} {nick} {data}') | |
irc3.asyncio.ensure_future(self.forward_message(target, nick, data)) | |
async def forward_message(self, target, nick, data): | |
for channel, irc in self.channels.items(): | |
if target in irc: | |
payload = { | |
'channel': channel, | |
'text': data, | |
'as_user': False, | |
'username': nick, | |
'icon_url': f'http://api.adorable.io/avatars/48/{nick}.jpg' | |
} | |
await self.api_call('chat.postMessage', data=payload) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment