The Syllabus The Fine Print The Notes

The Notes

Here’s where you’ll find resources, code, links, and notes for every class. Materials are added here generally at least one day before each class, but can change and get updated up until class time.

Class 1 • Basic internetting


Products in Journalism

What’s a Prototype (for us)?

Quick Examples

Logistics & plan

Exploring web pages


This is the “Class 1” assignment. Do it now … it’s due on at high noon before Class 2.

Start a new hello-webpage project in Glitch and make it your own. Change colors, play with formatting, play with the text. Get creative! Google around for html tips and tricks if you want. Post the link to your project in Slack in #design-dev so we can all try it.

Class 2 • Roll your own information service

Quick review of last week

Note on “assets”

A little more advanced Internetting

A different structure


What we did last week:

  1. Request: You -> -> Glitch
  2. Response: Glitch -> index.html -> you

Static, but server-driven

Instead of Glitch just serving up your fixed or static html page (as in Class 1) you’re using a “server” file that serves up the page.

  1. Request: You -> -> Glitch
  2. Response: Glitch -> server.js -> index.html -> you


  1. Request: You -> -> Glitch
  2. Response: Glitch -> server.js -> get data -> inject data -> fact-page.html -> you

Dynamic with a database

  1. Request: You -> -> Glitch
  2. Response: Glitch -> server.js -> query a database -> get the answer -> turn into JSON -> you

Let’s get some dog data


A little bit of SQL

Data on the web


This is the “Class 2” assignment. Do it now … it’s due on at high noon before Class 3.

Add a new “route” to your web service that, when hit by a web browser, displays a list of the top 5 dog breeds (by count) in the database. Paste a link to that route into Slack.

Class 3 • Texting as a service

Review last class

Walkthrough: Handling texts with Twilio

Twilio is a service that accepts text messages (also phone calls!) and sends them on to a web service – like Newmark Bark!

Here’s the path:

- **Request:** Your phone > the service phone number > Twilio > Our Glitch site
- **Response:** Our Glitch site > Twilio > your phone number > your phone 

If you send “hello” the service phone number, here’s what Twilio sends to our Glitch site:

    "ToCountry": "US",
    "ToState": "NY",
    "SmsMessageSid": "SM184eed5c374485f10ef379ec9a2e2259",
    "NumMedia": "0",
    "ToCity": "NEW YORK CITY",
    "FromZip": "10010",
    "SmsSid": "SM184eed5c374485f10ef379ec9a2e2259",
    "FromState": "NY",
    "SmsStatus": "received",
    "FromCity": "NEW YORK",
    "Body": "hello",
    "FromCountry": "US",
    "To": "+1929xxxxxxx",
    "ToZip": "",
    "NumSegments": "1",
    "MessageSid": "SM184eed5c374485f10ef379ec9a2e2259",
    "AccountSid": "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "From": "+1917xxxxxxx",
    "ApiVersion": "2010-04-01"

Quick digression: GET vs POST

We’ll use “POST” requests in our project.

Replying to Twilio

