Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Discord] Add more badges (members/online/boosts) #9098

Closed
wants to merge 12 commits into from
76 changes: 76 additions & 0 deletions services/discord/discord-boosts.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import Joi from 'joi'
import { nonNegativeInteger } from '../validators.js'
import { BaseJsonService } from '../index.js'

const schema = Joi.object({
guild: {
premium_subscription_count: nonNegativeInteger,
},
}).required()

const documentation = `
<p>
The Discord badge requires the <code>SERVER INVITE CODE</code> in order access the Discord JSON API, this invite code should be set to never expire.
</p>
<p>
The <code>SERVER INVITE CODE</code> can be located at the end of the invite url.
</p>
`

export default class DiscordBoosts extends BaseJsonService {
static category = 'chat'

static route = {
base: 'discord/boosts',
pattern: ':inviteId',
}

static auth = {
passKey: 'discord_bot_token',
authorizedOrigins: ['https://discord.com'],
isRequired: false,
}

static examples = [
{
title: 'Discord',
namedParams: { inviteId: 'HjJCwm5' },
staticPreview: this.render({ boosts: 5 }),
documentation,
},
]

static _cacheLength = 300

static defaultBadgeData = { label: 'chat' }

static render({ boosts }) {
return {
message: `${boosts} boosts`,
color: 'brightgreen',
}
}

async fetch({ inviteId }) {
const url = `https://discord.com/api/v9/invites/${inviteId}?with_counts=true`
return this._requestJson(
this.authHelper.withBearerAuthHeader(
{
url,
schema,
errorMessages: {
404: 'invalid server invite',
},
},
'Bot'
)
)
}
Comment on lines +54 to +68
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like there's some commonality/duplication across the new classes especially in these fetch functions. Probably worth hoisting that out into a Discord base class or a common helper function IMO


async handle({ inviteId }) {
const data = await this.fetch({ inviteId })
return this.constructor.render({
boosts: data.guild.premium_subscription_count,
})
}
}
15 changes: 15 additions & 0 deletions services/discord/discord-boosts.tester.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Joi from 'joi'
import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()

t.create('gets boosts for Reactiflux')
.get('/reactiflux.json')
.expectBadge({
label: 'chat',
message: Joi.string().regex(/^[0-9]+ boosts$/),
color: 'brightgreen',
})

t.create('invalid server invite ID')
.get('/discord.json')
.expectBadge({ label: 'chat', message: 'invalid server invite' })
74 changes: 74 additions & 0 deletions services/discord/discord-members.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import Joi from 'joi'
import { nonNegativeInteger } from '../validators.js'
import { BaseJsonService } from '../index.js'

const schema = Joi.object({
approximate_member_count: nonNegativeInteger,
}).required()

const documentation = `
<p>
The Discord badge requires the <code>SERVER INVITE CODE</code> in order access the Discord JSON API, this invite code should be set to never expire.
</p>
<p>
The <code>SERVER INVITE CODE</code> can be located at the end of the invite url.
</p>
`

export default class DiscordMembers extends BaseJsonService {
static category = 'chat'

static route = {
base: 'discord/members',
pattern: ':inviteId',
}

static auth = {
passKey: 'discord_bot_token',
authorizedOrigins: ['https://discord.com'],
isRequired: false,
}

static examples = [
{
title: 'Discord',
namedParams: { inviteId: 'HjJCwm5' },
staticPreview: this.render({ members: 237 }),
documentation,
},
]

static _cacheLength = 300

static defaultBadgeData = { label: 'chat' }

static render({ members }) {
return {
message: `${members} members`,
color: 'brightgreen',
}
}

async fetch({ inviteId }) {
const url = `https://discord.com/api/v9/invites/${inviteId}?with_counts=true`
return this._requestJson(
this.authHelper.withBearerAuthHeader(
{
url,
schema,
errorMessages: {
404: 'invalid server invite',
},
},
'Bot'
)
)
}

async handle({ inviteId }) {
const data = await this.fetch({ inviteId })
return this.constructor.render({
members: data.approximate_member_count,
})
}
}
15 changes: 15 additions & 0 deletions services/discord/discord-members.tester.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Joi from 'joi'
import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()

t.create('gets members for Reactiflux')
.get('/reactiflux.json')
.expectBadge({
label: 'chat',
message: Joi.string().regex(/^[0-9]+ members$/),
color: 'brightgreen',
})

t.create('invalid server invite ID')
.get('/discord.json')
.expectBadge({ label: 'chat', message: 'invalid server invite' })
76 changes: 76 additions & 0 deletions services/discord/discord-online-with-total.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import Joi from 'joi'
import { nonNegativeInteger } from '../validators.js'
import { BaseJsonService } from '../index.js'

const schema = Joi.object({
approximate_presence_count: nonNegativeInteger,
approximate_member_count: nonNegativeInteger,
}).required()

const documentation = `
<p>
The Discord badge requires the <code>SERVER INVITE CODE</code> in order access the Discord JSON API, this invite code should be set to never expire.
</p>
<p>
The <code>SERVER INVITE CODE</code> can be located at the end of the invite url.
</p>
`

