# Messenger Bot: Example Bot Using an External API
###### tags: `MessengerBot`
Besides from webscraping, you can also obtain data from external APIs. In this workshop, I'll making a bot that integrates with the Giphy API to send a gif with my input.

---
## The Process
Goal: Input a keyword and output a related gif.
Since I want to send a image back to the user, I'll probably need:
- send_image()
- Image url returned by the API
---
## Intro to APIs


---
## Using APIs
1. Select an API
2. Read the API Documentation
3. Make a request
5. Do stuff with the response
Quick note: Some APIs might require special authentication steps such as obtaining an API key or an access token. Read the API documentation for access requirements.
---
## Let's jump right in!
The first step is already taken care of for you (by me). We'll be using the Giphy API to fetch gifs based on a user's input.
Onto step 2: reading the API documentation!

Head over to https://developers.giphy.com/docs/api#quick-start-guide to get started.
---
## Step 2: Docs, Docs, Docs 📄
Looks like Giphy has a [Search Endpoint](https://developers.giphy.com/docs/api/endpoint#search), which returns gifs based on a certain query string. Just what we need!
Giphy requires users to obtain an API key (free!) in order to make requests to its API.
1. Go to https://developers.giphy.com/dashboard/?create=true and create a new App (make sure to select API, not SDK)

2. Make a new variable in your .env file

3. Load the env variable to use in your code
```python
GIPHY_API_KEY = os.environ.get("GIPHY_API_KEY")
```
----
Giphy has a neat API explorer tool you can play around with to try the API out: https://developers.giphy.com/explorer/
This endpoint can be broken down like so:
API host: api.giphy.com
Path: /v1/gifs/search
Parameters: ?q=YOUR_INPUT&api_key=YOUR_API_KEY&limit=1
Here's also an example request in a code sample:
https://developers.giphy.com/docs/resource/#code-examples
----
### Search Query
The request to send to Giphy looks like this:
http://api.giphy.com/v1/gifs/search?q=YOUR+SEARCH+HERE&api_key=YOUR_API_KEY&limit=5
From the Echo Bot, we know we can get the user's input using `messaging_event['message']['text'] `
Now, we only need to process that string and insert it into the query.
``` python
# This splits the input string into a list
input = messaging_event['message']['text'].lower().split()
# This turns the list back into a string but separated by +
search_query = "+".join(input)
```
----
### Step 3: Making the Request
``` python
# Base url for GIPHY search endpoint
giphy_url = "http://api.giphy.com/v1/gifs/search?q={input}&api_key={api_key}&limit={limit}"
# Make the request to get the page
query = giphy_url.format(input=search_query, api_key=GIPHY_API_KEY, limit=1)
# Use requests library to make the request
response = requests.get(query)
# Print out the response as JSON
pprint(response.json())
```
----
### Step 4: Parsing the JSON response
The JSON response will look something like this:
```json=
{
"data":
[
{
"type": "gif",
"id": "d3erWmTEGXoiYVgY",
"url": "https://giphy.com/gifs/redandhowling-funny-cute-d3erWmTEGXoiYVgY",
"slug": "redandhowling-funny-cute-d3erWmTEGXoiYVgY",
"bitly_gif_url": "http://gph.is/2ni2FXr",
"bitly_url": "http://gph.is/2ni2FXr",
"embed_url": "https://giphy.com/embed/d3erWmTEGXoiYVgY",
"username": "redandhowling",
"source": "https://shop.redandhowling.com/",
"title": "Tired Good Morning GIF by Red & Howling",
"rating": "g",
"content_url": "",
"source_tld": "shop.redandhowling.com",
"source_post_url": "https://shop.redandhowling.com/",
"is_sticker": 0,
"import_datetime": "2018-01-27 06:14:05",
"trending_datetime": "2019-07-25 15:15:02",
"images":
{
"original":
{
"height": "360",
"width": "480",
"size": "273098",
"url": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/giphy.gif?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=giphy.gif",
"mp4_size": "79611",
"mp4": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/giphy.mp4?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=giphy.mp4",
"webp_size": "125630",
"webp": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/giphy.webp?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=giphy.webp",
"frames": "18",
"hash": "2ec1024afcabfc64aae3f82107427376"
},
"downsized":
{
"height": "360",
"width": "480",
"size": "273098",
"url": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/giphy.gif?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=giphy.gif"
},
"downsized_large":
{
"height": "360",
"width": "480",
"size": "273098",
"url": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/giphy.gif?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=giphy.gif"
},
"downsized_medium":
{
"height": "360",
"width": "480",
"size": "273098",
"url": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/giphy.gif?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=giphy.gif"
},
"downsized_small":
{
"height": "360",
"width": "480",
"mp4_size": "79611",
"mp4": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/giphy-downsized-small.mp4?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=giphy-downsized-small.mp4"
},
"downsized_still":
{
"height": "360",
"width": "480",
"size": "273098",
"url": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/giphy_s.gif?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=giphy_s.gif"
},
"fixed_height":
{
"height": "200",
"width": "267",
"size": "102935",
"url": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/200.gif?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=200.gif",
"mp4_size": "33514",
"mp4": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/200.mp4?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=200.mp4",
"webp_size": "70496",
"webp": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/200.webp?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=200.webp"
},
"fixed_height_downsampled":
{
"height": "200",
"width": "267",
"size": "54229",
"url": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/200_d.gif?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=200_d.gif",
"webp_size": "52392",
"webp": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/200_d.webp?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=200_d.webp"
},
"fixed_height_small":
{
"height": "100",
"width": "134",
"size": "42936",
"url": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/100.gif?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=100.gif",
"mp4_size": "11890",
"mp4": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/100.mp4?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=100.mp4",
"webp_size": "28756",
"webp": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/100.webp?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=100.webp"
},
"fixed_height_small_still":
{
"height": "100",
"width": "134",
"size": "5512",
"url": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/100_s.gif?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=100_s.gif"
},
"fixed_height_still":
{
"height": "200",
"width": "267",
"size": "18942",
"url": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/200_s.gif?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=200_s.gif"
},
"fixed_width":
{
"height": "150",
"width": "200",
"size": "69674",
"url": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/200w.gif?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=200w.gif",
"mp4_size": "22266",
"mp4": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/200w.mp4?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=200w.mp4",
"webp_size": "48262",
"webp": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/200w.webp?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=200w.webp"
},
"fixed_width_downsampled":
{
"height": "150",
"width": "200",
"size": "35675",
"url": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/200w_d.gif?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=200w_d.gif",
"webp_size": "37748",
"webp": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/200w_d.webp?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=200w_d.webp"
},
"fixed_width_small":
{
"height": "75",
"width": "100",
"size": "29834",
"url": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/100w.gif?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=100w.gif",
"mp4_size": "8338",
"mp4": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/100w.mp4?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=100w.mp4",
"webp_size": "21074",
"webp": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/100w.webp?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=100w.webp"
},
"fixed_width_small_still":
{
"height": "75",
"width": "100",
"size": "3858",
"url": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/100w_s.gif?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=100w_s.gif"
},
"fixed_width_still":
{
"height": "150",
"width": "200",
"size": "13301",
"url": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/200w_s.gif?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=200w_s.gif"
},
"looping":
{
"mp4_size": "943174",
"mp4": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/giphy-loop.mp4?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=giphy-loop.mp4"
},
"original_still":
{
"height": "360",
"width": "480",
"size": "48284",
"url": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/giphy_s.gif?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=giphy_s.gif"
},
"original_mp4":
{
"height": "360",
"width": "480",
"mp4_size": "79611",
"mp4": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/giphy.mp4?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=giphy.mp4"
},
"preview":
{
"height": "284",
"width": "378",
"mp4_size": "25753",
"mp4": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/giphy-preview.mp4?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=giphy-preview.mp4"
},
"preview_gif":
{
"height": "154",
"width": "205",
"size": "49562",
"url": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/giphy-preview.gif?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=giphy-preview.gif"
},
"preview_webp":
{
"height": "178",
"width": "238",
"size": "46600",
"url": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/giphy-preview.webp?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=giphy-preview.webp"
},
"hd":
{
"height": "810",
"width": "1080",
"mp4_size": "316666",
"mp4": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/giphy-hd.mp4?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=giphy-hd.mp4"
},
"480w_still":
{
"height": "360",
"width": "480",
"size": "273098",
"url": "https://media0.giphy.com/media/d3erWmTEGXoiYVgY/480w_s.jpg?cid=50ac883419blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&rid=480w_s.jpg"
}
},
"user":
{
"avatar_url": "https://media4.giphy.com/avatars/redandhowling/KBya1PlSw5HO.jpg",
"banner_image": "https://media4.giphy.com/headers/redandhowling/bluYWDAjbKPK.gif",
"banner_url": "https://media4.giphy.com/headers/redandhowling/bluYWDAjbKPK.gif",
"profile_url": "https://giphy.com/redandhowling/",
"username": "redandhowling",
"display_name": "Red & Howling",
"description": "Celebrating our love of animals through super-cute cartoons and animations. shop.redandhowling.com",
"instagram_url": "https://instagram.com/redandhowling",
"website_url": "https://redandhowling.com/",
"is_verified": true
},
"analytics_response_payload": "e=Z2lmX2lkPWQzZXJXbVRFR1hvaVlWZ1kmZXZlbnRfdHlwZT1HSUZfU0VBUkNIJmNpZD01MGFjODgzNDE5Ymx2bW1qd21obmwwZmgyd2h2bzIwcDZ4NmlnZXV3bDlhY3B4ZnE",
"analytics":
{
"onload":
{
"url": "https://giphy-analytics.giphy.com/simple_analytics?response_id=19blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&event_type=GIF_SEARCH&gif_id=d3erWmTEGXoiYVgY&action_type=SEEN"
},
"onclick":
{
"url": "https://giphy-analytics.giphy.com/simple_analytics?response_id=19blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&event_type=GIF_SEARCH&gif_id=d3erWmTEGXoiYVgY&action_type=CLICK"
},
"onsent":
{
"url": "https://giphy-analytics.giphy.com/simple_analytics?response_id=19blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq&event_type=GIF_SEARCH&gif_id=d3erWmTEGXoiYVgY&action_type=SENT"
}
}
}
],
"pagination":
{
"total_count": 19754,
"count": 1,
"offset": 0
},
"meta":
{
"status": 200,
"msg": "OK",
"response_id": "19blvmmjwmhnl0fh2whvo20p6x6igeuwl9acpxfq"
}
}
```
Parsing the gif url:
``` python
# Check if request was successful
if (response.status_code == 200):
# Get the first gif from the list returned
gif_obj = response.json()['data'][0]
# Get the .gif url of the gif
gif_url = gif_obj['images']['original']['url']
```
---
### Return the image
``` python
# Send image link
messager.send_image(sender_id, gif_url)
```
---
### Test it out!
Message your bot a word or phrase (i.e "dog") and get a gif back!

Challenge: Modify the code such that a random gif is returned (instead of always returning the same gif)
---
Full Code:
```python=
# Loads environment variable
GIPHY_API_KEY = os.environ.get("GIPHY_API_KEY")
# This splits the input string into a list
input = messaging_event['message']['text'].lower().split()
# This turns the list back into a string but separated by +
search_query = "+".join(input)
# Base url for GIPHY search endpoint
giphy_url = "http://api.giphy.com/v1/gifs/search?q={input}&api_key={api_key}&limit={limit}"
# Make the request to get the page
query = giphy_url.format(input=search_query, api_key=GIPHY_API_KEY, limit=1)
# Use requests library to make the request
response = requests.get(query)
# Check if request was successful
if (response.status_code == 200):
# Get the first gif from the list returned
gif_obj = response.json()['data'][0]
# Get the url of the gif
gif_url = gif_obj['images']['original']['url']
# Send image link
messager.send_image(sender_id, gif_url)
```
## That's it!
That's it for the intro to API workshop! You can play around with the Giphy API and do some cooler stuff, or check out other APIs you want to integrate into your bot.
Here are some fun APIs to explore:
- Dog API: https://docs.thedogapi.com/
- Pokemon API: https://pokeapi.co/
- Food API: https://spoonacular.com/food-api/
- Create Meme API: https://imgflip.com/api