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
Add support for server templates #876
Changes from 12 commits
248bbdc
2ca92e3
5bfdaf7
24b8ee6
d5cca9a
c1e9095
d16e10b
0a88de0
dc791f1
3804c7a
0ed5acc
4699395
8cb4dad
0096ff1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,214 @@ | ||
package discord4j.core.object; | ||
|
||
import discord4j.common.util.Snowflake; | ||
import discord4j.core.GatewayDiscordClient; | ||
import discord4j.core.object.entity.Guild; | ||
import discord4j.core.object.entity.User; | ||
import discord4j.core.spec.GuildTemplateEditSpec; | ||
import discord4j.core.spec.TemplateCreateGuildSpec; | ||
import discord4j.discordjson.json.SerializedSourceGuildData; | ||
import discord4j.discordjson.json.TemplateData; | ||
import reactor.core.publisher.Mono; | ||
|
||
import java.time.Instant; | ||
import java.time.format.DateTimeFormatter; | ||
import java.util.Objects; | ||
import java.util.Optional; | ||
import java.util.function.Consumer; | ||
|
||
public class Template implements DiscordObject { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing javadoc |
||
|
||
/** The gateway associated to this object. */ | ||
private final GatewayDiscordClient gateway; | ||
|
||
/** The raw data as represented by Discord. */ | ||
private final TemplateData data; | ||
|
||
/** The ID of the guild this template is associated to. */ | ||
private final long guildId; | ||
|
||
/** | ||
* Constructs a {@code Template} with an associated Discord client and data. | ||
* | ||
* @param gateway The {@link GatewayDiscordClient} associated to this object, must be non-null. | ||
* @param data The raw data as represented by Discord, must be non-null. | ||
*/ | ||
public Template(final GatewayDiscordClient gateway, final TemplateData data) { | ||
this.gateway = Objects.requireNonNull(gateway); | ||
this.data = Objects.requireNonNull(data); | ||
this.guildId = Snowflake.asLong(data.sourceGuildId()); | ||
} | ||
|
||
@Override | ||
public GatewayDiscordClient getClient() { | ||
return this.gateway; | ||
} | ||
|
||
/** | ||
* Returns this object underlying raw data structure. | ||
* | ||
* @return an immutable data representation of this object | ||
*/ | ||
public TemplateData getData() { | ||
return data; | ||
} | ||
|
||
/** | ||
* Returns the template code (unique ID). | ||
* | ||
* @return the template code (unique ID) | ||
*/ | ||
public final String getCode() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think these methods need to be final. Most of our entity classes are final, though. |
||
return data.code(); | ||
} | ||
|
||
/** | ||
* Returns the source guild ID. | ||
* | ||
* @return the guild id | ||
*/ | ||
public final Snowflake getGuildId() { | ||
return Snowflake.of(guildId); | ||
} | ||
|
||
/** | ||
* Returns the name of the template. | ||
* | ||
* @return The template name | ||
*/ | ||
public final String getName() { | ||
return data.name(); | ||
} | ||
|
||
/** | ||
* Returns the description of the template. | ||
* | ||
* @return the template description | ||
*/ | ||
public final Optional<String> getDescription() { | ||
return data.description(); | ||
} | ||
|
||
/** | ||
* Returns the amount of times the template has been used. | ||
* | ||
* @return the template usage count | ||
*/ | ||
public final int getUsageCount() { | ||
return data.usageCount(); | ||
} | ||
|
||
/** | ||
* Returns the id of the creator of this template. | ||
* | ||
* @return the creator id | ||
*/ | ||
public final Snowflake getCreatorId() { | ||
return Snowflake.of(data.creatorId()); | ||
} | ||
|
||
/** | ||
* Returns the creator of this template. | ||
* | ||
* @return the creator | ||
*/ | ||
public final User getCreator() { | ||
return new User(gateway, data.creator()); | ||
} | ||
|
||
/** | ||
* Returns an {@link Instant} when this template was created. | ||
* | ||
* @return a timestamp when template was last updated | ||
*/ | ||
public final Instant getCreatedAt() { | ||
return DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(data.createdAt(), Instant::from); | ||
} | ||
|
||
/** | ||
* Returns an {@link Instant} when this template was last updated. | ||
* | ||
* @return a timestamp when template was last updated | ||
*/ | ||
public final Instant getUpdatedAt() { | ||
return DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(data.updatedAt(), Instant::from); | ||
} | ||
|
||
/** | ||
* Gets the guild snapshot of the template. | ||
* | ||
* @return The guild snapshot. | ||
*/ | ||
public final SerializedSourceGuildData getSourceGuild() { | ||
return data.serializedSourceGuild(); | ||
} | ||
|
||
/** | ||
* Creates a new guild from a template. Fires Guild Create Gateway event. | ||
* | ||
* @return the guild object | ||
*/ | ||
public final Mono<Guild> createGuild(final Consumer<? super TemplateCreateGuildSpec> spec) { | ||
return Mono.defer( | ||
() -> { | ||
TemplateCreateGuildSpec mutatedSpec = new TemplateCreateGuildSpec(); | ||
spec.accept(mutatedSpec); | ||
return gateway.getRestClient().getTemplateService().createGuild(getCode(), | ||
mutatedSpec.asRequest(), mutatedSpec.getReason()); | ||
}) | ||
.map(data -> new Guild(gateway, data)); | ||
} | ||
|
||
/** | ||
* Requests to sync this template with the guild's current state. | ||
* | ||
* @return a {@link Mono} that, upon subscription, syncs a guild with this template. If an error is received, it | ||
* will be emitted through the Mono. | ||
*/ | ||
public final Mono<Template> sync() { | ||
return sync(guildId); | ||
} | ||
|
||
/** | ||
* Requests to sync this template with the given guild. | ||
* | ||
* @param guildId the guild to fetch current state for the template | ||
* @return a {@link Mono} that, upon subscription, syncs a guild with this template. If an error is received, it | ||
* will be emitted through the Mono. | ||
*/ | ||
public final Mono<Template> sync(long guildId) { | ||
return gateway.getRestClient().getTemplateService() | ||
.syncTemplate(guildId, getCode()) | ||
.map(data -> new Template(gateway, data)); | ||
} | ||
|
||
/** | ||
* Requests to edit this guild template. | ||
* | ||
* @param spec A {@link Consumer} that provides a "blank" {@link GuildTemplateEditSpec} to be operated on. | ||
* @return A {@link Mono} where, upon successful completion, emits the edited {@link Template}. If an error is | ||
* received, it is emitted through the {@code Mono}. | ||
*/ | ||
public final Mono<Template> edit(final Consumer<? super GuildTemplateEditSpec> spec) { | ||
return Mono.defer( | ||
() -> { | ||
GuildTemplateEditSpec mutatedSpec = new GuildTemplateEditSpec(); | ||
spec.accept(mutatedSpec); | ||
return gateway.getRestClient().getTemplateService().modifyTemplate(guildId, getCode(), | ||
mutatedSpec.asRequest(), mutatedSpec.getReason()); | ||
}) | ||
.map(data -> new Template(gateway, data)); | ||
} | ||
|
||
/** | ||
* Requests to delete this template while optionally specifying a reason. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a way to specify the reason? (does that even show up in Audit Log?) |
||
* | ||
* @return A {@link Mono} where, upon successful completion, emits the deleted template. If an error is received, | ||
* it is emitted through the {@code Mono}. | ||
*/ | ||
public final Mono<Template> delete(Snowflake guildId) { | ||
return gateway.getRestClient().getTemplateService() | ||
.deleteTemplate(guildId.asLong(), getCode()) | ||
.map(data -> new Template(gateway, data)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -18,10 +18,7 @@ | |||||
|
||||||
import discord4j.common.util.Snowflake; | ||||||
import discord4j.core.GatewayDiscordClient; | ||||||
import discord4j.core.object.Ban; | ||||||
import discord4j.core.object.ExtendedInvite; | ||||||
import discord4j.core.object.Region; | ||||||
import discord4j.core.object.VoiceState; | ||||||
import discord4j.core.object.*; | ||||||
import discord4j.core.object.audit.AuditLogEntry; | ||||||
import discord4j.core.object.entity.channel.*; | ||||||
import discord4j.core.object.presence.Presence; | ||||||
|
@@ -1010,6 +1007,24 @@ public Mono<GuildEmoji> createEmoji(final Consumer<? super GuildEmojiCreateSpec> | |||||
.map(data -> new GuildEmoji(gateway, data, getId().asLong())); | ||||||
} | ||||||
|
||||||
/** | ||||||
* Requests to create an template. A guild can only have a single template. | ||||||
* | ||||||
* @param spec A {@link Consumer} that provides a "blank" {@link GuildTemplateCreateSpec} to be operated on. | ||||||
* @return A {@link Mono} where, upon subscription, emits the created {@link Template} on success. If an error is | ||||||
* received, it is emitted through the {@code Mono}. | ||||||
*/ | ||||||
public Mono<Template> createTemplate(final Consumer<? super GuildTemplateCreateSpec> spec) { | ||||||
return Mono.defer( | ||||||
() -> { | ||||||
GuildTemplateCreateSpec mutatedSpec = new GuildTemplateCreateSpec(); | ||||||
spec.accept(mutatedSpec); | ||||||
return gateway.getRestClient().getTemplateService() | ||||||
.createTemplate(getId().asLong(), mutatedSpec.asRequest(), mutatedSpec.getReason()); | ||||||
}) | ||||||
.map(data -> new Template(gateway, data)); | ||||||
} | ||||||
|
||||||
/** | ||||||
* Requests to create a role. | ||||||
* | ||||||
|
@@ -1368,6 +1383,18 @@ public Flux<ExtendedInvite> getInvites() { | |||||
.map(data -> new ExtendedInvite(gateway, data)); | ||||||
} | ||||||
|
||||||
/** | ||||||
* Requests to retrieve the invites of the guild. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
* | ||||||
* @return A {@link Flux} that continually emits the {@link ExtendedInvite invites} of the guild. If an error is | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
* received, it is emitted through the {@code Flux}. | ||||||
*/ | ||||||
public Flux<Template> getTemplates() { | ||||||
return gateway.getRestClient().getTemplateService() | ||||||
.getTemplates(getId().asLong()) | ||||||
.map(data -> new Template(gateway, data)); | ||||||
} | ||||||
|
||||||
/** | ||||||
* Requests to change the bot user's nickname in this guild. | ||||||
* | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing license header