-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
133 lines (119 loc) · 4.08 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
const admin = require("firebase-admin");
const functions = require("firebase-functions");
const {DateTime} = require("luxon");
admin.initializeApp();
const db = admin.firestore();
/**
* Fetches all users from the "app_users" collection.
* @return {Promise<Array<{uid: string}>>} A promise that resolves
* to a list of user objects with uids.
*/
async function getAllUser() {
const snapshot = await db.collection("app_users").get();
return snapshot.docs.map((doc) => ({
uid: doc.data().uid.toString(),
}));
}
/**
* Fetches all user journals from the "user_journals" collection.
* @return {Promise<Array<{uid: string, rememberThisDayBy:
* string, moodToday: string, challenges: string}>>}
* A promise that resolves to a list of user journal objects.
*/
async function getUsersJournals() {
const snapshot = await db.collection("user_journals").get();
return snapshot.docs.map((doc) => ({
uid: doc.data().uid,
rememberThisDayBy: doc.data().rememberThisDayBy,
moodToday: doc.data().moodToday,
challenges: doc.data().challenges,
}));
}
/**
* Generates insights for each user based on their journals using OpenAI.
* @return {Promise<Array<{insight: string, uid: string}>>}
* A promise that resolves to a list of user insights objects.
*/
async function generateUserInsights() {
const users = await getAllUser();
const journals = await getUsersJournals();
const insightsList = [];
for (const singleUser of users) {
const userId = singleUser.uid;
const userJournals = journals.filter((journal) => journal.uid === userId);
if (userJournals.length > 0) {
const data = JSON.stringify(userJournals);
const response = await fetchInsightsFromOpenAI(data);
if (response) {
insightsList.push({
insight: response,
uid: userId,
});
}
}
}
return insightsList;
}
/**
* Fetches insights from the OpenAI API based on the provided journal entries.
*
* @param {string} journals - A JSON string of the user's journal entries.
* @return {Promise<string>} A promise that resolves to a string containing
* the insights.
*/
async function fetchInsightsFromOpenAI(journals) {
const key = ""; // TODO : Attach key here.
try {
const response = await fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${key}`,
},
body: JSON.stringify({
model: "gpt-3.5-turbo",
messages: [
{
role: "user",
content: `Respond as the second person (You), who was asked thes
three questions: [My mood today?, I'll remember this day by?
, Challenges I'm facing] on a daily basis, and his answers
were these: ${journals}. Based on these entries, give him three
insights about him. Respond with a single List<String>
containing a maximum of 3 strings in the following format:
['Insight 1', 'Insight 2', 'Insight 3']`,
},
],
max_tokens: 3000,
}),
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`HTTP ${response.status}: ${errorData.error.message}`);
}
const data = await response.json();
return data.choices[0].message.content;
} catch (error) {
console.error("Error fetching insights:", error);
throw error;
}
}
exports.addInsights = functions.https.onCall(async (data, context) => {
try {
const insightsList = await generateUserInsights();
const batch = db.batch();
insightsList.forEach((insight) => {
const ref = db.collection("users_insights").doc(insight.uid);
batch.set(ref, {
insights: insight.insight,
uid: insight.uid,
createdAt: DateTime.now().toMillis(),
});
});
await batch.commit();
return {message: "Insights added successfully."};
} catch (error) {
console.error("Error adding insights:", error);
throw new functions.https.HttpsError("internal", "Failed to add insights.");
}
});