How To Set Up Automated Chastity Cage Check Emails Using Google Sheets and Apps Script

This is a quick guide to setting up automated chastity cage checks/verification requests by email, using a Google Sheets spreadsheet and some Apps Script code.

It’s a free alternative to workflow automation tools such as IFTTT or Zapier, which do a more flexible job of scheduling, but usually charge on a monthly basis.

What it does

The idea is to set up the Google Sheets spreadsheet to send yourself (or your locked sub) emails during the day, requesting a photo to prove that the sub is still wearing their cage. The spreadsheet contains text that can be selected randomly to generate a variety of emails. The actual email construction and scheduling is then done with some JavaScript-like Google Apps Script code, contained within the spreadsheet.

Step by step process

Create the spreadsheet

Create a Google Sheets spreadsheet in your Google Drive folder. Call it e.g. “Cage checks”.

The next step is technically optional, but makes things easier to manage. For each column of text values that you want the email to select from, create a Named Range (Data menu: Named ranges). These will be used in the Apps Script code later. (Note, if you extend a range later, you must also edit the Named Range to include the extra rows.)

In the above screenshot, the data values in column A have been given the name “Intro”, matching the label in cell A1.

Set up the email constructor

Click the Extensions menu: Apps Script. This opens up a code editor window, where we can write code to generate our cage check emails.

The full code is shown at the end of this section. I’ll explain what each of the sections does.


function sendCageCheckEmail() {
  ...
}

We’re defining a function called sendCageCheckEmail() that will write a cage check email and send it.

  // Randomly select item from an array
  function getRandomItem(array) {
    return array[Math.floor(Math.random() * array.length)];
  }

All the code here and following is indented by two spaces as it goes inside the main sendCageCheckEmail() function. This function getRandomItem() is a utility function that takes an array (a list of text values, for example) and selects one of the values at random. We’ll use it later to choose one of the possible values in our Named Ranges.

  const sheet = SpreadsheetApp.getActiveSheet();
  const spreadsheet = SpreadsheetApp.getActive();
  var send = "yes"
  var space = " "
  var para = "\n\n"

Here we set up references to the cage check spreadsheet. The variable send will be used to control whether the email is sent or not (for testing purposes). The space and para variables (a single space and two new lines, respectively) are used to help format the email correctly.

  // Get values from a named range
  // var intro = getRandomItem(sheet.getRange("A2:A11").getValues())
  var intro = getRandomItem(spreadsheet.getRangeByName("Intro").getValues()).toString();
  var instruction = getRandomItem(spreadsheet.getRangeByName("Instruction").getValues()).toString();
  var clothing = getRandomItem(spreadsheet.getRangeByName("Clothing").getValues()).toString();
  var pose = getRandomItem(spreadsheet.getRangeByName("Pose").getValues()).toString();
  var writing = getRandomItem(spreadsheet.getRangeByName("Writing").getValues()).toString();
  var adjective = getRandomItem(spreadsheet.getRangeByName("Adjective").getValues()).toString();
  var noun = getRandomItem(spreadsheet.getRangeByName("Noun").getValues()).toString();
  var forfeit = getRandomItem(spreadsheet.getRangeByName("Forfeit").getValues()).toString();
  var forfeitoptions = getRandomItem(spreadsheet.getRangeByName("ForfeitOptions").getValues()).toString();

Here we pull in all the Named Ranges in the spreadsheet into variables. The commented line shows that this can be done by direct reference to a range, but mostly we want to use the Named Ranges for this. We then store a clean string that’s been chosen randomly from each named range, in these variables.

  var body = intro + space + instruction + para + clothing + space + pose + space + writing + para + adjective + space + noun + para + forfeit + space + forfeitoptions

We define a variable, body, that will contain the body of the email. It consists of the randomly chosen strings from our spreadsheet, with whitespace added as required.

  Logger.log("Email body: " + body);

This prints the body of the email to console, which helps with debugging when we’re running the code in the editor.

  var message = {
    to: "varlance.interactive@gmail.com",
    subject: "Cage check",
    body: body,
    // cc: "cc@example.com",
    // bcc: "bcc@example.com",
    // replyTo: "help@example.com",
    name: "Sir"
  }

We define a variable called message that represents the cage check email. We can set the ‘to’ email address, subject, email body, sender name, and a few other options.

  if (send == "yes") {
    Logger.log("Sending email...");
    MailApp.sendEmail(message);
  }

Finally, we send the cage check message as an email.

The full script is below.

function sendCageCheckEmail() {
  // Randomly select item from an array
  function getRandomItem(array) {
    return array[Math.floor(Math.random() * array.length)];
  }

  const sheet = SpreadsheetApp.getActiveSheet();
  const spreadsheet = SpreadsheetApp.getActive();
  var send = "yes"
  var space = " "
  var para = "\n\n"
  
  // Get values from a named range
  // var intro = getRandomItem(sheet.getRange("A2:A11").getValues())
  var intro = getRandomItem(spreadsheet.getRangeByName("Intro").getValues()).toString();
  var instruction = getRandomItem(spreadsheet.getRangeByName("Instruction").getValues()).toString();
  var clothing = getRandomItem(spreadsheet.getRangeByName("Clothing").getValues()).toString();
  var pose = getRandomItem(spreadsheet.getRangeByName("Pose").getValues()).toString();
  var writing = getRandomItem(spreadsheet.getRangeByName("Writing").getValues()).toString();
  var adjective = getRandomItem(spreadsheet.getRangeByName("Adjective").getValues()).toString();
  var noun = getRandomItem(spreadsheet.getRangeByName("Noun").getValues()).toString();
  var forfeit = getRandomItem(spreadsheet.getRangeByName("Forfeit").getValues()).toString();
  var forfeitoptions = getRandomItem(spreadsheet.getRangeByName("ForfeitOptions").getValues()).toString();
  
  var body = intro + space + instruction + para + clothing + space + pose + space + writing + para + adjective + space + noun + para + forfeit + space + forfeitoptions
  Logger.log("Email body: " + body);
  
  var message = {
    to: "varlance.interactive@gmail.com",
    subject: "Cage check",
    body: body,
    // cc: "cc@example.com",
    // bcc: "bcc@example.com",
    // replyTo: "help@example.com",
    name: "Sir"
  }
  if (send == "yes") {
    Logger.log("Sending email...");
    MailApp.sendEmail(message);
  }
}

Grant permission to send emails from your Gmail account

Make sure the sendCageCheckEmail() function is the one that’s selected to run. Then click the Run button. If this is the first time it’s running, Google will ask you for permission to send email from your account. Grant permission.

You’ll see the Execution log pop up to show the email being generated and sent.

Set up triggers to send the emails

On the Triggers tab, you can set up triggers that determine when emails will be sent. In this implementation, we set up a trigger that causes the email to be sent at a certain hour of the day.

And that’s it! You can monitor the executions of the cage check emails from the Executions tab.

To turn off email sending, you can either edit/remove the triggers, or you can change the value of the send variable, so that the email is generated but not actually sent.

Additional resources

Spreadsheet.Dev is a very useful resource that explains how to write Google Apps Script code: https://spreadsheet.dev/learn-coding-google-sheets-apps-script