Discord Bot

This is an example of a basic discord bot and some commands.

  1# this example assumes you have discord.py > v2.0
  2# installed via `python -m pip install -U discord.py`
  3# for more info on using discord.py, see the docs at:
  4# https://discordpy.readthedocs.io/en/latest
  5import asyncio
  6import logging
  7import os
  8import traceback
  9
 10import discord
 11from discord.ext import commands
 12
 13import coc
 14from coc import utils
 15
 16INFO_CHANNEL_ID = 761848043242127370  # some discord channel ID
 17clan_tags = ["#20090C9PR", "#202GG92Q", "#20C8G0RPL"]
 18
 19bot = commands.Bot(command_prefix="?", intents=discord.Intents.all())
 20
 21
 22@bot.event
 23async def on_ready():
 24    print("Logged in!!")
 25
 26
 27@coc.ClanEvents.member_join(tags=clan_tags)
 28async def on_clan_member_join(member, clan):
 29    await bot.get_channel(INFO_CHANNEL_ID).send(
 30        "{0.name} ({0.tag}) just " "joined our clan {1.name} ({1.tag})!".format(
 31            member, clan)
 32    )
 33
 34
 35@coc.ClanEvents.member_name(tags=clan_tags)
 36async def member_name_change(old_player, new_player):
 37    await bot.get_channel(INFO_CHANNEL_ID).send(
 38        "Name Change! {0.name} is now called {1.name} (his tag is {1.tag})".format(
 39            old_player, new_player)
 40    )
 41
 42
 43@coc.ClientEvents.event_error()
 44async def on_event_error(exception):
 45    if isinstance(exception, coc.PrivateWarLog):
 46        return  # lets ignore private war log errors
 47    print(
 48        "Uh oh! Something went wrong in coc.py events... printing traceback for you.")
 49    traceback.print_exc()
 50
 51
 52@bot.command()
 53async def player_heroes(ctx, player_tag):
 54    if not utils.is_valid_tag(player_tag):
 55        await ctx.send("You didn't give me a proper tag!")
 56        return
 57
 58    try:
 59        player = await ctx.bot.coc_client.get_player(player_tag)
 60    except coc.NotFound:
 61        await ctx.send("This player doesn't exist!")
 62        return
 63
 64    to_send = ""
 65    for hero in player.heroes:
 66        to_send += "{}: Lv{}/{}\n".format(str(hero),
 67                                          hero.level, hero.max_level)
 68
 69    await ctx.send(to_send)
 70
 71
 72@bot.command()
 73async def parse_army(ctx, army_link: str):
 74    troops, spells = ctx.bot.coc_client.parse_army_link(army_link)
 75    print(troops, spells)
 76    parsed_link_output = ''
 77    if troops or spells:  # checking if troops or spells is present in link
 78
 79        for troop, quantity in troops:
 80            parsed_link_output += "The user wants {} {}s. They each have {} DPS.\n".format(
 81                quantity, troop.name, troop.dps)
 82
 83        for spell, quantity in spells:
 84            parsed_link_output += "The user wants {} {}s.\n".format(
 85                quantity, spell.name)
 86    else:
 87        parsed_link_output += "Invalid Link!"
 88    await ctx.send(parsed_link_output)
 89
 90
 91@bot.command()
 92async def create_army(ctx):
 93    link = ctx.bot.coc_client.create_army_link(
 94        barbarian=10,
 95        archer=20,
 96        hog_rider=30,
 97        healing_spell=3,
 98        poison_spell=2,
 99        rage_spell=2
100    )
101    await ctx.send(link)
102
103
104@bot.command()
105async def member_stat(ctx, player_tag):
106    if not utils.is_valid_tag(player_tag):
107        await ctx.send("You didn't give me a proper tag!")
108        return
109
110    try:
111        player = await ctx.bot.coc_client.get_player(player_tag)
112    except coc.NotFound:
113        await ctx.send("This clan doesn't exist!")
114        return
115
116    frame = ''
117    if player.town_hall > 11:
118        frame += f"`{'TH Weapon LvL:':<15}` `{player.town_hall_weapon:<15}`\n"
119    role = player.role if player.role else 'None'
120    clan = player.clan.name if player.clan else 'None'
121    frame += (
122        f"`{'Role:':<15}` `{role:<15}`\n"
123        f"`{'Player Tag:':<15}` `{player.tag:<15}`\n"
124        f"`{'Current Clan:':<15}` `{clan:<15.15}`\n"
125        f"`{'League:':<15}` `{player.league.name:<15.15}`\n"
126        f"`{'Trophies:':<15}` `{player.trophies:<15}`\n"
127        f"`{'Best Trophies:':<15}` `{player.best_trophies:<15}`\n"
128        f"`{'War Stars:':<15}` `{player.war_stars:<15}`\n"
129        f"`{'Attack Wins:':<15}` `{player.attack_wins:<15}`\n"
130        f"`{'Defense Wins:':<15}` `{player.defense_wins:<15}`\n"
131        f"`{'Capital Contrib':<15}` `{player.clan_capital_contributions:<15}`\n"
132    )
133    e = discord.Embed(colour=discord.Colour.green(),
134                      description=frame)
135    e.set_thumbnail(url=player.clan.badge.url)
136    await ctx.send(embed=e)
137
138
139@bot.command()
140async def clan_info(ctx, clan_tag):
141
142    if not utils.is_valid_tag(clan_tag):
143        await ctx.send("You didn't give me a proper tag!")
144        return
145
146    try:
147        clan: coc.Clan = await ctx.bot.coc_client.get_clan(clan_tag)
148    except coc.NotFound:
149        await ctx.send("This clan doesn't exist!")
150        return
151
152    if clan.public_war_log is False:
153        log = "Private"
154    else:
155        log = "Public"
156
157    e = discord.Embed(colour=discord.Colour.green())
158
159    e.set_thumbnail(url=clan.badge.url)
160    e.add_field(name="Clan Name",
161                value=f"{clan.name}({clan.tag})\n[Open in game]({clan.share_link})",
162                inline=False)
163    e.add_field(name="Clan Level", value=clan.level, inline=False)
164    e.add_field(name="Description", value=clan.description, inline=False)
165    for district in clan.capital_districts: