cocozxu / serverless-reader

GNU General Public License v3.0
0 stars 1 forks source link

Emotionalgifs #13

Closed cocozxu closed 3 years ago

ghost commented 3 years ago

Week 2 Step 4 ⬤⬤⬤⬤◯◯◯◯ | 🕐 Estimated completion: 5-10 minutes

Getting Emotional ~ Returning the Dominant Emotion

✅ Task:

Modify your Azure Function so that it returns the Dominant Emotion of an Image.

1. Finding the Dominant Emotion

In order to match the results of the Face API with Gifs from the Giphy API, we need to determine the dominant emotion from the API response.

:hammer_and_wrench: Modifying the Azure Function

We need to access the emotion data by itself, without the face id and other analyzed data. To do this, we need to create another variable in the first async function in our Azure Function:

let emotions = result[0].faceAttributes.emotion;

:bulb: Now you've got the JSON object with all the emotion values, find the highest valued emotion! Use context.log(emotions) to see how it's structured.

We're accessing the data at index 0 because we're analyzing one face. If there were two faces, the data for the second face would be stored at index 1.

❓ How do I find the max value from the JSON object?
1️⃣ We need to create **an array** with the emotion values (ranging from 0 to 1) so that we can manipulate it and find the dominant emotion. `Object.values()` converts an object into an array, with each **value** in the object stored as a separate element: ```js let objects = Object.values(WHAT_IS_YOUR_JSON); // FILL IT IN // What your array could look like: [0.01, 0.34, .....] ``` > :bulb: In JSON, the **key** values are what you use to access the **value**. `{key: value}`, or in our case, `{emotion: value}`. Finally, we need to find the dominant emotion in the array `objects`: 2️⃣ Let's break this line down. ```js const main_emotion = Object.keys(emotions).find(key => emotions[key] === Math.max(...objects)); ``` - `Math.max(...objects)` finds the max value. Let's say it's `0.99`. - `Object.keys(emotions).find(key => emotions[key] === Math.max(...objects));` finds the emotion, or key, that matches the max value of `0.99`. Let's say it's `happiness`. 3️⃣ Now, `main_emotion` contains the dominant emotion! All we need to do is output `main_emotion` when the function is called: ```js context.res = { // status: 200, /* Defaults to 200 */ body: main_emotion }; ```
ghost commented 3 years ago

Week 2 Step 5 ⬤⬤⬤⬤⬤◯◯◯ | 🕐 Estimated completion: 20-30 minutes

Getting Emotional ~ Calling the Giphy API

✅ Task:

Call the GIPHY API with the dominant emotion of a picture

:construction: Test your work

Create a POST request in Postman. Use the function URL as the request URL, and send an image in the body of the request:

Screen Shot 2021-05-30 at 3 07 21 PM
:white_check_mark: Expected Output
The link outputted by the function should look something like this:

`https://giphy.com/gifs/happy-spongebob-squarepants-happiness-brHaCdJqCXijm`

1. Using the GIPHY API

We're going to connect the your first Azure function, emotionalgifs, with the GIPHY API.

Creating a GIPHY Account

Set up an account by clicking here and enter an email address, username, and password.

Generating an API Key

According to the documentation, an API key is a required parameters in a call to GIPHY's translate endpoint. The link (for gifs) that is listed in the documentation is the endpoint we will be using in this project.

:question: How do I create an API key?
To create an **API key** click [here](https://developers.giphy.com/dashboard/) and click Create an App.
Screen Shot 2021-04-15 at 5 55 16 PM Select API, **not** SDK!
Screen Shot 2021-04-15 at 5 55 32 PM Then, enter the required information.
Screen Shot 2021-04-15 at 5 55 41 PM Click **Create App**, and your key should be given. Next, store your API key in your Azure Function's environment secrets.

2. Modifying the Azure Function

We will be calling the GIPHY API in the same function that analyzes inputted images.

Create another async function in emotionalgifs called findGifs. It needs a parameter through which we can pass the dominant emotion of an image. Call this parameter emotion.

:bulb: Use the documentation to create a request to the Giphy API in the function.

:question: How do you call the GIPHY API?
We're going to call the GIPHY API inside our new async function using `fetch`. Use the **translate endpoint** from the [documentation](https://developers.giphy.com/docs/api/endpoint#translate). HINT: we want the dominant emotion from the image to be the **search term**, and we only want **1 gif** to be returned. ```js //COMPLETE THE CODE const apiResult = await fetch ("https://api.giphy.com/v1/gifs/translate?//WHAT GOES HERE?"); ``` > **Hint**: If you read the documentation correctly, you should see that you need to use your API key in the request. Remember to access your environment secrets, you can use `process.env['the secret name']` We need to convert the content of `apiResult` into **JSON format**. Remember, we're using the `await` keyword because `fetch` (which we used to call the GIPHY API) returns a Promise, and a Promise is a **proxy** for a value that isn't currently known. ```js const jsonResult = await //WHAT GOES HERE?.json(); ``` Finally, we need to return a specific link from the JSON file stored in `jsonResult`: ```js return //WHAT GOES HERE.data.url; ```

Now that you have a async function that can can the Giphy API with an emotion and return a gif link, you need to incorporate it in the main module.exports function.

TIP: Use await to receive a response from the function since it is async!

❗ How should I call the findGifs function we wrote?

Let's call findGifs in the first async function in emotionalgifs. Currently, our first async function looks like this:

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    var boundary = multipart.getBoundary(req.headers['content-type']);
    var body = req.body;
    var parts = multipart.Parse(body, boundary);

    var result = await analyzeImage(parts[0].data);

    let emotions = result[0].faceAttributes.emotion;
    let objects = Object.values(emotions);
    const main_emotion = Object.keys(emotions).find(key => emotions[key] === Math.max(...objects));

    context.res = {
        // status: 200, /* Defaults to 200 */
        body: main_emotion
    };
    console.log(result)
    context.done();
}

We need to declare another variable, gif. It needs to store the link returned when our new async function, findGifs, is called. Also, the dominant emotion from our analyzed image needs to be passed through the emotion parameter.

var gif = await //WHAT GOES HERE?

Finally, we need our new variable gif to be the output of emotionalgifs rather than main_emotion:

context.res = {
    // status: 200, /* Defaults to 200 */
    body: //WHAT GOES HERE?
};



ghost commented 3 years ago

⏰ Time to merge!

Go ahead and merge this branch to main to move on. Great work finishing this section!

merge

⚠️ If you receive a Conflicts error, simply press Resolve conflicts and you should be good to merge!