Skip to content
Permalink
2f85e7af45
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
247 lines (209 sloc) 10.9 KB
###Mo's Chatbot Code###
"""Documentation = https://discordpy.readthedocs.io/en/latest/api.html#server"""
"""using ubuntu 16.04 instead of 18.04 since that never worked. had to upgrade setuptools and pip too."""
"""Had to install FFmpeg from https://linuxconfig.org/install-ffmpeg-on-ubuntu-18-04-bionic-beaver-linux. Allows conversion from video to audio to be played in voice channel."""
#Template for this project:
#NanoDano (2018) | Make a Discord Bot with Python [online] available from
#<https://www.devdungeon.com/content/make-discord-bot-python> (29/11/18)
#Discord API:
#Rapptz (2018) | An API wrapper for Discord written in Python. [online] available from
#<https://github.com/Rapptz/discord.py> (29/11/18)
#API Reference/Documentation:
#Rapptz (2017) | API Reference [online] available from
#<https://discordpy.readthedocs.io/en/latest/api.html> (29/11/19)
#Tutorial used:
#Lukas Kumara (2018) | Making a Python Bot with Discord.py. [online] avaiable from
#<https://www.youtube.com/playlist?list=PLW3GfRiBCHOiEkjvQj0uaUB1Q-RckYnj9> (29/11/18)
import discord
from discord.ext import commands
from discord.ext.commands import Bot
import youtube_dl
import time
"""Dictionaries that will be used to store data this is later accessed by the functions below. Players"""
players={}
queues={}
TOKEN = 'NTA0NjM4OTc5Njg2MTM3ODU3.DrH9Wg.oKLjS7aOW0fFHKiNlfGZc0XzDyE'
bot = commands.Bot(command_prefix ='.')
@bot.event
async def on_ready():
print("The bot is now online!")
@bot.event
async def on_message(message):
# we do not want the bot to reply to itself
if message.author == bot.user:
return
if message.content.startswith('!hello'):
msg = 'Hello {0.author.mention}, Welcome to the server'.format(message)
await bot.send_message(message.channel, msg)
if message.content.startswith('!AI'):
msg = 'Artificial Intelligence will take over....'.format(message)
await bot.send_message(message.channel, msg)
if message.content.startswith('!music'):
msg = 'Music player is not ready yet'.format(message)
await bot.send_message(message.channel, msg)
if message.content.startswith('!command'):
msg = '!AI, !music, !hello, !private, !logoff, !command, !time, .summon, .disconnect, .play, .pause, .resume, .stop, .queue, .info'.format(message)
await bot.send_message(message.channel, msg)
if message.content.startswith('!private'):
msg = 'Hello {0.author.mention}, this is a private message'.format(message)
await bot.send_message(message.author, msg)
if message.content.startswith('!logoff'):
msg = 'Logging off!'.format(message)
await bot.send_message(message.channel, msg)
await bot.close()
if message.content.startswith('!time'):
msg = 'The time is '.format(message)
await bot.send_message(message.channel, msg+str(message.timestamp))
await bot.process_commands(message)
@bot.command(pass_context=True)
async def summon(ctx):
"""joins the voice channel that the user is currently in"""
if ctx.message.author.voice_channel:
vc = ctx.message.author.voice.voice_channel
msg = "The bot has joined your voice channel"
await bot.send_message(ctx.message.channel, msg)
await bot.join_voice_channel(vc)
else:
msg = "Join a voice channel and try again"
await bot.send_message(ctx.message.channel, msg)
async def ycjoin(ctx):
"""Seperate function that joins the voice channel for .play command since async functions can't be called from other async functions"""
if ctx.message.author.voice_channel:
vc = ctx.message.author.voice.voice_channel
msg = "The bot has joined your voice channel"
await bot.send_message(ctx.message.channel, msg)
await bot.join_voice_channel(vc)
else:
msg = "Join a voice channel and try again"
await bot.send_message(ctx.message.channel, msg)
@bot.command(pass_context=True)
async def disconnect(ctx):
"""Disconnects from the voice channel that bot is currently in"""
server = ctx.message.server
if ctx.bot.voice_client_in(server):
voice_client = bot.voice_client_in(server)
msg = "The bot has now disconnected from the voice channel"
await bot.send_message(ctx.message.channel, msg)
await voice_client.disconnect()
else:
msg = "The chatbot is not currently in a voice channel"
await bot.send_message(ctx.message.channel, msg)
@bot.command(pass_context=True)
async def play(ctx,*,url):
"""Downloads the audio from a youtube video via url to play through the voice channel. Don't play two videos at the same time. Use queue instead."""
try:
server = ctx.message.server
if ctx.bot.voice_client_in(server):
server = ctx.message.server
voice_client = bot.voice_client_in(server)
player = await voice_client.create_ytdl_player(url, ytdl_options={'default_search': 'auto'}, after=lambda: check_queue(server.id))
players[server.id] = player
player.start()
msg = "Now playing.... " + str(player.title) + " This video is " +str(player.duration) + " ...seconds long"
await bot.send_message(ctx.message.channel, msg)
else:
await ycjoin(ctx)
if ctx.bot.voice_client_in(server):
server = ctx.message.server
voice_client = bot.voice_client_in(server)
player = await voice_client.create_ytdl_player(url, ytdl_options={'default_search': 'auto'}, after=lambda: check_queue(server.id))
players[server.id] = player
player.start()
msg = "Now playing.... " + str(player.title)
await bot.send_message(ctx.message.channel, msg)
except:
msg = "Sorry, I couldn't find that video you wanted "
await bot.send_message(ctx.message.channel, msg)
#@bot.command functions are not callable in the same or other command functions otherwise it causes an error. So i created a seperate non-command (ycjoin) function to join a voice
#channel and then play the video if the bot was not already in the voice channel. (ycjoin and summon functions are identical)
#the "x" in the argument is needed otherwise the bot will only use the first word of what i want it to search for. It forces the bot to take everything after .play as the
#non-keyworded variable length argument list
@bot.command(pass_context=True)
async def pause(ctx):
"""This pauses the music that is currently playing through the bot"""
server = ctx.message.server
try:
if ctx.bot.voice_client_in(server):
if players[server.id].is_playing()==True:
players[server.id].pause()
msg = "The audio is now paused."
await bot.send_message(ctx.message.channel, msg)
elif players[server.id].is_playing()==False:
msg = "There is nothing currently playing"
await bot.send_message(ctx.message.channel, msg)
if not ctx.bot.voice_client_in(server):
msg = "The bot is not in a voice channel"
await bot.send_message(ctx.message.channel, msg)
except:
msg = "There is no video that is currently loaded. Play something first."
await bot.send_message(ctx.message.channel, msg)
@bot.command(pass_context=True)
async def resume(ctx):
"""This will resume the previously paused audio stream"""
server = ctx.message.server
try:
if ctx.bot.voice_client_in(server):
if players[server.id].is_playing()==False:
server = ctx.message.server
players[server.id].resume()
msg = "The audio feed has now resumed."
await bot.send_message(ctx.message.channel, msg)
elif players[server.id].is_playing()==True:
msg = "It's already playing buddy"
await bot.send_message(ctx.message.channel, msg)
if not ctx.bot.voice_client_in(server):
msg = "The bot is not in a voice channel"
await bot.send_message(ctx.message.channel, msg)
except:
msg = "There is no video that is currently loaded. Play something first."
await bot.send_message(ctx.message.channel, msg)
@bot.command(pass_context=True)
async def stop(ctx):
"""Completely cuts off the audio feed and can't be resumed unlike pause. Only works if there is no queue. Otherwise it just acts as a skip function"""
server = ctx.message.server
players[server.id].stop()
msg = "The audio feed has now been stopped."
await bot.send_message(ctx.message.channel, msg)
@bot.command(pass_context=True)
async def info(ctx):
"""This provides the user information on the YouTube video that is currently playing. Title, duration, upload date and the uploader"""
server = ctx.message.server
player = players[server.id]
msg = "This video is called " + str(player.title) + " and it is " +str(player.duration) + " ...seconds long. It was uploaded on " +str(player.upload_date) + " by " + str(player.uploader)
await bot.send_message(ctx.message.channel, msg)
@bot.command(pass_context=True)
async def queue(ctx,*,url):
"""This allows the user to queue multiple videos to be played by the bot in the order they were entered. Use .play first beforehand"""
server = ctx.message.server
if ctx.bot.voice_client_in(server):
voice_client = bot.voice_client_in(server)
player = await voice_client.create_ytdl_player(url,ytdl_options={'default_search': 'auto'},after=lambda: check_queue(server.id))
if server.id in queues:
queues[server.id].append(player)
else:
queues[server.id] = [player]
msg = "Next up is... " + str(player.title) + " This video will be " +str(player.duration) + " ...seconds long. This video is now in queue. Remember, you must use .play to play a video first before .queue to place others in the queue"
await bot.send_message(ctx.message.channel, msg)
else:
await ycjoin(ctx)
msg = "I have now joined your voice channel. If nothing is playing, Try .play to play a video before placing others in the queue using .queue"
await bot.send_message(ctx.message.channel, msg)
def check_queue(id):
if queues[id] != []:
player = queues[id].pop(0)
players[id] = player
player.start()
@bot.command(pass_context=True)
async def skip(ctx):
"""Skips the current song in the queue."""
server = ctx.message.server
players[server.id].stop()
msg = "Skipped!"
await bot.send_message(ctx.message.channel, msg)
@bot.event
async def on_ready():
print('Logged in as')
print(bot.user.name)
print(bot.user.id)
print('------')
bot.run(TOKEN)