Skip to content

Commit

Permalink
feat: BillingManager (test)
Browse files Browse the repository at this point in the history
guild boost
  • Loading branch information
aiko-chan-ai committed Jan 5, 2023
1 parent e00e92f commit cada44a
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/client/Client.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const WebSocketManager = require('./websocket/WebSocketManager');
const { Error, TypeError, RangeError } = require('../errors');
const Discord = require('../index');
const BaseGuildEmojiManager = require('../managers/BaseGuildEmojiManager');
const BillingManager = require('../managers/BillingManager');
const ChannelManager = require('../managers/ChannelManager');
const ClientSettingManager = require('../managers/ClientSettingManager');
const DeveloperPortalManager = require('../managers/DeveloperPortalManager');
Expand Down Expand Up @@ -160,6 +161,12 @@ class Client extends BaseClient {
*/
this.guilds = new GuildManager(this);

/**
* Manages the API methods
* @type {BillingManager}
*/
this.billing = new BillingManager(this);

/**
* All of the sessions of the client
* @type {SessionManager}
Expand Down
66 changes: 66 additions & 0 deletions src/managers/BillingManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
'use strict';

const { Collection } = require('@discordjs/collection');
const BaseManager = require('./BaseManager');
const GuildBoost = require('../structures/GuildBoost');

/**
* Manages the API methods of a data model.
* @extends {CachedManager}
*/
class BillingManager extends BaseManager {
constructor(client) {
super(client);
/**
* All the payment sources of the client
* @type {Collection<Snowflake, Object>}
*/
this.paymentSources = new Collection();
/**
* All the guild boosts of the client
* @type {Collection<Snowflake, GuildBoost>}
*/
this.guildBoosts = new Collection();
/**
* The current subscription of the client
* @type {Collection<Snowflake, Object>}
*/
this.currentSubscription = new Collection();
}

/**
* Fetches all the payment sources of the client
* @returns {Collection<Snowflake, Object>}
*/
async fetchPaymentSources() {
// https://discord.com/api/v9/users/@me/billing/payment-sources
const d = await this.client.api.users('@me').billing['payment-sources'].get();
// ! TODO: Create a PaymentSource class
this.paymentSources = new Collection(d.map(s => [s.id, s]));
return this.paymentSources;
}

/**
* Fetches all the guild boosts of the client
* @returns {Collection<Snowflake, GuildBoost>}
*/
async fetchGuildBoosts() {
// https://discord.com/api/v9/users/@me/guilds/premium/subscription-slots
const d = await this.client.api.users('@me').guilds.premium['subscription-slots'].get();
this.guildBoosts = new Collection(d.map(s => [s.id, new GuildBoost(this.client, s)]));
return this.guildBoosts;
}

/**
* Fetches the current subscription of the client
* @returns {Collection<Snowflake, Object>}
*/
async fetchCurrentSubscription() {
// https://discord.com/api/v9/users/@me/billing/subscriptions
const d = await this.client.api.users('@me').billing.subscriptions.get();
this.currentSubscription = new Collection(d.map(s => [s.id, s]));
return this.currentSubscription;
}
}

module.exports = BillingManager;
108 changes: 108 additions & 0 deletions src/structures/GuildBoost.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
'use strict';

const Base = require('./Base');

/**
* Represents a guild boost in a guild on Discord.
* @extends {Base}
*/
class GuildBoost extends Base {
constructor(client, data) {
super(client);
this._patch(data);
}

_patch(data) {
if ('id' in data) {
/**
* The id of the guild boost
* @type {Snowflake}
*/
this.id = data.id;
}
if ('subscription_id' in data) {
/**
* The id of the subscription
* @type {Snowflake}
*/
this.subscriptionId = data.subscription_id;
}
if (typeof data.premium_guild_subscription === 'object') {
/**
* The premium guild subscription id
* @type {?Snowflake}
*/
this.premiumGuildSubscriptionId = data.premium_guild_subscription.id;
/**
* Guild id
* @type {?Snowflake}
*/
this.guildId = data.premium_guild_subscription.guild_id;
/**
* Ended ???
* @type {?boolean}
*/
this.ended = data.premium_guild_subscription.ended;
}
if ('canceled' in data) {
/**
* Whether the subscription is canceled
* @type {boolean}
*/
this.canceled = data.canceled;
}
if ('cooldown_ends_at' in data) {
/**
* The cooldown end date
* @type {Date}
*/
this.cooldownEndsAt = new Date(data.cooldown_ends_at);
}
}
/**
* The guild of the boost
* @type {?Guild}
* @readonly
*/
get guilld() {
return this.client.guilds.cache.get(this.guildId);
}

/**
* Cancel the boost
* @returns {Promise<GuildBoost>}
*/
async unsubscribe() {
// https://discord.com/api/v9/guilds/:id/premium/subscriptions/:id
if (!this.guildId) throw new Error('BOOST_UNUSED');
if (!this.premiumGuildSubscriptionId) throw new Error('BOOST_UNCACHED');
await this.client.api.guilds(this.guildId).premium.subscriptions(this.premiumGuildSubscriptionId).delete();
this.guildId = null;
this.premiumGuildSubscriptionId = null;
this.ended = null;
return this;
}

/**
* Use the boost
* @param {GuildResolvable} guild The guild to use the boost on
* @returns {Promise<GuildBoost>}
*/
async subscribe(guild) {
// https://discord.com/api/v9/guilds/:id/premium/subscriptions
if (this.guildId || this.premiumGuildSubscriptionId) throw new Error('BOOST_USED');
const id = this.client.guilds.resolveId(guild);
if (!id) throw new Error('UNKNOWN_GUILD');
const d = await this.client.api.guilds(id).premium.subscriptions.put({
data: {
user_premium_guild_subscription_slot_ids: [this.id],
},
});
this._patch({
premium_guild_subscription: d,
});
return this;
}
}

module.exports = GuildBoost;
26 changes: 26 additions & 0 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,30 @@ export class SessionManager extends CachedManager {
public logoutAllDevices(mfaCode?: string): Promise<undefined>;
}

export class BillingManager extends BaseManager {
constructor(client: Client);
public paymentSources: Collection<Snowflake, object>;
public fetchPaymentSources(): Promise<Collection<Snowflake, object>>;
public guildBoosts: Collection<Snowflake, GuildBoost>;
public fetchGuildBoosts(): Promise<Collection<Snowflake, GuildBoost>>;
public currentSubscription: Collection<Snowflake, object>;
public fetchCurrentSubscription(): Promise<Collection<Snowflake, object>>;
}

export class GuildBoost extends Base {
constructor(client: Client, data: object);
public id: Snowflake;
public guildId?: Snowflake;
public readonly guild: Guild | null;
public subscriptionId: Snowflake;
public premiumGuildSubscriptionId?: Snowflake;
public ended?: boolean;
public canceled: boolean;
public cooldownEndsAt: Date;
public unsubscribe(): Promise<this>;
public subscribe(guild: GuildResolvable): Promise<this>;
}

export class Session extends Base {
constructor(client: Client);
public id?: string;
Expand Down Expand Up @@ -858,6 +882,8 @@ export class Client<Ready extends boolean = boolean> extends BaseClient {
public relationships: RelationshipManager;
public readonly callVoice?: VoiceConnection;
public voiceStates: VoiceStateManager;
public sessions: SessionManager;
public billing: BillingManager;
// End
public channels: ChannelManager;
public readonly emojis: BaseGuildEmojiManager;
Expand Down

0 comments on commit cada44a

Please sign in to comment.