-
Notifications
You must be signed in to change notification settings - Fork 2
/
slack2discord.py
94 lines (78 loc) · 2.91 KB
/
slack2discord.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/usr/bin/env python3
import discord
from discord.ext import commands
import datetime
import json
import argparse
import sys
import re
arg_parser = argparse.ArgumentParser(description="A Discord bot for transferring a Slack archive to a channel")
arg_parser.add_argument('--prefix', dest='prefix', default='!', help='bot command prefix (default !)')
arg_parser.add_argument('--token', required=True, help='bot access token')
arg_parser.add_argument('--users', required=True, type=argparse.FileType('r'), help='slack users.json file')
arg_parser.add_argument('file', nargs='+')
# Parse the command-line
args = arg_parser.parse_args(sys.argv[1:])
# Load user data
users = {}
for u in json.load(args.users):
if not u['deleted']:
users[u['id']] = u['real_name']
# Process the input files
messages = []
for fn in args.file:
with open(fn, "rb") as fh:
for msg in json.load(fh):
# Unfold mentions
txt = re.sub(r'<@(\w+)>',
(lambda m: '@' + users.get(m.group(1), 'Unknown')),
msg["text"])
# Unescape HTML characters
txt = re.sub(r'>', '>', txt)
txt = re.sub(r'<', '<', txt)
txt = re.sub(r'&', '&', txt)
# Split messages longer than 2000 characters
while len(txt) > 0:
msg["text"] = txt[:2000]
txt = txt[2000:]
messages.append(msg)
# Sort the messages by timestamp
messages.sort(key=(lambda msg: msg['ts']))
print("Read {0} messages.".format(len(messages)))
# Create the bot
bot = commands.Bot(command_prefix=args.prefix)
print("Activating the bot. Press Ctrl-C to exit.")
def format_message(msg):
"""Format the given message in Markdown, suitable for posting on Discord."""
return "{timestamp} **{user}**: {text}".format(
timestamp = datetime.datetime.fromtimestamp(float(msg['ts'])).strftime('%Y-%m-%d %H:%M'),
user=users.get(msg.get('user'), 'Unknown'),
text=msg['text'])
# Set up the bot listener
@bot.command(pass_context=True)
async def slackimport(ctx):
n = len(messages)
k = 0
print ("Sending {0} messages ...".format(n))
for msg in messages:
k = k + 1
if k % 10 == 0: print ("{0}/{1} messages sent ...".format(k, n))
try:
# Send the message to Discord (Markdown format)
await ctx.send (format_message(msg))
except:
print("Message {0} could not be sent.".format(k))
print ("Finished sending messages. My job is done, kill me now.")
@bot.command(pass_context=True)
async def slackpreview(ctx):
for msg in messages:
print("-" * 50)
print(format_message(msg))
@bot.command(pass_context=True)
async def slackexit(ctx):
print("Logging out ...")
await bot.logout()
print("Stopping (do not worry about the error messages printed below) ...")
exit(0)
# Run the bot
bot.run(args.token)