First we have to accept incoming POST messages. So I added this “route” to server.js in my original Glitch app (note that this goes just above the line that reads “listen for requests :)” ):'/text/name', function(request,response) {
  var data = {} // no data yet
  response.render('text-back.html', data)

To send back a message to Twilio, there’s a special little language that Twilio uses (they call TwiML), which looks like this:

<?xml version="1.0" encoding="UTF-8"?>
    <Message>Hello back!</Message>

The Twilio documentation has more about this, if you ever need to explore it.

I’ve stored exactly that code above as views/text-back.html in my Glitch app.

We send that back to Twilio in our Glitch app just like we did with the fact-page.html

Let’s get more sophiticated

Remember … request.body is all of our text data … and request.body.Body is the message itself. So we can use that in our code.

So we can get all of the message, and pass the name into the database.

I’ll step through what you’ll do.

Your turn

Preparing the Glitch side:'/text/name', function(request,response) {
    db.all('SELECT dog_name, count(dog_name) AS total FROM doginfo WHERE dog_name LIKE "' + request.body.Body + '" GROUP BY dog_name COLLATE NOCASE', function(err, rows) {
    if (err) {
    var data = rows[0]
    response.render('text-back.html', data)
<?xml version="1.0" encoding="UTF-8"?>
    <Message>There are  dogs by that name!</Message>

Set Up Twilio

We’ll be using Twilio to make the connection between the telephone systems and your code.

This is the “Class 3” assignment. Do it now … it’s due on at high noon before Class 4 (Which is THURSDAY).

Add a the new “route” to your web service that so that when I text your phone number I get the right number of dogs. Make sure it works and post a screenshot of your interaction with your bot into Slack.

Class 4 • Introduction to conversational interfaces

Say what? Computers understanding human language

Automatically processing what someone is saying – either in a chat, to a voice assistant, or in an email – is increasingly possible thanks to machine learning. We’ll play with one of these natural language processing tools (Dialogflow) to get a handle on how to make it work for you.


Also called “Training Phrases” (Dialogflow).

Those are all the things a human might say that mean the same intent. So:

… could all utterances for an intent we might call the chitchat-wow intent. The more utterances, the better the NLP learns.


Having your bot (or any conversational software) understand “yes” is pretty clear. But what if people say yes differently?

You can teach it that phrases like this mean “yes.” So we could call this intent chitchat-yes.

If we see words like the above, we could say these are chitchat-no.

And words like these could mean the chitchat-wow intent.

So you could make bot responses to those intents instead of those words, and let the Natural Language Processor decide which intent is, um, intended.


Interestingly, most natural language systems allow you to review its decisions and train it when it performed well and performed poorly.

More intents

Consider the intents for the following phrases:


To answer a “forecast” intent, you need two additional pieces of information: Where and when.

These are called “entities” (and also slots and elements and probably many other things).

So a weather-forcast intent requires place and time.


In Dialogflow, you can name an “action” in addition to an intent. The action is the name of something that should be done. It can be passed along to your code.

Introduction to Dialogflow

There are lots of tools out there to use. We’ll play with Dialogflow (which used to be called … so there may be some notations here that still reference that).


As usual, you’ll need to sign up. It’s free. And you’ll need a Google/Gmail account.

OK, your “agent” is established.

You have now turned on a bunch of default responses for common things humans say to bots.

You can alter the default responses on this page, tho it would take you a while to go through them all.

Try typing some things in the “Try it now” space in the upper right corner.

Note that these defaults do not result in an intent. That’s because we haven’t made them yet. They do however, result in an action which we can use.

Play a little

Find the “Try it now” box at the top and try typing some random phrases that might constitute small talk. What happens?

Pay close attention to the “Intent” and “Action” areas.

Also try things that might be casual synonyms for “yes” and “no.”


This is the “Class 4” assignment. Do it now … it’s due on at high noon before Class 5 (Which is a week from Monday).

“Hi, I’m Newmark Bark! Ask me anything about dogs and dog ownership in New York City!”

Here’s an example:

Class 5 • Talk to me: Making a voice service for Google Home

Giving Dialogflow more smarts

Remember, last class we taught Dialogflow to (mostly!) identify the dog name in the natural language phrase, “How many dogs are named spot?”. But it didn’t answer the question.

To answer the question, we need to ask our special service – which lives in Glitch! Let’s set up Glitch to answer the question.

Updating our Glitch project to fulfill the requests

Dialogflow is going to send us a “fulfillment request.” If you’d like to see the whole “payload” it will send, look at the documentation here.

The key piece we’re going to want is the “dogname” value, right? We need to know the name of the dog to look up. That’s represented by this value in the payload: queryResult.parameters.dogname

So this is the code we’ll add to the server.js file in our Glitch app. Remember to paste this on a blank line above the “// listen for requests :)” line!'/voice/name', function(request, response){
  var search_dog = request.body.queryResult.parameters.dogname 
  db.all('SELECT dog_name, count(dog_name) AS total FROM doginfo WHERE dog_name LIKE "' + search_dog + '" GROUP BY dog_name COLLATE NOCASE', function(err, rows) {
    if (err) {
    var total_dogs
    if (rows.length < 1) {
      total_dogs = "no"
    }  else {
      total_dogs = rows[0].total
    var response_phrase = `There are ${total_dogs} dogs named ${search_dog} in New York City.`

    var data ={
      "fulfillmentText": response_phrase


We’ll walk through this in class. It should be mostly familiar!

Important fix: We also need to change line No. 9 in the Glitch script.


app.use(bodyParser.urlencoded({ extended: true }));

And replace it with:


Add fulfillment to our intent

Now we have to go back and get this intent set up for being “fulfilled” this way:

Wiring it up to Google Assistant (and Google Home)

Quick updates we’ll need for Dialogflow

Need to tie that to one of the “Actions by Google”

Head back to Dialogflow

Testing in Actions by Google

You can also get here from Dialogflow by clicking “See how it works in Google Assistant”

Deployment (aka: Making it available to others)

You can make Google Assistant apps available to others, either a select group of testers or to the public at large. Here is a good post outlining the steps for doing that.


This is the “Class 5” assignment. Do it now … it’s due on at high noon before Class 5 (Which is a week from WEDNESDAY).

Show me that you’ve successfully connected Dialogflow to your Glitch service, and that you get a correct answer when you ask “How many dogs are named spot.” We’ll do this in class. Make sure I watch you do it individually.

If you can’t do this in class, or were not in class, use QuickTime to make a screen recording of you using it and DM that recording to me in Slack.

Class 6 • Storytelling with chat & voice

Tips for crafting story flow

Watch this video … which is essentially the class presentation.

Build a bot using Dexter

We’ll step through the slides for today’s class.


This is the “Class 6” assignment. Do it now … it’s due on at high noon before Class 7.

Go through the Build-a-Bot workshop using Dexter and publishing all of your topics to the web. Then paste the url for your bot into Slack.

That’s it! If you get errors, hit me up in Slack. Give yourself time to work on it and debug it.

Class 7 • Make bots to do your bidding

We’ll particularly focus on automated bot tools for journalists.

Anatomy of a bot

Google Alerts

Make a Google alert for stories and people, especially when you’re working on them.

What’s the trigger? What’s the response?




Introduction to APIs

Putting it into Dexter!

+ whats a bitcoin worth
- The current price of one bitcoin is $ dollars.