Resolves #153 This is a breaking change! With the introduction of Vanity URLs and the shortening of Invite URLs, the API appears to have removed the "xkcdpass" field of the Invite. Since this functionality was removed from the Discord API and thus obsolete, it has been removed from the Invite models.tags/1.0-rc
@@ -10,7 +10,5 @@ namespace Discord.API | |||||
public InviteGuild Guild { get; set; } | public InviteGuild Guild { get; set; } | ||||
[JsonProperty("channel")] | [JsonProperty("channel")] | ||||
public InviteChannel Channel { get; set; } | public InviteChannel Channel { get; set; } | ||||
[JsonProperty("xkcdpass")] | |||||
public string XkcdPass { get; set; } | |||||
} | } | ||||
} | } |
@@ -519,21 +519,21 @@ namespace Discord.API | |||||
} | } | ||||
//Guild Invites | //Guild Invites | ||||
public async Task<Invite> GetInviteAsync(string inviteIdOrXkcd, RequestOptions options = null) | |||||
public async Task<Invite> GetInviteAsync(string inviteId, RequestOptions options = null) | |||||
{ | { | ||||
Preconditions.NotNullOrEmpty(inviteIdOrXkcd, nameof(inviteIdOrXkcd)); | |||||
Preconditions.NotNullOrEmpty(inviteId, nameof(inviteId)); | |||||
//Remove trailing slash | //Remove trailing slash | ||||
if (inviteIdOrXkcd[inviteIdOrXkcd.Length - 1] == '/') | |||||
inviteIdOrXkcd = inviteIdOrXkcd.Substring(0, inviteIdOrXkcd.Length - 1); | |||||
if (inviteId[inviteId.Length - 1] == '/') | |||||
inviteId = inviteId.Substring(0, inviteId.Length - 1); | |||||
//Remove leading URL | //Remove leading URL | ||||
int index = inviteIdOrXkcd.LastIndexOf('/'); | |||||
int index = inviteId.LastIndexOf('/'); | |||||
if (index >= 0) | if (index >= 0) | ||||
inviteIdOrXkcd = inviteIdOrXkcd.Substring(index + 1); | |||||
inviteId = inviteId.Substring(index + 1); | |||||
try | try | ||||
{ | { | ||||
return await SendAsync<Invite>("GET", $"invites/{inviteIdOrXkcd}", options: options).ConfigureAwait(false); | |||||
return await SendAsync<Invite>("GET", $"invites/{inviteId}", options: options).ConfigureAwait(false); | |||||
} | } | ||||
catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { return null; } | catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { return null; } | ||||
} | } | ||||
@@ -16,9 +16,5 @@ namespace Discord.API.Rest | |||||
[JsonProperty("temporary")] | [JsonProperty("temporary")] | ||||
internal Optional<bool> _temporary { get; set; } | internal Optional<bool> _temporary { get; set; } | ||||
public bool Temporary { set { _temporary = value; } } | public bool Temporary { set { _temporary = value; } } | ||||
[JsonProperty("xkcdpass")] | |||||
internal Optional<bool> _xkcdPass { get; set; } | |||||
public bool XkcdPass { set { _xkcdPass = value; } } | |||||
} | } | ||||
} | } |
@@ -19,8 +19,7 @@ namespace Discord | |||||
/// <param name="maxAge"> The time (in seconds) until the invite expires. Set to null to never expire. </param> | /// <param name="maxAge"> The time (in seconds) until the invite expires. Set to null to never expire. </param> | ||||
/// <param name="maxUses"> The max amount of times this invite may be used. Set to null to have unlimited uses. </param> | /// <param name="maxUses"> The max amount of times this invite may be used. Set to null to have unlimited uses. </param> | ||||
/// <param name="isTemporary"> If true, a user accepting this invite will be kicked from the guild after closing their client. </param> | /// <param name="isTemporary"> If true, a user accepting this invite will be kicked from the guild after closing their client. </param> | ||||
/// <param name="withXkcd"> If true, creates a human-readable link. Not supported if maxAge is set to null. </param> | |||||
Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 1800, int? maxUses = default(int?), bool isTemporary = false, bool withXkcd = false); | |||||
Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 1800, int? maxUses = default(int?), bool isTemporary = false); | |||||
/// <summary> Returns a collection of all invites to this channel. </summary> | /// <summary> Returns a collection of all invites to this channel. </summary> | ||||
Task<IReadOnlyCollection<IInviteMetadata>> GetInvitesAsync(); | Task<IReadOnlyCollection<IInviteMetadata>> GetInvitesAsync(); | ||||
@@ -86,8 +86,7 @@ namespace Discord | |||||
/// <param name="maxAge"> The time (in seconds) until the invite expires. Set to null to never expire. </param> | /// <param name="maxAge"> The time (in seconds) until the invite expires. Set to null to never expire. </param> | ||||
/// <param name="maxUses"> The max amount of times this invite may be used. Set to null to have unlimited uses. </param> | /// <param name="maxUses"> The max amount of times this invite may be used. Set to null to have unlimited uses. </param> | ||||
/// <param name="isTemporary"> If true, a user accepting this invite will be kicked from the guild after closing their client. </param> | /// <param name="isTemporary"> If true, a user accepting this invite will be kicked from the guild after closing their client. </param> | ||||
/// <param name="withXkcd"> If true, creates a human-readable link. Not supported if maxAge is set to null. </param> | |||||
Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 1800, int? maxUses = default(int?), bool isTemporary = false, bool withXkcd = false); | |||||
Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 1800, int? maxUses = default(int?), bool isTemporary = false); | |||||
/// <summary> Gets the role in this guild with the provided id, or null if not found. </summary> | /// <summary> Gets the role in this guild with the provided id, or null if not found. </summary> | ||||
IRole GetRole(ulong id); | IRole GetRole(ulong id); | ||||
@@ -8,10 +8,6 @@ namespace Discord | |||||
string Code { get; } | string Code { get; } | ||||
/// <summary> Gets the url used to accept this invite, using Code. </summary> | /// <summary> Gets the url used to accept this invite, using Code. </summary> | ||||
string Url { get; } | string Url { get; } | ||||
/// <summary> Gets the human-readable identifier for this code. </summary> | |||||
string XkcdCode { get; } | |||||
/// <summary> Gets the url used to accept this invite, using XkcdCode. </summary> | |||||
string XkcdUrl { get; } | |||||
/// <summary> Gets the id of the the channel this invite is linked to. </summary> | /// <summary> Gets the id of the the channel this invite is linked to. </summary> | ||||
ulong ChannelId { get; } | ulong ChannelId { get; } | ||||
@@ -31,7 +31,7 @@ namespace Discord | |||||
Task<IReadOnlyCollection<IUserGuild>> GetGuildSummariesAsync(); | Task<IReadOnlyCollection<IUserGuild>> GetGuildSummariesAsync(); | ||||
Task<IGuild> CreateGuildAsync(string name, IVoiceRegion region, Stream jpegIcon = null); | Task<IGuild> CreateGuildAsync(string name, IVoiceRegion region, Stream jpegIcon = null); | ||||
Task<IInvite> GetInviteAsync(string inviteIdOrXkcd); | |||||
Task<IInvite> GetInviteAsync(string inviteId); | |||||
Task<IUser> GetUserAsync(ulong id); | Task<IUser> GetUserAsync(ulong id); | ||||
Task<IUser> GetUserAsync(string username, string discriminator); | Task<IUser> GetUserAsync(string username, string discriminator); | ||||
@@ -201,9 +201,9 @@ namespace Discord.Rest | |||||
} | } | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public virtual async Task<IInvite> GetInviteAsync(string inviteIdOrXkcd) | |||||
public virtual async Task<IInvite> GetInviteAsync(string inviteId) | |||||
{ | { | ||||
var model = await ApiClient.GetInviteAsync(inviteIdOrXkcd).ConfigureAwait(false); | |||||
var model = await ApiClient.GetInviteAsync(inviteId).ConfigureAwait(false); | |||||
if (model != null) | if (model != null) | ||||
return new Invite(this, model); | return new Invite(this, model); | ||||
return null; | return null; | ||||
@@ -76,14 +76,13 @@ namespace Discord | |||||
var models = await Discord.ApiClient.GetChannelInvitesAsync(Id).ConfigureAwait(false); | var models = await Discord.ApiClient.GetChannelInvitesAsync(Id).ConfigureAwait(false); | ||||
return models.Select(x => new InviteMetadata(Discord, x)).ToImmutableArray(); | return models.Select(x => new InviteMetadata(Discord, x)).ToImmutableArray(); | ||||
} | } | ||||
public async Task<IInviteMetadata> CreateInviteAsync(int? maxAge, int? maxUses, bool isTemporary, bool withXkcd) | |||||
public async Task<IInviteMetadata> CreateInviteAsync(int? maxAge, int? maxUses, bool isTemporary) | |||||
{ | { | ||||
var args = new CreateChannelInviteParams | var args = new CreateChannelInviteParams | ||||
{ | { | ||||
MaxAge = maxAge ?? 0, | MaxAge = maxAge ?? 0, | ||||
MaxUses = maxUses ?? 0, | MaxUses = maxUses ?? 0, | ||||
Temporary = isTemporary, | |||||
XkcdPass = withXkcd | |||||
Temporary = isTemporary | |||||
}; | }; | ||||
var model = await Discord.ApiClient.CreateChannelInviteAsync(Id, args).ConfigureAwait(false); | var model = await Discord.ApiClient.CreateChannelInviteAsync(Id, args).ConfigureAwait(false); | ||||
return new InviteMetadata(Discord, model); | return new InviteMetadata(Discord, model); | ||||
@@ -220,7 +220,7 @@ namespace Discord | |||||
var models = await Discord.ApiClient.GetGuildInvitesAsync(Id).ConfigureAwait(false); | var models = await Discord.ApiClient.GetGuildInvitesAsync(Id).ConfigureAwait(false); | ||||
return models.Select(x => new InviteMetadata(Discord, x)).ToImmutableArray(); | return models.Select(x => new InviteMetadata(Discord, x)).ToImmutableArray(); | ||||
} | } | ||||
public async Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 1800, int? maxUses = null, bool isTemporary = false, bool withXkcd = false) | |||||
public async Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 1800, int? maxUses = null, bool isTemporary = false) | |||||
{ | { | ||||
if (maxAge <= 0) throw new ArgumentOutOfRangeException(nameof(maxAge)); | if (maxAge <= 0) throw new ArgumentOutOfRangeException(nameof(maxAge)); | ||||
if (maxUses <= 0) throw new ArgumentOutOfRangeException(nameof(maxUses)); | if (maxUses <= 0) throw new ArgumentOutOfRangeException(nameof(maxUses)); | ||||
@@ -229,8 +229,7 @@ namespace Discord | |||||
{ | { | ||||
MaxAge = maxAge ?? 0, | MaxAge = maxAge ?? 0, | ||||
MaxUses = maxUses ?? 0, | MaxUses = maxUses ?? 0, | ||||
Temporary = isTemporary, | |||||
XkcdPass = withXkcd | |||||
Temporary = isTemporary | |||||
}; | }; | ||||
var model = await Discord.ApiClient.CreateChannelInviteAsync(DefaultChannelId, args).ConfigureAwait(false); | var model = await Discord.ApiClient.CreateChannelInviteAsync(DefaultChannelId, args).ConfigureAwait(false); | ||||
return new InviteMetadata(Discord, model); | return new InviteMetadata(Discord, model); | ||||
@@ -10,15 +10,13 @@ namespace Discord | |||||
{ | { | ||||
public string ChannelName { get; private set; } | public string ChannelName { get; private set; } | ||||
public string GuildName { get; private set; } | public string GuildName { get; private set; } | ||||
public string XkcdCode { get; private set; } | |||||
public ulong ChannelId { get; private set; } | public ulong ChannelId { get; private set; } | ||||
public ulong GuildId { get; private set; } | public ulong GuildId { get; private set; } | ||||
public override DiscordRestClient Discord { get; } | public override DiscordRestClient Discord { get; } | ||||
public string Code => Id; | public string Code => Id; | ||||
public string Url => $"{DiscordConfig.InviteUrl}/{XkcdCode ?? Code}"; | |||||
public string XkcdUrl => XkcdCode != null ? $"{DiscordConfig.InviteUrl}/{XkcdCode}" : null; | |||||
public string Url => $"{DiscordConfig.InviteUrl}/{Code}"; | |||||
public Invite(DiscordRestClient discord, Model model) | public Invite(DiscordRestClient discord, Model model) | ||||
: base(model.Code) | : base(model.Code) | ||||
@@ -31,7 +29,6 @@ namespace Discord | |||||
{ | { | ||||
if (source == UpdateSource.Rest && IsAttached) return; | if (source == UpdateSource.Rest && IsAttached) return; | ||||
XkcdCode = model.XkcdPass; | |||||
GuildId = model.Guild.Id; | GuildId = model.Guild.Id; | ||||
ChannelId = model.Channel.Id; | ChannelId = model.Channel.Id; | ||||
GuildName = model.Guild.Name; | GuildName = model.Guild.Name; | ||||
@@ -47,7 +44,7 @@ namespace Discord | |||||
await Discord.ApiClient.DeleteInviteAsync(Code).ConfigureAwait(false); | await Discord.ApiClient.DeleteInviteAsync(Code).ConfigureAwait(false); | ||||
} | } | ||||
public override string ToString() => XkcdUrl ?? Url; | |||||
private string DebuggerDisplay => $"{XkcdUrl ?? Url} ({GuildName} / {ChannelName})"; | |||||
public override string ToString() => Url; | |||||
private string DebuggerDisplay => $"{Url} ({GuildName} / {ChannelName})"; | |||||
} | } | ||||
} | } |