Pull Congressional Data via SMS with the Congress API and JavaScript
Tags: javascript, tutorial, serverless, twilio
Published: 2022-10-31 23:27:27

---
title: Pull Congressional Data via SMS with the Congress API and JavaScript
published: true
cover_image: https://twilio-cms-prod.s3.amazonaws.com/images/Copy_of_C01_Blog_Text_4LrpoGM.width-1616.png
description: Pull data about Congress via SMS using the new Congress API and Twilio Serverless!
tags: javascript, tutorial, serverless, twilio
# Use a ratio of 100:42 for best results.
# published_at: 2022-10-31 23:04 +0000
---
This blog post was written for [Twilio](https://www.twilio.com/) and [originally published on the Twilio blog](https://www.twilio.com/blog/congress-api-sms).

Congress recently came out with an official API so the public can "view, retrieve, and re-use machine-readable data from collections available on Congress.gov!" Read on to learn how to read congressional data using the [Congress API](https://api.congress.gov/), [Twilio Functions](https://www.twilio.com/docs/runtime/functions), and the [Twilio Serverless Toolkit](https://www.twilio.com/docs/labs/serverless-toolkit).

<em>Text "bill", "amendment", or "summaries" to <strong>+12029337044</strong> to receive data about a random bill or amendment!</em>
![sms example](https://twilio-cms-prod.s3.amazonaws.com/images/HYVHmE_W9Y8knYpQ9QYbRs1ZmWT5wHog1u6cqJqNC4xzG.width-1000.jpg)

### Prerequisites
1. A Twilio account - [sign up for a free one here](https://www.twilio.com/try-twilio)
2. A Twilio phone number with SMS capabilities - [configure one here](https://support.twilio.com/hc/en-us/articles/223135247-How-to-Search-for-and-Buy-a-Twilio-Phone-Number-from-Console)
3. A Congress.gov API Key – [get one here](https://api.congress.gov/sign-up/)
4. [Postman](https://www.postman.com/downloads/) (you could alternatively make cURL requests from the command line)
5. Node.js installed - [download it here](https://nodejs.org/en/download/)

### Make a congress.gov Request
You can look over the [different Congress API endpoints offered here](https://api.congress.gov/#/). To get someone's profile information, the URL would look like `[https://api.congress.gov/v3/bill/117/s/4693/summaries](https://api.congress.gov/v3/bill/117/s/4693/summaries)` where 117 is the [Congress number[https://en.wikipedia.org/wiki/117th_United_States_Congress](https://en.wikipedia.org/wiki/117th_United_States_Congress), "s" is the type of bill, and "4693" is the bill number. Open Postman and paste that URL into the URL bar.

Add your API Key under Params: the `key` is `api_key` and the `value` is your Congress API Key.

Click `Send` to hit it with a GET request to see the following data returned:
![congress API data returned in Postman](https://twilio-cms-prod.s3.amazonaws.com/images/Screen_Shot_2022-10-29_at_3.04.38_PM.width-1600.png)
Again, you can see [more Congress API endpoints here you can play around with](https://api.congress.gov/)!

### Get Started with the Twilio Serverless Toolkit
The Serverless Toolkit is CLI tooling that helps you develop locally and deploy to [Twilio Functions & Assets](https://www.twilio.com/docs/serverless/functions-assets). The best way to work with the Serverless Toolkit is through the [Twilio CLI](https://www.twilio.com/docs/twilio-cli/quickstart). If you don't have the Twilio CLI installed yet, run the following commands on the command line to install it and the Serverless Toolkit:
```bash
npm install twilio-cli -g
twilio login
twilio plugins:install @twilio-labs/plugin-serverless
```
Afterwards, create your new project and install our lone requirement `[undici](https://github.com/nodejs/undici)` to make HTTP requests in Node.js by running:
```bash
twilio serverless:init congress-api-sms –template=blank
cd congress-api-sms
npm install -s undici
```
The Functions and Assets team recommends using `undici` with your Functions.

### Set an Environment Variable with Twilio Functions and Assets
Open up your `.env` file for your Functions project in your root directory and add the following line:
```bash
CONGRESS_API_KEY=YOUR-CONGRESS-API-KEY
```
Now you can access this API Key if you'd like to do so in your code with `context.CONGRESS_API_KEY`.
### Make a Twilio Function with JavaScript
Make a new file in the `/functions` directory called <em>congress.js</em> containing the following code:
```javascript
exports.handler = async (context, event, callback) => {
  const { request } = await import('undici');
  const inbMsg = event.Body.toLowerCase().trim();
  const twiml = new Twilio.twiml.MessagingResponse();
  if(inbMsg.includes("bill")) {
    const {
      body
    } = await request(`https://api.congress.gov/v3/bill?api_key=${context.CONGRESS_API_KEY}`);
    const data = await body.json();
    const billsLength = data.bills.length;
    const randNum = Math.floor(Math.random() * (billsLength - 1)) + 1;
    const bill = data.bills[randNum];
    const { latestAction, title, type, number, originChamber } = bill;
    
    const billMap = {
        HR: "house bill",
        S: "senate bill",
        HJRES: "house joint resolution",
        SJRES: "senate joint resolution",
        HCONRES: "house concurrent resolution",
        SCONRES: "senate concurrent resolution",
        HRES: "house simple resolution",
        SRES: "senate simple resolution"
    };
    twiml.message(`Bill: ${title}.\nType: ${billMap[type]}\nAssigned bill or resolution number:   ${number}\nIt originated in the ${originChamber} but the latest action was ${latestAction.text} on ${latestAction.actionDate}`);
  }
  else if(inbMsg.includes("amendment")) {
    const {
      body
    } = await request(`https://api.congress.gov/v3/amendment?api_key=${context.CONGRESS_API_KEY}`);
    const data = await body.json();
    const amendmentLength = data.amendments.length;
    const randNum = Math.floor(Math.random() * (amendmentLength - 1)) + 1;
    const amendment = data.amendments[randNum];
    const { latestAction, purpose, congress, number } = amendment;
    twiml.message(`Amendment purpose: ${purpose}\nAssigned amendment or resolution number:${number}\n Latest action was on ${latestAction.actionDate} to ${latestAction.text}.\n Congress: ${congress}.`);
  }
  else if(inbMsg.includes("summaries")) {
    const CURRENT_CONGRESS = 117;
    const {
      body
    } = await request(`https://api.congress.gov/v3/summaries/${CURRENT_CONGRESS}?api_key=${context.CONGRESS_API_KEY}`);
    const data = await body.json();
    const sumLength = data.summaries.length;
    const randNum = Math.floor(Math.random() * (sumLength - 1)) + 1;
    const summaries = data.summaries[randNum];
    const { bill, currentChamber, text, actionDate, actionDesc } = summaries;
    const regexToStripHtmlTags = /<(.|\n)*?>/g;
    const textWithoutHtmlTags = text.replace(regexToStripHtmlTags, '');
    const msg = `Summary title: ${bill.title}.\nStarted in: ${bill.originChamber} on ${actionDate}, currently in the ${currentChamber} chamber in Congress ${bill.congress} and it was ${actionDesc}\n${textWithoutHtmlTags}`; 
    twiml.message(msg);
  }
  else {
    twiml.message(`Send "bill", "amendment", or "summaries"`);
  }
  callback(null, twiml);
};
```
This code imports `undici`, makes a [Twilio Messaging Response object](https://www.twilio.com/docs/sms/api/message-resource), creates a variable `inbMsg` from the inbound text message users will text in and checks if that message input contains `bill`, `amendment`, or `summaries` (three endpoints of the Congress API). The code then generates a random number based on the total amount of items returned from the Congress API to select a random Bill or Amendment, parses the responses from that given endpoint (as we saw using Postman above) into variables such as the type of Amendment or Bill, the most recent date some action was taken, and more!

If someone does not send a message containing "bill", "summaries", or "amendment" (the three topics they can learn about), we return a message saying so. Else, we parse the Congress object returned for information such as the latest action taken on a bill, type of bill, purpose of the given random amendment, origin chamber of a bill, and more. We return a text message containing that data!

You can view the [complete app on GitHub here](https://github.com/elizabethsiegle/congress-api-sms-serverless).

### Configure the Function with a Twilio Phone Number
To open up our app to the web with a public-facing URL, run `twilio serverless:deploy` from the `congress-api-sms` root directory. You should see this at the bottom of your terminal:
![twilio function urls once deployed](https://twilio-cms-prod.s3.amazonaws.com/images/vRoJgBk9ankJswPRzdI7pB9d4Z_bDg7k8VqGl553E1xte.width-1000.png)
Grab the Function URL corresponding to your app (the one that ends with `/congress`) and configure a Twilio phone number with it as shown below: select the Twilio number you just purchased in your Twilio phone numbers console and scroll down to the <em>Messaging</em> section. Paste the link in the text field for <em>A MESSAGE COMES IN</em> webhook making sure that it's set to <em>HTTP POST</em>. When you click <em>Save</em> it should look like this!
![messaging section of twilio phone number](https://twilio-cms-prod.s3.amazonaws.com/images/VpL0FI8mnh3kr34peiPb84tWuvxnW3apxB9qAKrDcC90F.width-1000.png)
The Service is the Serverless project name, environment provides no other options, and Function Path is the file name. Now take out your phone and text "bill" or "amendment" or "summaries" to your Twilio number.
![sms example](https://twilio-cms-prod.s3.amazonaws.com/images/MP41e2iatOLCc2VsbIoOVxzEXTKL9OEPW1JQOpZw9OWNe.width-1000.jpg)
### What's Next for Twilio Serverless and the Congress API?
![being in congress must be fun kimmy schmidt gif](https://twilio-cms-prod.s3.amazonaws.com/original_images/XPsVwWwntVmcz3LF9bTOJC2Cv4vgEfXpYRFd6bI7mNqwMUNbJNiPbsvkh0BoEFcgrkkP4pyQIiucSG)
Twilio's Serverless Toolkit makes it possible to deploy web apps quickly, and Functions & Assets seamlessly handles servers for you. You can do a lot with this data, and you can see what actions Congress are taking--it's fun data to play around with! Let me know online what you're building with Twilio Functions&Assets and don't forget to vote this November!