-
Notifications
You must be signed in to change notification settings - Fork 3.8k
/
index.js
123 lines (111 loc) · 4.3 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/**
* Copyright 2017 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const language = require('@google-cloud/language');
const client = new language.LanguageServiceClient();
const express = require('express');
const app = express();
// Express middleware that validates Firebase ID Tokens passed in the Authorization HTTP header.
// The Firebase ID token needs to be passed as a Bearer token in the Authorization HTTP header like this:
// `Authorization: Bearer <Firebase ID Token>`.
// when decoded successfully, the ID Token content will be added as `req.user`.
const authenticate = async (req, res, next) => {
if (!req.headers.authorization || !req.headers.authorization.startsWith('Bearer ')) {
res.status(403).send('Unauthorized');
return;
}
const idToken = req.headers.authorization.split('Bearer ')[1];
try {
const decodedIdToken = await admin.auth().verifyIdToken(idToken);
req.user = decodedIdToken;
next();
return;
} catch(e) {
res.status(403).send('Unauthorized');
return;
}
};
app.use(authenticate);
// POST /api/messages
// Create a new message, get its sentiment using Google Cloud NLP,
// and categorize the sentiment before saving.
app.post('/messages', async (req, res) => {
const message = req.body.message;
try {
const results = await client.analyzeSentiment({document: message});
const category = categorizeScore(results[0].documentSentiment.score);
const data = {message: message, sentiment: results, category: category};
const snapshot = await admin.database().ref(`/users/${req.user.uid}/messages`).push(data);
const val = snapshot.val();
res.status(201).json({message: val.message, category: val.category});
} catch(error) {
console.log('Error detecting sentiment or saving message', error.message);
res.sendStatus(500);
}
});
// GET /api/messages?category={category}
// Get all messages, optionally specifying a category to filter on
app.get('/messages', async (req, res) => {
const category = req.query.category;
let query = admin.database().ref(`/users/${req.user.uid}/messages`);
if (category && ['positive', 'negative', 'neutral'].indexOf(category) > -1) {
// Update the query with the valid category
query = query.orderByChild('category').equalTo(category);
} else if (category) {
res.status(404).json({errorCode: 404, errorMessage: `category '${category}' not found`});
return;
}
try {
const snapshot = await query.once('value');
let messages = [];
snapshot.forEach((childSnapshot) => {
messages.push({key: childSnapshot.key, message: childSnapshot.val().message});
});
res.status(200).json(messages);
} catch(error) {
console.log('Error getting messages', error.message);
res.sendStatus(500);
}
});
// GET /api/message/{messageId}
// Get details about a message
app.get('/message/:messageId', async (req, res) => {
const messageId = req.params.messageId;
try {
const snapshot = await admin.database().ref(`/users/${req.user.uid}/messages/${messageId}`).once('value');
if (!snapshot.exists()) {
return res.status(404).json({errorCode: 404, errorMessage: `message '${messageId}' not found`});
}
return res.set('Cache-Control', 'private, max-age=300');
} catch(error) {
console.log('Error getting message details', messageId, error.message);
return res.sendStatus(500);
}
});
// Expose the API as a function
exports.api = functions.https.onRequest(app);
// Helper function to categorize a sentiment score as positive, negative, or neutral
const categorizeScore = (score) => {
if (score > 0.25) {
return 'positive';
} else if (score < -0.25) {
return 'negative';
}
return 'neutral';
};