Skip to content

Commit

Permalink
feat(WebhookClient): allow creation of clients via URLs (#6192)
Browse files Browse the repository at this point in the history
  • Loading branch information
J-Human committed Jul 29, 2021
1 parent 42a0313 commit e000af5
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 6 deletions.
29 changes: 25 additions & 4 deletions src/client/WebhookClient.js
@@ -1,6 +1,7 @@
'use strict';

const BaseClient = require('./BaseClient');
const { Error } = require('../errors');
const Webhook = require('../structures/Webhook');

/**
Expand All @@ -10,17 +11,37 @@ const Webhook = require('../structures/Webhook');
*/
class WebhookClient extends BaseClient {
/**
* @param {Snowflake} id The webhook's id
* @param {string} token Token of the webhook
* The data for the webhook client containing either an id and token or just a URL
* @typedef {Object} WebhookClientData
* @property {Snowflake} [id] The id of the webhook
* @property {string} [token] The token of the webhook
* @property {string} [url] The full url for the webhook client
*/

/**
* @param {WebhookClientData} data The data of the webhook
* @param {ClientOptions} [options] Options for the client
* @example
* // Create a new webhook and send a message
* const hook = new Discord.WebhookClient('1234', 'abcdef');
* const hook = new Discord.WebhookClient({ id: '1234', token: 'abcdef' });
* hook.send('This will send a message').catch(console.error);
*/
constructor(id, token, options) {
constructor(data, options) {
super(options);
Object.defineProperty(this, 'client', { value: this });
let { id, token } = data;

if ('url' in data) {
const url = data.url.match(
// eslint-disable-next-line no-useless-escape
/^https?:\/\/(?:canary|ptb)?\.?discord\.com\/api\/webhooks(?:\/v[0-9]\d*)?\/([^\/]+)\/([^\/]+)/i,
);

if (!url || url.length <= 1) throw new Error('WEBHOOK_URL_INVALID');

[, id, token] = url;
}

this.id = id;
Object.defineProperty(this, 'token', { value: token, writable: true, configurable: true });
}
Expand Down
1 change: 1 addition & 0 deletions src/errors/Messages.js
Expand Up @@ -101,6 +101,7 @@ const Messages = {

WEBHOOK_MESSAGE: 'The message was not sent by a webhook.',
WEBHOOK_TOKEN_UNAVAILABLE: 'This action requires a webhook token, but none is available.',
WEBHOOK_URL_INVALID: 'The provided webhook URL is not valid.',
MESSAGE_REFERENCE_MISSING: 'The message does not reference another message',

EMOJI_TYPE: 'Emoji must be a string or GuildEmoji/ReactionEmoji',
Expand Down
2 changes: 1 addition & 1 deletion test/webhooktest.js
Expand Up @@ -97,7 +97,7 @@ client.on('messageCreate', async message => {
if (message.author.id !== owner) return;
const match = message.content.match(/^do (.+)$/);
const hooks = [
{ type: 'WebhookClient', hook: new WebhookClient(webhookChannel, webhookToken) },
{ type: 'WebhookClient', hook: new WebhookClient({ id: webhookChannel, token: webhookToken }) },
{ type: 'TextChannel#fetchWebhooks', hook: await message.channel.fetchWebhooks().then(x => x.first()) },
{ type: 'Guild#fetchWebhooks', hook: await message.guild.fetchWebhooks().then(x => x.first()) },
];
Expand Down
13 changes: 12 additions & 1 deletion typings/index.d.ts
Expand Up @@ -1900,7 +1900,7 @@ export class Webhook extends WebhookMixin() {
}

export class WebhookClient extends WebhookMixin(BaseClient) {
public constructor(id: Snowflake, token: string, options?: WebhookClientOptions);
public constructor(data: WebhookClientData, options?: WebhookClientOptions);
public client: this;
public options: WebhookClientOptions;
public token: string;
Expand Down Expand Up @@ -4350,6 +4350,17 @@ export type VerificationLevel = keyof typeof VerificationLevels;

export type VoiceBasedChannelTypes = 'GUILD_VOICE' | 'GUILD_STAGE_VOICE';

export type WebhookClientData = WebhookClientDataIdWithToken | WebhookClientDataURL;

export interface WebhookClientDataIdWithToken {
id: Snowflake;
token: string;
}

export interface WebhookClientDataURL {
url: string;
}

export type WebhookClientOptions = Pick<
ClientOptions,
'allowedMentions' | 'restTimeOffset' | 'restRequestTimeout' | 'retryLimit' | 'http'
Expand Down

0 comments on commit e000af5

Please sign in to comment.