-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbackground_script.js
More file actions
188 lines (177 loc) · 7.11 KB
/
Copy pathbackground_script.js
File metadata and controls
188 lines (177 loc) · 7.11 KB
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
const disclaimers = [
"Since we do not have any information about the reviewer, we cannot be completely sure about their authenticity.",
"It is important to note that this is only one review and other reviews should also be considered for a more accurate assessment.",
"It is important to consider other reviews as well before making a final decision.",
"It should be taken with a grain of salt and considered alongside other reviews.",
"It is recommended to read other reviews as well to get a more accurate assessment."
];
function parsePlaceInfo(placeInfoStr) {
console.log(placeInfoStr);
const tokens = placeInfoStr.split('\n');
return {
name: tokens[0],
rating: tokens[1],
numReviews: tokens[2].split(' ')[0],
type: tokens[3]
};
}
function generatePrompt(reviewInfo) {
// retrieve info
const placeInfo = parsePlaceInfo(reviewInfo.place);
console.log(placeInfo);
return `${placeInfo.name} is a ${placeInfo.type}.
The overall rating of this place is ${placeInfo.rating} (lowest rating is 1 and highest rating is 5).
There are a total of ${placeInfo.numReviews} reviews for this place.
The following is a review for this place:
"${reviewInfo.text}"
The reviewer gave a rating of ${reviewInfo.rating} (lowest rating is 1 and highest rating is 5).
The review was written ${reviewInfo.time}. Note that the earlier the review was written, the less reliable the review is. Reviews written with the past 6 months are considered relevant.
Do you think the review is reliable?
Please return an answer between 0 to 10, where 0 stands for absolutely not reliable and 10 stands for absolutely reliable.
Your answer should include the number first and some explanation.
Your response should be in strict JSON format that includes the opening and closing curly brackets.
The first key is called "rate" and should include a single number, which is the number you provided out of 10; the second key is called "explanation", which should include your explanation.
Please DO NOT include any sentences that have the same meaning as the following:
"Since we do not have any information about the reviewer, we cannot be completely sure about their authenticity."
"It is important to note that this is only one review and other reviews should also be considered for a more accurate assessment."
"it is important to consider other reviews as well before making a final decision."
"it should be taken with a grain of salt and considered alongside other reviews."
"It is recommended to read other reviews as well to get a more accurate assessment."
`;
}
async function moderation(reviewText, OPENAI_API_KEY) {
const apiURL = "https://api.openai.com/v1/moderations";
const response = await fetch(apiURL, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${OPENAI_API_KEY}`
},
body: JSON.stringify({
input: reviewText
})
});
const data = await response.json();
if (data.results[0].flagged) {
let flaggedList = [];
const flagCategories = data.results[0].categories;
for (const cat in flagCategories) {
if (flagCategories[cat]) {
flaggedList.push(cat);
}
}
return { flagged: true, categories: flaggedList };
} else {
return { flagged: false };
}
}
async function compareDisclaimer(lastSentence, OPENAI_API_KEY) {
const systemContent = `You are a bot that checks if sentences have the same meaning. Only answer "Yes" or "No".`;
let userPrompt = `You are given the following sentence: "${lastSentence}". Is the above sentence the same meaning as any one of the following sentences?\n`;
for (const idx in disclaimers) {
userPrompt += `\t"${disclaimers[idx]}"\n`;
}
userPrompt += 'Please only answer "Yes" or "No" and nothing else.\n';
userPrompt += 'The sentence "the review appears to be genuine and reliable" does not have the same meaning as any of the sentences above.'
console.log(userPrompt);
const apiURL = "https://api.openai.com/v1/chat/completions";
const response = await fetch(apiURL, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${OPENAI_API_KEY}`
},
body: JSON.stringify({
model: "gpt-3.5-turbo",
messages: [
{role: "system", content: systemContent},
{role: "user", content: userPrompt}
],
temperature: 0.1
})
});
const data = await response.json();
const gptResponse = data.choices[0].message.content;
console.log(gptResponse);
return gptResponse;
}
async function analyzeReview(reviewInfo) {
if (reviewInfo.text === "") {
return {
success: true,
result: {
rate: 0,
explanation: "The reviewer didn't give any comments."
}
}
}
const systemContent = `You are a bot that checks for reliability of place reviews.
Check if the review is genuine and warn the users if the review is a spam.`;
const userPrompt = generatePrompt(reviewInfo);
try {
const apiKeyResponse = await fetch(chrome.runtime.getURL("API_key.json"));
const apiKeyData = await apiKeyResponse.json();
const OPENAI_API_KEY = apiKeyData.OPENAI;
const moderationResult = await moderation(
reviewInfo.text, OPENAI_API_KEY
);
if (moderationResult.flagged) {
let flagMsg = "The review is flagged for the following inappropriate elements:";
for (const cat in moderationResult.categories) {
flagMsg += " " + String(cat);
}
return {
success: true,
result: {
rate: 0,
explanation: flagMsg
}
};
}
const apiURL = "https://api.openai.com/v1/chat/completions";
const response = await fetch(apiURL, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${OPENAI_API_KEY}`
},
body: JSON.stringify({
model: "gpt-3.5-turbo",
messages: [
{role: "system", content: systemContent},
{role: "user", content: userPrompt}
],
temperature: 0.253
})
});
const data = await response.json();
const gptResponse = data.choices[0].message.content;
let gptResponseJSON = {};
try {
gptResponseJSON = JSON.parse(gptResponse);
} catch {
gptResponse = `{${gptResponse}}`;
gptResponseJSON = JSON.parse(gptResponse);
}
const sentences = gptResponseJSON.explanation.split(/(?<=\.|\?|!)\s/);
const lastSentence = sentences[sentences.length - 1];
const compareDisclaimerResult = await compareDisclaimer(
lastSentence, OPENAI_API_KEY
);
if (compareDisclaimerResult === "Yes.") {
sentences.pop();
gptResponseJSON.explanation = sentences.join(" ");
}
return { success: true, result: gptResponseJSON };
} catch (err) {
return { success: false, result: err };
}
}
const extensionApi = typeof browser !== 'undefined' ? browser : chrome;
extensionApi.runtime.onMessage.addListener((request, sender, sendResponse) => {
console.log('background');
if (request.action === 'analyze_review') {
analyzeReview(request).then(sendResponse);
return true;
}
});