Skip to content

Commit

Permalink
Merge pull request #165 from thesis/zoom-use-pro-accounts-first
Browse files Browse the repository at this point in the history
Zoom use pro accounts first

This filters availableSessions into separate arrays for accounts
of Basic vs Pro user type.

It uses Basic accounts only if no sessions are available with Pro
accounts. When a basic account is used, the Heimdall zoom link
reply includes messaging about the time limit.
  • Loading branch information
Shadowfiend authored Nov 14, 2019
2 parents 1e0a8b4 + 2270c12 commit b3e3143
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 34 deletions.
74 changes: 45 additions & 29 deletions lib/zoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ async function getSession(
if (userResponse.status != 200) {
throw `Error looking up users: ${util.inspect(userResponse.data)}.`
} else {
// NB: We currently do not have to handle pagination, because we have fewer
// users than the number of potential results per page (30).
// If our user count (user.data.total_records) grows to exceed that, we'll
// need to update this to handle pagination.
return new Session(
apiKey,
apiSecret,
Expand Down Expand Up @@ -87,46 +91,57 @@ class Session {
)

const accountMeetings = await Promise.all(
Array.from(this.users.map(u => u.email))
.map(email => this.accountForEmail(email))
.map(async function(accountSession): Promise<[Account, boolean]> {
let live = await accountSession.liveMeetings()
// filter out any upcoming or scheduled meetings starting within meetingLengthBuffer
let upcoming = await accountSession.upcomingMeetings()
let upcomingMeetingsInBuffer = upcoming.filter(meeting =>
meeting.start_time
? moment(meeting.start_time).isBetween(now, bufferExpiryTime)
: false,
)
let scheduled = await accountSession.scheduledMeetings()
let scheduledMeetingsInBuffer = scheduled.filter(meeting =>
meeting.start_time
? moment(meeting.start_time).isBetween(now, bufferExpiryTime)
: false,
)
return [
accountSession,
live.length == 0 &&
upcomingMeetingsInBuffer.length == 0 &&
scheduledMeetingsInBuffer.length == 0,
]
}),
Array.from(
this.users.map(u => this.accountFromUser(u.email, u.type)),
).map(async function(accountSession): Promise<[Account, boolean]> {
// filter out any upcoming or scheduled meetings starting within meetingLengthBuffer
let upcoming = await accountSession.upcomingMeetings()
let upcomingMeetingsInBuffer = upcoming.filter(meeting =>
meeting.start_time
? moment(meeting.start_time).isBetween(now, bufferExpiryTime)
: false,
)
let scheduled = await accountSession.scheduledMeetings()
let scheduledMeetingsInBuffer = scheduled.filter(meeting =>
meeting.start_time
? moment(meeting.start_time).isBetween(now, bufferExpiryTime)
: false,
)
let live = await accountSession.liveMeetings()
return [
accountSession,
live.length == 0 &&
upcomingMeetingsInBuffer.length == 0 &&
scheduledMeetingsInBuffer.length == 0,
]
}),
)

const availableSessions = accountMeetings
.filter(([, availableForMeeting]) => availableForMeeting)
.map(([session]) => session)
const chosenIndex = Math.floor(Math.random() * availableSessions.length)

return await availableSessions[chosenIndex].createMeeting()
const availableProSessions = availableSessions.filter(
session => session.type == UserType.Pro,
)
const availableBasicSessions = availableSessions.filter(
session => session.type != UserType.Pro,
)

const candidateSessions =
(availableProSessions.length > 0 && availableProSessions) ||
availableBasicSessions

const chosenIndex = Math.floor(Math.random() * candidateSessions.length)
return await candidateSessions[chosenIndex].createMeeting()
}

private get token() {
return tokenFrom(this.apiKey, this.apiSecret)
}

private accountForEmail(email: string) {
return new Account(email, this.apiKey, this.apiSecret)
private accountFromUser(email: string, type: number) {
return new Account(email, this.apiKey, this.apiSecret, type)
}
}

Expand Down Expand Up @@ -158,6 +173,7 @@ class Account {
private email: string,
private apiKey: string,
private apiSecret: string,
private type: UserType,
) {}

// NB: we may run into pagination issues at some point, especially for
Expand Down Expand Up @@ -207,7 +223,7 @@ class Account {
meeting: Meeting = response.data

meeting.app_url = URLs.appJoin.replace(/{meetingId}/, meeting.id)
return [meeting, this.email]
return [meeting, this.email, this.type]
}

private get token() {
Expand Down
13 changes: 8 additions & 5 deletions scripts/zoom.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,16 @@ module.exports = function(robot) {
return
}
ZOOM_SESSION.nextAvailableMeeting()
.then(([meeting, zoomUserEmail]) => {
.then(([meeting, zoomUserEmail, zoomUserType]) => {
robot.logger.info(
`Created meeting: ${meeting.id}: using account for ${zoomUserEmail}`,
)
res.send(
`All set; open in [the app](${meeting.app_url}) or [your browser](${meeting.join_url})!`,
`Created meeting: ${meeting.id}: using type ${zoomUserType} account for ${zoomUserEmail}`,
)
let replyMessage = `All set; open in [the app](${meeting.app_url}) or [your browser](${meeting.join_url})!`
if (zoomUserType == 1) {
replyMessage +=
"\n\nNote: this meeting has a limited duration of 40 minutes. All accounts with unlimited meetings are currently occupied. If you need a longer meeting, please try again later, or request a new meeting when this one ends."
}
res.send(replyMessage)
return meeting
})
.catch(err => {
Expand Down

0 comments on commit b3e3143

Please sign in to comment.