Robocalling in 12 minutes*

On John Oliver's Last Week Tonight, he showed how they were robocalling the FCC commissioners. As an offhanded comment he said their tech person literally got it running in less than 15 minutes. I took that as a challenge, and based on a comment from Kirsten, my goal was to get audio of our Audreycat growling when she answered the phone.

I was confident because I knew I had an account ready to go at Twilio. They have developer-friendly APIs and I had previous experience of managing over 10k phone numbers on their platform, though I hadn't done it recently.

So, I bought a phone number from an area code she'd recognize and cobbled together the code from their sample:

from import Client

k = "+15035551212"

client = Client(acct_sid,acct_tok)
call = client.calls.create(


And here's the XML, which tells Twilio what to do after the phone is picked up, which I put on S3:

<?xml version="1.0" encoding="UTF-8"?>
    <Say voice="alice">hi kirsten</Say>

Sure enough, I had her phone ringing 12 minutes later. She picked up, and a robot voice told her there was an error. What?!

So, I did it in 12 minutes, but it took another 13 minutes to figure out what was wrong. Twilio's error console said it was returning a 403 error, which didn't make sense, as I could access the content just fine.

With some further digging I found that the XML URL is hit with POST, so I knew the problem- the content was being served from S3, which only expects a GET. So I had to dig further to find all of the parameters to the Twilio code. It was actually really hard to find good documentation for the python library, as everything pointed to the basics of using the library. Finally I found the entrypoint to the documentation, and after a lot of work I got to the calls.create documentation. It was difficult to find but the answer was easy- I needed to add a parameter called method:

call = client.calls.create(

After doing that it was easy. I can't say it was done in 15 minutes like John Oliver's tech dude, but I still suspect his wasn't fully working after 15 minutes either.

Using shell conditionals in AWS Codebuild

I was working on AWS Codebuild and having trouble getting a conditional to work. In my case, I wanted a "dry run" type flag. I'll use that as the example here.

Conditionals support in Codebuild's buildspec

My first problem was figuring out what shell AWS uses. I didn't find anything on the "Shells and Commands in Build Environments" documentation page, so I decided to keep it really vanilla- avoid using bash specifics and stay close to a POSIX shell. Here was my first try:

    - [ "$DRY_RUN" -gt "0" ] && echo "run my command"

Looks great, right? Well, except I forgot the first rule of yaml: always run a linter. That would have shown me that I was using square brackets in a scalar, which is never a good idea.


So, I quoted the whole thing:

    - '[ "$DRY_RUN" -gt "0" ] && echo "run my command"'
    - |-
        [ "$DRY_RUN" -gt "0" ] && echo "alternate quoting syntax"

And that's what led me to write up this blog entry. That was returning COMMAND_EXECUTION_ERROR in the build:

[Container] 2019/02/28 21:14:25 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: [ "$DRY_RUN" -gt "0" ] && echo "run my command". Reason: exit status 1

When I google for this, I only found a couple lines of linkspam, nothing relevant. I had to iterate several times to solve it, and I ended up just using an if-fi block instead.

    - |-
          if [ "$DRY_RUN" -gt "0" ]; then
            echo "run my command"

And that works! So, TLDR: use the if-fi syntax in a quoted yaml section.

First post!

This is the obligatory "first post" of my new blog. My last blog was from a few years ago, pre-Life Changes, and I've needed something to place random geekery. I love static sites and have opinions, so this is Nikola with Markdown posts and markdown meta-data posts. I tend to write in Markdown even when I never render the content, so .. may as well.

things to write about:

  • how I sync to s3
  • my config changes


  • sync to s3
  • figure out how to add images to posts
  • smugmug?