Skip to content

Instantly share code, notes, and snippets.

@mac-chaffee
Last active July 21, 2019 19:33
Show Gist options
  • Select an option

  • Save mac-chaffee/180dea3c29977872014b7ec067c0617b to your computer and use it in GitHub Desktop.

Select an option

Save mac-chaffee/180dea3c29977872014b7ec067c0617b to your computer and use it in GitHub Desktop.
A discord bot that can start, stop, and check the status of Google Compute Engine instances. Automatically shuts down after a configurable amount of time.
import asyncio
import traceback
from discord.ext import commands
from googleapi import GoogleApi
VM_ARGS = {
"instance": "",
"project": "",
"zone": ""
}
SHUTDOWN_REMINDER_SECONDS = 3 * 60 * 60
SHUTDOWN_DELAY = 5 * 60
shutdown_task = None # Will be set to Task that runs shutdown_reminder
bot = commands.Bot(command_prefix="!")
compute = GoogleApi.compute().with_service_account_file("google_cloud_credentials.json")
@bot.command()
async def start(context):
try:
compute.instances().start(**VM_ARGS).execute()
loop = asyncio.get_event_loop()
global shutdown_task
shutdown_task = loop.create_task(shutdown_reminder(context))
await context.send("Start signal sent successfully")
except Exception as err:
print(traceback.format_exc())
await context.send(f"Could not start the server: {repr(err)}")
@bot.command()
async def stop(context):
"""Call do_stop so that code can be reused in shutdown_reminder"""
if shutdown_task:
shutdown_task.cancel()
await do_stop(context)
async def do_stop(context):
try:
compute.instances().stop(**VM_ARGS).execute()
await context.send("Stop signal sent successfully")
except Exception as err:
print(traceback.format_exc())
await context.send(f"Could not stop the server: {repr(err)}")
@bot.command()
async def status(context):
try:
result = compute.instances().get(**VM_ARGS).execute()
current_status = result.get("status", "UNKNOWN")
if current_status == "RUNNING":
external_ip = result["networkInterfaces"][0]["accessConfigs"][0]["natIP"]
await context.send(f"The server is currently {current_status.lower()} on IP {external_ip}")
else:
await context.send(f"The server is currently {current_status.lower()}")
except Exception as err:
print(traceback.format_exc())
await context.send(f"Could not get the server's status: {repr(err)}")
@bot.command()
async def keepalive(context):
global shutdown_task
if shutdown_task:
shutdown_task.cancel()
loop = asyncio.get_event_loop()
shutdown_task = loop.create_task(shutdown_reminder(context))
await context.send(f"Delaying shutdown for another {SHUTDOWN_REMINDER_SECONDS / 3600} hours.")
async def shutdown_reminder(context):
await asyncio.sleep(SHUTDOWN_REMINDER_SECONDS)
await context.send(
f"The server has been running for {SHUTDOWN_REMINDER_SECONDS / 3600} hours. "
f"Automatically shutting down in {SHUTDOWN_DELAY / 60} minutes unless you type !keepalive"
)
await asyncio.sleep(SHUTDOWN_DELAY)
await do_stop(context)
if __name__ == '__main__':
bot.run("")
discord.py==1.2.3
google-api-helper==0.3.1
@mac-chaffee
Copy link
Author

mac-chaffee commented Jul 21, 2019

To run:

  1. Ensure you're using Python version 3.7 or higher
  2. Install the requirements with pip install -r requirements.txt
  3. Follow the instructions here to create a service account .json file and save it as google-cloud-credentials.json in the same folder that the script is running (see line 18)
  4. Create a discord bot here: https://discordapp.com/developers/applications/
  5. Put your bot's token in the bot.run() function on line 82
  6. Get your GCE VM's instance ID, project, and zone and enter that in VM_ARGS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment