Permalink
Cannot retrieve contributors at this time
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?
Chatbot/mo.py
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
247 lines (209 sloc)
10.9 KB
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
###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) |