export default class DiscordOnlineWithTotalt extends BaseJsonService {
static category = 'chat'

static route = {
base: 'discord/online-with-total',
pattern: ':inviteId',
}

static auth = {
passKey: 'discord_bot_token',
authorizedOrigins: ['https://discord.com'],
isRequired: false,
}

static examples = [
{
title: 'Discord',
namedParams: { inviteId: 'HjJCwm5' },
staticPreview: this.render({ online: 97, members: 237 }),
documentation,
},
]

static _cacheLength = 300

static defaultBadgeData = { label: 'chat' }

static render({ online, members }) {
return {
message: `${online}/${members} online`,
color: 'brightgreen',
}
}

async fetch({ inviteId }) {
const url = `https://discord.com/api/v9/invites/${inviteId}?with_counts=true`
return this._requestJson(
this.authHelper.withBearerAuthHeader(
{
url,
schema,
errorMessages: {
404: 'invalid server invite',
},
},
'Bot'
)
)
}

async handle({ inviteId }) {
const data = await this.fetch({ inviteId })
return this.constructor.render({
online: data.approximate_presence_count,
members: data.approximate_member_count,
})
}
}
15 changes: 15 additions & 0 deletions services/discord/discord-online-with-total.tester.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Joi from 'joi'
import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()

t.create('gets online members for Reactiflux')
.get('/reactiflux.json')
.expectBadge({
label: 'chat',
message: Joi.string().regex(/^[0-9]+\/[0-9]+ online$/),
color: 'brightgreen',
})

t.create('invalid server invite ID')
.get('/discord.json')
.expectBadge({ label: 'chat', message: 'invalid server invite' })
74 changes: 74 additions & 0 deletions services/discord/discord-online.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import Joi from 'joi'
import { nonNegativeInteger } from '../validators.js'
import { BaseJsonService } from '../index.js'

const schema = Joi.object({
approximate_presence_count: nonNegativeInteger,
}).required()

const documentation = `
<p>
The Discord badge requires the <code>SERVER INVITE CODE</code> in order access the Discord JSON API, this invite code should be set to never expire.
</p>
<p>
The <code>SERVER INVITE CODE</code> can be located at the end of the invite url.
</p>
`

export default class DiscordOnline extends BaseJsonService {
static category = 'chat'

static route = {
base: 'discord/online',
pattern: ':inviteId',
}

static auth = {
passKey: 'discord_bot_token',
authorizedOrigins: ['https://discord.com'],
isRequired: false,
}

static examples = [
{
title: 'Discord',
namedParams: { inviteId: 'HjJCwm5' },
staticPreview: this.render({ online: 97 }),
documentation,
},
]

static _cacheLength = 300

static defaultBadgeData = { label: 'chat' }

static render({ online }) {
return {
message: `${online} online`,
color: 'brightgreen',
}
}

async fetch({ inviteId }) {
const url = `https://discord.com/api/v9/invites/${inviteId}?with_counts=true`
return this._requestJson(
this.authHelper.withBearerAuthHeader(
{
url,
schema,
errorMessages: {
404: 'invalid server invite',
},
},
'Bot'
)
)
}

async handle({ inviteId }) {
const data = await this.fetch({ inviteId })
return this.constructor.render({
online: data.approximate_presence_count,
})
}
}
15 changes: 15 additions & 0 deletions services/discord/discord-online.tester.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Joi from 'joi'
import { createServiceTester } from '../tester.js'
export const t = await createServiceTester()

t.create('gets online members for Reactiflux')
.get('/reactiflux.json')
.expectBadge({
label: 'chat',
message: Joi.string().regex(/^[0-9]+ online$/),
color: 'brightgreen',
})

t.create('invalid server invite ID')
.get('/discord.json')
.expectBadge({ label: 'chat', message: 'invalid server invite' })
2 changes: 1 addition & 1 deletion services/discord/discord.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export default class Discord extends BaseJsonService {
}

async fetch({ serverId }) {
const url = `https://discord.com/api/v6/guilds/${serverId}/widget.json`
const url = `https://discord.com/api/v9/guilds/${serverId}/widget.json`
return this._requestJson(
this.authHelper.withBearerAuthHeader(
{
Expand Down
4 changes: 2 additions & 2 deletions services/discord/discord.tester.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ t.create('widget disabled')
.get('/12345.json')
.intercept(nock =>
nock('https://discord.com/')
.get('/api/v6/guilds/12345/widget.json')
.get('/api/v9/guilds/12345/widget.json')
.reply(403, {
code: 50004,
message: 'Widget Disabled',
Expand All @@ -30,7 +30,7 @@ t.create('server error')
.get('/12345.json')
.intercept(nock =>
nock('https://discord.com/')
.get('/api/v6/guilds/12345/widget.json')
.get('/api/v9/guilds/12345/widget.json')
.reply(500, 'Something broke')
)
.expectBadge({ label: 'chat', message: 'inaccessible' })