-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
148 lines (142 loc) · 5.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
'use strict';
const http = require('http');
/*
* HTTP Cloud Function.
*
* @param {Object} req Cloud Function request context.
* @param {Object} res Cloud Function response context.
*/
exports.poetryDesk = function poetryDesk (req, res) {
console.log('poetryDesk start request: ', req)
let poet = '';
if (req.body.result.parameters['poet']) {
poet = req.body.result.parameters['poet'];
}
console.log('poetryDesk poet: ', poet)
// Call the poetry API
getRandomPoemByPoet(poet)
.then(output => {
console.log('poetryDesk getRandomPoemByPoet fulfillment output: ', output)
console.log('poetryDesk res: ', res)
// Return the results of the poetry API to Dialogflow
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ speech: output, displayText: output }));
}, rejectReason => {
console.log('poetryDesk getRandomPoemByPoet rejectReason: ', rejectReason)
console.log('poetryDesk res: ', res)
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ speech: 'Something went wrong, check the logs', displayText: rejectReason }));
})
.catch(error => {
console.log('poetryDesk error: ', error)
// If there is an error let the user know
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({ speech: error, displayText: error }));
});
};
/*
* getRandomPoemByPoet
*
* @param {String} poet Poet name to search in poetrydb api, first then middle (if applicable) then last name, separated by spaces, requires exact match
*/
const getRandomPoemByPoet = poet => {
return new Promise((resolve, reject) => {
let speechOutput = '';
// neither encodeURI nor encodeURIComponent work here since GC converts spaces to %C2%A0, but the api only supports %20 or + for spaces
const poemTitlePath =
'http://poetrydb.org/author/' + poet.replace(/\s+/, '+') + '/title';
console.log('getRandomPoemByPoet API call: ', poemTitlePath)
http.get(poemTitlePath, res => {
// Handle server errors
const { statusCode } = res;
let error;
if (statusCode !== 200) {
error = new Error(`Request Failed - Status Code: ${statusCode}`);
console.error(error.message);
res.resume(); // consume response data to free up memory
speechOutput = `I'm sorry, there was an error with the poetry service - we've been notified, please try again later`;
resolve(speechOutput);
}
// Handle server response
let body = ''; // store the response chunks
res.on('data', d => {
body += d;
}); // accumulate response chunks
res.on('end', () => {
let poems = JSON.parse(body);
console.log('getRandomPoemByPoet http end poems: ', poems)
if (poems.length > 0) {
const randomPoemTitle =
poems[Math.floor(Math.random() * poems.length)].title;
getPoemByTitle(randomPoemTitle).then(speechOutputData => {
if (speechOutputData.poemFound !== false) {
speechOutput = `This ${speechOutputData.poemLines}-line poem by ${
speechOutputData.poemAuthor
} is called ${speechOutputData.poemTitle}: ${
speechOutputData.poemBody
}`;
console.log('getRandomPoemByPoet resolve speechOutput: ', speechOutput)
resolve(speechOutput);
} else {
// todo: try a different poem from the list
}
});
} else {
// todo: log the request
speechOutput = `Sorry, I don't currently have any poems by ${poet}, but we'll make a note to check them out. Please try again later!`;
console.log('getRandomPoemByPoet resolve speechOutput: ', speechOutput)
resolve(speechOutput);
}
});
// Handle client errors
res.on('error', error => {
console.log('getRandomPoemByPoet http error, rejecting: ', error)
reject(error); // todo: do we want to resolve here instead?
});
});
});
};
/*
* getPoemByTitle
*
* @param {String} poemTitle Poem title to search in poetrydb api, does not require exact match
*/
const getPoemByTitle = poemTitle => {
return new Promise((resolve, reject) => {
let poemFound = false;
let poemAuthor = '';
let poemBody = '';
let poemLines = '';
const poemLinesPath =
'http://poetrydb.org/title/' + poemTitle.replace(/\s+/, '+');
http.get(poemLinesPath, res => {
let poemData = '';
res.on('data', d => {
poemData += d;
});
res.on('end', () => {
console.log('poemData: ', poemData)
const poemObj = JSON.parse(poemData);
if (poemObj.length > 0 && poemData) {
poemTitle = poemObj[0].title;
poemAuthor = poemObj[0].author;
poemBody = poemObj[0].lines.join();
poemLines = poemObj[0].linecount.toString();
poemFound = true;
}
const speechOutputData = {
poemFound: poemFound,
poemTitle: poemTitle,
poemAuthor: poemAuthor,
poemLines: poemLines,
poemBody: poemBody,
};
console.log('getPoemByTitle resolve speechOutputData: ', speechOutputData)
resolve(speechOutputData);
});
res.on('error', error => {
reject(error);
});
});
});
};