Newer
Older
const puppeteer = require("puppeteer");
const sleep = require("sleep-promise");
module.exports.createFreshPage = async function createFreshPage() {
const browser = await puppeteer.launch({
defaultViewport: {
width: 1200,
height: 600,
isLandscape: true,
},
});
const context = await browser.createIncognitoBrowserContext();
return context.newPage();
};
module.exports.joinRoom = async function joinRoom(
page,
roomUrl,
displayName = "Puppet"
) {
await page.goto(roomUrl);
console.log("joinRoom > Gone to start page for", roomUrl);
try {
// Set displayname for program
await page.type("input.join-form", displayName);
} catch (error) {
console.warn("Could not set displayname, probably signed in.");
try {
// Join and load room
await page.click("button#room-join");
} catch (error) {
try {
await page.click('input[value="Join"]');
} catch (error2) {
try {
await page.click('input[value="Start"]');
} catch (error3) {
try {
await page.click('input[value="Starten"]');
} catch (error4) {
await page.click('input[value="Teilnehmen"]');
}
}
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
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
const dismissButton = await page.waitForSelector(
'button[aria-describedBy="modalDismissDescription"]'
);
console.log("joinRoom > Joined room");
// Click audio choice panel away
await dismissButton.click();
console.log("joinRoom > clicked audio choice away.");
return page;
};
module.exports.sendChatMessage = async function sendChatMessage(
page,
messageText
) {
const chatInputHandle = await page.$("textarea#message-input");
const chatSendButtonHandle = await page.$(
'form > div > button[type="submit"]'
);
// Send a text message
await chatInputHandle.type(messageText);
await chatSendButtonHandle.click();
console.log("sendChatMessage > sent Message");
};
module.exports.signIn = async function signIn(
bbbUrl,
username,
password,
page = null
) {
// Create page if not done already
if (page === null) {
page = await createFreshPage();
}
await page.goto(bbbUrl);
await page.waitForSelector("a.sign-in-button");
const signInButton = await page.$("a.sign-in-button");
if (signInButton === null) {
console.log(
"SignIn > Can't find sign-in button: User is probably already authenticated."
);
return page;
}
await page.click("a.sign-in-button");
await page.waitForNavigation();
console.log("SignIn > NAVIGATED TO LOGIN PAGE");
await page.type("input#session_username", username);
await page.type("input#session_password", password);
await page.click("input.signin-button");
console.log("SignIn > entered credentials");
await page.waitForNavigation();
console.log("SignIn > Probably logged in.");
return page;
};
module.exports.screenShotPresentationArea = async function screenShotPresentationArea(
authenticatedPage,
path
) {
const presentationAreaHandle = await authenticatedPage.$("div#container");
presentationAreaHandle.screenshot({ path, type: "jpeg", quality: 33 });
};
module.exports.getUserCount = async function getUserCount(authenticatedPage) {
const selector = 'div[role="complementary"] > div > div > h2';
const h2Handle = (await authenticatedPage.$$(selector))[2];
return h2Handle.evaluate(
(node) => node.innerText.split("(")[1].split(")")[0]
);
};
module.exports.getUserList = async function getUserList(authenticatedPage) {
const users = [];
const selector = 'div[class*="userItemContents"]';
const userHandles = await authenticatedPage.$$(selector);
for (const userHandle of userHandles) {
const avatarHandle = await userHandle.$('div[class*="avatar"]');
const classes = (await avatarHandle.evaluate((node) => node.className))
.split(" ")
.map((wholeClass) => wholeClass.split("--")[0])
.filter((name) => name !== "avatar");
const userNameHandle = await userHandle.$(
'span[class*="userNameMain"] > span'
);
const userName = await userNameHandle.evaluate((node) => node.innerText);
users.push({
classes,
name: userName,
});
}
return users;
};
module.exports.getRoomName = async function getRoomName(authenticatedPage) {
const roomNameHandle = await authenticatedPage.$(
'h1[class*="presentationTitle"]'
);
if (roomNameHandle === null) {
process.send({ eventName: "sessionClosed", data: null });
await sleep(100);
process.exit(0);
}
return await roomNameHandle.evaluate((node) => node.innerText);
};
module.exports.createRoom = async function createRoom(
authenticatedPage,
roomSettings
) {
const pageUrl = await authenticatedPage.url();
const urlparts = pageUrl.split("/");
const url = urlparts[0] + "//" + urlparts[2];
const authenticityTokenHandle = await authenticatedPage.$(
'input[name="authenticity_token"]'
);
const authenticityToken = await authenticityTokenHandle.evaluate(
(node) => node.value
);
await authenticatedPage.evaluate(
async (url, authenticityToken, roomSettings) => {
function urlencodeFormData(fd) {
var s = "";
function encode(s) {
return encodeURIComponent(s).replace(/%20/g, "+");
}
for (var pair of fd.entries()) {
if (typeof pair[1] == "string") {
s += (s ? "&" : "") + encode(pair[0]) + "=" + encode(pair[1]);
}
}
return s;
}
// Prepare form data
const form = new FormData();
form.set("utf8", "✓");
form.set("authenticity_token", authenticityToken);
for (const key of Object.keys(roomSettings)) {
// Maybe fix this, because the POST format is weird
if (typeof roomSettings[key] === "boolean") {
form.append("room[" + key + "]", 0);
if (roomSettings[key]) {
form.append("room[" + key + "]", 1);
}
} else {
form.set("room[" + key + "]", roomSettings[key]);
}
}
form.set("room[auto_join]", "0");
form.set("commit", "Create+Room");
try {
// Send request to create room
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
redirect: "follow", // manual, *follow, error
body: urlencodeFormData(form),
});
return response;
} catch (error) {
return error;
}
},
url + "/b",
authenticityToken,
roomSettings
);
await authenticatedPage.goto(url);
};