Created
February 20, 2018 18:10
-
-
Save supposedly/a612aa66b41ed9f13a4e311b6777256e 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 pkg_resources | |
import platform | |
import os | |
from collections import defaultdict | |
from inspect import cleandoc | |
import asyncpg | |
import discord | |
from discord.ext import commands | |
DISCORD_PUBLIC_VERSION = pkg_resources.get_distribution('discord.py').parsed_version.public | |
PY_VERSION = platform.python_version() | |
bot = commands.Bot(command_prefix=commands.when_mentioned_or('+/')) | |
bot.chns = defaultdict(set) | |
bot.msgs = set() | |
class ChannelConv: | |
@classmethod | |
async def convert(cls, ctx, chn_id): | |
if chn_id != ctx.channel.id: | |
return bot.get_channel(int(chn_id)) | |
def getchn(chn_id: str) -> discord.TextChannel: | |
return bot.get_channel(int(chn_id)) | |
@bot.event | |
async def on_ready(): | |
######################################### | |
# THIS WORKS OUT-OF-THE-BOX ON HEROKU # | |
# IF NOT ON HEROKU REPLACE WITH YOUR # | |
# OWN INITIALIZATION PARAMETERS # | |
bot.pool = await asyncpg.create_pool(os.getenv('DATABASE_URL')) | |
# ALSO IF NOT ON HEROKU, MAKE SURE YOU # | |
# CREATE A PROPER ROLE/ACCT IN POSTGRES # | |
# FOR THE BOT (INSTEAD OF DOING IT IN # | |
# ONE SPOT LIKE BELOW) # | |
await bot.pool.execute('''CREATE TABLE IF NOT EXISTS chlinks (source BIGINT, dest BIGINT, PRIMARY KEY (source, dest))''') | |
######################################### | |
for i in await bot.pool.fetch('''SELECT source, dest FROM chlinks'''): | |
bot.chns[getchn(i['source'])].add(getchn(i['dest'])) | |
print('oof') | |
@bot.event | |
async def on_message(msg): | |
st = 0 | |
for i in bot.msgs.copy(): | |
if i.content in msg.content or i.author.id != bot.user.id: | |
bot.msgs ^= {i} | |
st += i.content in msg.content | |
if st < 1: | |
if msg.channel in bot.chns: | |
for chn in bot.chns[msg.channel]: | |
try: | |
await chn.send(f'**<`{msg.guild.name}`/`#{msg.channel.name}`:{msg.author.nick or msg.author.name}>** {msg.content}') | |
bot.msgs.add(msg) | |
except Exception as e: | |
print(f'Error sending {msg.id} from {msg.channel.name} in {msg.guild.name} to {chn.name} in {chn.guild.name}. {e.__class__.__name__}: {e}') | |
await bot.process_commands(msg) | |
@bot.event | |
async def on_command_error(ctx, e): | |
await ctx.message.add_reaction('๐') | |
if not isinstance(e, commands.errors.CommandNotFound): | |
await ctx.send(f'`{e.__class__.__name__}: {e}`') | |
@bot.group() | |
async def relay(ctx): | |
""" | |
Relay commands between channels. | |
``````apache | |
+/relay to [chnID chnID chnID ...] | |
# Send to this channel from the others # | |
``````apache | |
+/relay from [chnID chnID chnID ...] | |
# Send from this channel to the others # | |
``````apache | |
+/relay both [chnID chnID chnID ...] | |
# Send both ways between this channel and the others # | |
`````` | |
""" | |
pass | |
@relay.command('from') | |
async def from_(ctx, *chns: ChannelConv): | |
""" | |
Send to current channel from the given ones. | |
``````apache | |
+/relay from [chnID chnID chnID ...] | |
""" | |
async with bot.pool.acquire() as conn: | |
await conn.copy_records_to_table( | |
'chlinks', | |
records = list({(i.id, ctx.channel.id) for i in filter(None, chns)}), | |
columns = ['source', 'dest'] | |
) | |
for chn in chns: | |
bot.chns[chn].add(ctx.channel) | |
await ctx.message.add_reaction('๐') | |
@relay.command() | |
async def to(ctx, *chns: ChannelConv): | |
""" | |
Send from current channel to the given ones. | |
``````apache | |
+/relay to [chnID chnID chnID ...] | |
""" | |
async with bot.pool.acquire() as conn: | |
await conn.copy_records_to_table( | |
'chlinks', | |
records = list({(ctx.channel.id, i.id) for i in filter(None, chns)}), | |
columns = ['source', 'dest'] | |
) | |
bot.chns[ctx.channel].update(chns) | |
await ctx.message.add_reaction('๐') | |
@relay.command(aliases=['between', 'btwn']) | |
async def both(ctx, *chns: ChannelConv): | |
""" | |
Send between current channel and the given ones. | |
``````apache | |
+/relay both [chnID chnID chnID ...] | |
""" | |
recs = {(ctx.channel.id, i.id) for i in filter(None, chns)} | |
async with bot.pool.acquire() as conn: | |
await conn.copy_records_to_table( | |
'chlinks', | |
records = list(recs) + [i[::-1] for i in recs], | |
columns = ['source', 'dest'] | |
) | |
bot.chns[ctx.channel].update(chns) | |
for chn in chns: | |
bot.chns[chn].add(ctx.channel) | |
await ctx.message.add_reaction('๐') | |
@bot.command() | |
async def unlink(ctx, *chns: ChannelConv): | |
""" | |
Unlink current channel from each given no matter their relation. | |
``````apache | |
+/unlink [chnID chnID chnID ...] | |
""" | |
bot.chns[ctx.channel] ^= set(chns) & bot.chns[ctx.channel] | |
for chn in chns: | |
if ctx.channel in bot.chns[chn]: | |
bot.chns[chn] ^= {ctx.channel} | |
await bot.pool.execute(''' | |
DELETE FROM chlinks | |
WHERE (source = $1::bigint AND dest = $2::bigint) | |
OR (dest = $1::bigint AND source = $2::bigint) | |
''', | |
ctx.channel.id, | |
chn.id | |
) | |
await ctx.message.add_reaction('๐') | |
@bot.command(aliases=['about']) | |
async def info(ctx): | |
"""About this bot.""" | |
desc = f'''**```ini | |
{'[An inter-guild message-relaying demo bot]': ^45}```** | |
**Version numbers:** | |
python {PY_VERSION} | |
discord.py {DISCORD_PUBLIC_VERSION} (rewrite) | |
**Links:** | |
โข [The original Reddit comment](https://reddit.com/comments/7yr4ur//dujbrym/) | |
**By Wright#9480** | |
```FORTRAN | |
{f"'+/help' for command info": ^45}``` | |
''' | |
await ctx.send(embed=discord.Embed(description=cleandoc(desc))) | |
bot.run('TOKEN HERE') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment