-
Notifications
You must be signed in to change notification settings - Fork 1
/
background.js
217 lines (205 loc) · 5.92 KB
/
background.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
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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
// gets the tab which is open
async function getCurrentTab() {
const tabs = await chrome.tabs.query({ active: true, currentWindow: true });
console.log(tabs[0]);
return tabs[0];
}
// gets the page content from a given tab
// injects and executes content_script.js programmatically
// this allows us to get page content w/o reload
async function getPageContent(tab) {
return new Promise((resolve, reject) => {
chrome.scripting.executeScript(
{ target: { tabId: tab.id }, files: ["content_script.js"] },
() => {
chrome.tabs.sendMessage(
tab.id,
{ action: "getPageContent" },
(response) => {
if (chrome.runtime.lastError) {
if (
chrome.runtime.lastError.message ===
"The message port closed before a response was received"
) {
reject("Page needs refresh");
} else {
reject(chrome.runtime.lastError.message);
}
} else if (response) {
resolve({
pageInfo: {
readable: response.readable,
rawText: response.content,
readabilityContent: response.readability,
},
tab: tab,
});
} else {
reject("No response received");
}
}
);
}
);
});
}
// this function gets the JWT from local storage
async function getJWT() {
return new Promise((resolve, reject) => {
chrome.storage.local.get(["access_token"], function (result) {
if (chrome.runtime.lastError) {
reject(chrome.runtime.lastError);
} else {
resolve(result.access_token);
}
});
});
}
// listens for messages from the app to get JWT
chrome.runtime.onMessageExternal.addListener(function (
request,
sender,
sendResponse
) {
if (request && request.action === "getJWT") {
const token = request.access_token;
chrome.storage.local.set({ access_token: token }).then(() => {
console.log("set access_token", token);
});
sendResponse({ status: "recieved" });
} else if (request && request.action === "getBookmarks") {
chrome.bookmarks.getTree((bookmarks) => {
sendResponse({ bookmarks: bookmarks });
});
}
});
// listens for messages from popup.js to get page content
chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
if (request.action === "getPageContent") {
const tab = await getCurrentTab();
savePage(tab).then((data) => {
chrome.runtime.sendMessage({ action: "response", data: data });
});
}
});
// listens for keyboard shortcut to save page
chrome.commands.onCommand.addListener(async (command) => {
console.log(`Command "${command}" triggered`);
const tab = await getCurrentTab();
console.log(tab);
const data = await savePage(tab);
console.log(data);
chrome.scripting.executeScript({
target: { tabId: tab.id },
func: showBanner,
args: [data],
});
});
// on install, create the context menu and open login page
chrome.runtime.onInstalled.addListener(() => {
chrome.contextMenus.create({
id: "save-to-nous",
title: "Save to Nous",
contexts: ["page"],
});
chrome.tabs.create({ url: "https://app.nous.fyi/?ext" });
// chrome.tabs.create({ url: 'http://localhost:3000/login' });
});
// listens for context menu click to save page
chrome.contextMenus.onClicked.addListener(async (info, tab) => {
if (info.menuItemId === "save-to-nous") {
const tab = await getCurrentTab();
const data = await savePage(tab);
chrome.scripting.executeScript({
target: { tabId: tab.id },
func: showBanner,
args: [data],
});
}
});
// Listen for new bookmarks being added
chrome.bookmarks.onCreated.addListener(async (id, bookmark) => {
console.log("New bookmark added:", bookmark);
const tab = await getCurrentTab();
const data = await savePage(tab);
chrome.scripting.executeScript({
target: { tabId: tab.id },
func: showBanner,
args: [data],
});
console.log("Page saved:", data);
});
// calls the save endpoint with the page data
async function savePage(tab) {
try {
// const tab = await getCurrentTab();
const { pageInfo } = await getPageContent(tab);
console.log(pageInfo);
const jwt = await getJWT();
const apiResponse = await fetch(
'https://api.nous.fyi/api/save',
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + jwt,
},
body: JSON.stringify({
pageData: {
favIconUrl: tab.favIconUrl,
url: tab.url,
title: tab.title,
content: pageInfo,
},
}),
}
);
if (apiResponse.status === 403) {
// Wait for 4 seconds
setTimeout(() => {
// Open the app with a specific query parameter
chrome.tabs.create(
{ url: "https://app.nous.fyi/?ext" },
);
}, 4000);
return { status: "token_expired", message: "Token expired" };
}
const data = await apiResponse.json();
console.log(data);
return data;
} catch (error) {
console.log(error);
return { status: "error", message: error };
}
}
// shows a banner on the page
function showBanner(data) {
const notyf = new Notyf({
duration: 3000,
position: {
x: "right",
y: "top",
},
ripple: true,
types: [
{
type: "success",
background: "#065B08",
},
{
type: "warning",
background: "#FF801F",
},
],
});
console.log(data.status);
if (data.status === "ok") {
notyf.success("saved to nous!");
} else if (data.status === "limit_reached") {
notyf.open({ type: "warning", message: "Limit Reached!" });
} else if (data.status === "token_expired") {
notyf.error("Token expired! Opening app...");
} else {
notyf.error("Refresh page!");
}
}