Skip to content

Commit 9a7b302

Browse files
authored
Allow modifying GuildOnboarding (#819)
The DSL looks like this: val onboarding = guild.editOnboarding { enabled = true mode = OnboardingMode.Advanced defaultChannelId(channelId1) defaultChannelId(channelId2) defaultChannelId(channelId3) defaultChannelId(channelId4) defaultChannelId(channelId5) defaultChannelId(channelId6) defaultChannelId(channelId7) prompt( OnboardingPromptType.MultipleChoice, title = "prompt title", singleSelect = false, required = false, inOnboarding = true, ) { option(title = "option 1 title") { channelIds += someChannelId description = "option 1 description" } option(title = "option 2 title") { roleIds += someRoleId } } } println(onboarding) See discord/discord-api-docs#6101
1 parent 2dad036 commit 9a7b302

File tree

15 files changed

+568
-11
lines changed

15 files changed

+568
-11
lines changed

common/api/common.api

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4121,18 +4121,20 @@ public final class dev/kord/common/entity/DiscordGuildMember$Companion {
41214121

41224122
public final class dev/kord/common/entity/DiscordGuildOnboarding {
41234123
public static final field Companion Ldev/kord/common/entity/DiscordGuildOnboarding$Companion;
4124-
public synthetic fun <init> (ILdev/kord/common/entity/Snowflake;Ljava/util/List;Ljava/util/List;ZLkotlinx/serialization/internal/SerializationConstructorMarker;)V
4125-
public fun <init> (Ldev/kord/common/entity/Snowflake;Ljava/util/List;Ljava/util/List;Z)V
4124+
public synthetic fun <init> (ILdev/kord/common/entity/Snowflake;Ljava/util/List;Ljava/util/List;ZLdev/kord/common/entity/OnboardingMode;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
4125+
public fun <init> (Ldev/kord/common/entity/Snowflake;Ljava/util/List;Ljava/util/List;ZLdev/kord/common/entity/OnboardingMode;)V
41264126
public final fun component1 ()Ldev/kord/common/entity/Snowflake;
41274127
public final fun component2 ()Ljava/util/List;
41284128
public final fun component3 ()Ljava/util/List;
41294129
public final fun component4 ()Z
4130-
public final fun copy (Ldev/kord/common/entity/Snowflake;Ljava/util/List;Ljava/util/List;Z)Ldev/kord/common/entity/DiscordGuildOnboarding;
4131-
public static synthetic fun copy$default (Ldev/kord/common/entity/DiscordGuildOnboarding;Ldev/kord/common/entity/Snowflake;Ljava/util/List;Ljava/util/List;ZILjava/lang/Object;)Ldev/kord/common/entity/DiscordGuildOnboarding;
4130+
public final fun component5 ()Ldev/kord/common/entity/OnboardingMode;
4131+
public final fun copy (Ldev/kord/common/entity/Snowflake;Ljava/util/List;Ljava/util/List;ZLdev/kord/common/entity/OnboardingMode;)Ldev/kord/common/entity/DiscordGuildOnboarding;
4132+
public static synthetic fun copy$default (Ldev/kord/common/entity/DiscordGuildOnboarding;Ldev/kord/common/entity/Snowflake;Ljava/util/List;Ljava/util/List;ZLdev/kord/common/entity/OnboardingMode;ILjava/lang/Object;)Ldev/kord/common/entity/DiscordGuildOnboarding;
41324133
public fun equals (Ljava/lang/Object;)Z
41334134
public final fun getDefaultChannelIds ()Ljava/util/List;
41344135
public final fun getEnabled ()Z
41354136
public final fun getGuildId ()Ldev/kord/common/entity/Snowflake;
4137+
public final fun getMode ()Ldev/kord/common/entity/OnboardingMode;
41364138
public final fun getPrompts ()Ljava/util/List;
41374139
public fun hashCode ()I
41384140
public fun toString ()Ljava/lang/String;
@@ -7894,6 +7896,32 @@ public final class dev/kord/common/entity/NsfwLevel$Unknown : dev/kord/common/en
78947896
public fun <init> (I)V
78957897
}
78967898

7899+
public abstract class dev/kord/common/entity/OnboardingMode {
7900+
public static final field Companion Ldev/kord/common/entity/OnboardingMode$Companion;
7901+
public synthetic fun <init> (ILkotlin/jvm/internal/DefaultConstructorMarker;)V
7902+
public final fun equals (Ljava/lang/Object;)Z
7903+
public final fun getValue ()I
7904+
public final fun hashCode ()I
7905+
public final fun toString ()Ljava/lang/String;
7906+
}
7907+
7908+
public final class dev/kord/common/entity/OnboardingMode$Advanced : dev/kord/common/entity/OnboardingMode {
7909+
public static final field INSTANCE Ldev/kord/common/entity/OnboardingMode$Advanced;
7910+
}
7911+
7912+
public final class dev/kord/common/entity/OnboardingMode$Companion {
7913+
public final fun from (I)Ldev/kord/common/entity/OnboardingMode;
7914+
public final fun getEntries ()Ljava/util/List;
7915+
public final fun serializer ()Lkotlinx/serialization/KSerializer;
7916+
}
7917+
7918+
public final class dev/kord/common/entity/OnboardingMode$Default : dev/kord/common/entity/OnboardingMode {
7919+
public static final field INSTANCE Ldev/kord/common/entity/OnboardingMode$Default;
7920+
}
7921+
7922+
public final class dev/kord/common/entity/OnboardingMode$Unknown : dev/kord/common/entity/OnboardingMode {
7923+
}
7924+
78977925
public abstract class dev/kord/common/entity/OnboardingPromptType {
78987926
public static final field Companion Ldev/kord/common/entity/OnboardingPromptType$Companion;
78997927
public synthetic fun <init> (ILkotlin/jvm/internal/DefaultConstructorMarker;)V
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// THIS FILE IS AUTO-GENERATED, DO NOT EDIT!
2+
@file:Suppress(names = arrayOf("IncorrectFormatting", "ReplaceArrayOfWithLiteral",
3+
"SpellCheckingInspection", "GrazieInspection"))
4+
5+
package dev.kord.common.entity
6+
7+
import kotlin.LazyThreadSafetyMode.PUBLICATION
8+
import kotlinx.serialization.KSerializer
9+
import kotlinx.serialization.Serializable
10+
import kotlinx.serialization.descriptors.PrimitiveKind
11+
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
12+
import kotlinx.serialization.descriptors.SerialDescriptor
13+
import kotlinx.serialization.encoding.Decoder
14+
import kotlinx.serialization.encoding.Encoder
15+
16+
/**
17+
* Defines the criteria used to satisfy Onboarding constraints that are required for enabling.
18+
*
19+
* See [OnboardingMode]s in the
20+
* [Discord Developer Documentation](https://discord.com/developers/docs/resources/guild#guild-onboarding-object-onboarding-mode).
21+
*/
22+
@Serializable(with = OnboardingMode.Serializer::class)
23+
public sealed class OnboardingMode(
24+
/**
25+
* The raw value used by Discord.
26+
*/
27+
public val `value`: Int,
28+
) {
29+
final override fun equals(other: Any?): Boolean = this === other ||
30+
(other is OnboardingMode && this.value == other.value)
31+
32+
final override fun hashCode(): Int = value.hashCode()
33+
34+
final override fun toString(): String =
35+
if (this is Unknown) "OnboardingMode.Unknown(value=$value)"
36+
else "OnboardingMode.${this::class.simpleName}"
37+
38+
/**
39+
* An unknown [OnboardingMode].
40+
*
41+
* This is used as a fallback for [OnboardingMode]s that haven't been added to Kord yet.
42+
*/
43+
public class Unknown internal constructor(
44+
`value`: Int,
45+
) : OnboardingMode(value)
46+
47+
/**
48+
* Counts only Default Channels towards constraints.
49+
*/
50+
public object Default : OnboardingMode(0)
51+
52+
/**
53+
* Counts Default Channels and Questions towards constraints.
54+
*/
55+
public object Advanced : OnboardingMode(1)
56+
57+
internal object Serializer : KSerializer<OnboardingMode> {
58+
override val descriptor: SerialDescriptor =
59+
PrimitiveSerialDescriptor("dev.kord.common.entity.OnboardingMode",
60+
PrimitiveKind.INT)
61+
62+
override fun serialize(encoder: Encoder, `value`: OnboardingMode) {
63+
encoder.encodeInt(value.value)
64+
}
65+
66+
override fun deserialize(decoder: Decoder): OnboardingMode = from(decoder.decodeInt())
67+
}
68+
69+
public companion object {
70+
/**
71+
* A [List] of all known [OnboardingMode]s.
72+
*/
73+
public val entries: List<OnboardingMode> by lazy(mode = PUBLICATION) {
74+
listOf(
75+
Default,
76+
Advanced,
77+
)
78+
}
79+
80+
81+
/**
82+
* Returns an instance of [OnboardingMode] with [OnboardingMode.value] equal to the
83+
* specified [value].
84+
*/
85+
public fun from(`value`: Int): OnboardingMode = when (value) {
86+
0 -> Default
87+
1 -> Advanced
88+
else -> Unknown(value)
89+
}
90+
}
91+
}

common/src/commonMain/kotlin/entity/DiscordGuildOnboarding.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
@file:Generate(
2+
INT_KORD_ENUM, name = "OnboardingMode", unknownConstructorWasPublic = false,
3+
kDoc = "Defines the criteria used to satisfy Onboarding constraints that are required for enabling.",
4+
docUrl = "https://discord.com/developers/docs/resources/guild#guild-onboarding-object-onboarding-mode",
5+
entries = [
6+
Entry("Default", intValue = 0, kDoc = "Counts only Default Channels towards constraints."),
7+
Entry("Advanced", intValue = 1, kDoc = "Counts Default Channels and Questions towards constraints."),
8+
],
9+
)
10+
111
@file:Generate(
212
INT_KORD_ENUM, name = "OnboardingPromptType",
313
docUrl = "https://discord.com/developers/docs/resources/guild#guild-onboarding-object-prompt-types",
@@ -21,6 +31,7 @@ public data class DiscordGuildOnboarding(
2131
val prompts: List<DiscordOnboardingPrompt>,
2232
@SerialName("default_channel_ids") val defaultChannelIds: List<Snowflake>,
2333
val enabled: Boolean,
34+
val mode: OnboardingMode,
2435
)
2536

2637
@Serializable

core/api/core.api

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ public final class dev/kord/core/behavior/GuildBehaviorKt {
421421
public static final fun createVoiceChannel (Ldev/kord/core/behavior/GuildBehavior;Ljava/lang/String;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
422422
public static synthetic fun createVoiceChannel$default (Ldev/kord/core/behavior/GuildBehavior;Ljava/lang/String;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
423423
public static final fun edit (Ldev/kord/core/behavior/GuildBehavior;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
424+
public static final fun editOnboarding (Ldev/kord/core/behavior/GuildBehavior;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
424425
public static final fun editWidget (Ldev/kord/core/behavior/GuildBehavior;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
425426
public static final fun getAuditLogEntries (Ldev/kord/core/behavior/GuildBehavior;Lkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/flow/Flow;
426427
public static synthetic fun getAuditLogEntries$default (Ldev/kord/core/behavior/GuildBehavior;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
@@ -6388,6 +6389,7 @@ public final class dev/kord/core/entity/GuildOnboarding : dev/kord/core/KordObje
63886389
public final fun getGuildId ()Ldev/kord/common/entity/Snowflake;
63896390
public final fun getGuildOrNull (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
63906391
public fun getKord ()Ldev/kord/core/Kord;
6392+
public final fun getMode ()Ldev/kord/common/entity/OnboardingMode;
63916393
public final fun getPrompts ()Ljava/util/List;
63926394
public fun getSupplier ()Ldev/kord/core/supplier/EntitySupplier;
63936395
public final fun isEnabled ()Z

core/src/commonMain/kotlin/behavior/GuildBehavior.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import dev.kord.common.annotation.KordExperimental
55
import dev.kord.common.entity.*
66
import dev.kord.common.entity.AutoModerationRuleEventType.MessageSend
77
import dev.kord.common.entity.Permission.ManageGuild
8+
import dev.kord.common.entity.Permission.ManageRoles
89
import dev.kord.common.entity.optional.Optional
910
import dev.kord.common.entity.optional.unwrap
1011
import dev.kord.common.exception.RequestException
@@ -968,6 +969,21 @@ public suspend inline fun GuildBehavior.editWidget(builder: GuildWidgetModifyBui
968969
return GuildWidget(GuildWidgetData.from(kord.rest.guild.modifyGuildWidget(id, builder)), id, kord)
969970
}
970971

972+
/**
973+
* Requests to edit the [GuildOnboarding] object of the guild and returns the edited onboarding object.
974+
*
975+
* This requires the [ManageGuild] and [ManageRoles] permissions.
976+
*
977+
* @throws RestRequestException if something went wrong during the request.
978+
*/
979+
public suspend inline fun GuildBehavior.editOnboarding(
980+
builder: GuildOnboardingModifyBuilder.() -> Unit,
981+
): GuildOnboarding {
982+
contract { callsInPlace(builder, EXACTLY_ONCE) }
983+
val onboarding = kord.rest.guild.modifyGuildOnboarding(guildId = id, builder)
984+
return GuildOnboarding(onboarding, kord)
985+
}
986+
971987
/**
972988
* The [Audit log entries][AuditLogEntry] from this guild, configured by the [builder].
973989
*

core/src/commonMain/kotlin/entity/GuildOnboarding.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ public class GuildOnboarding(
4545
/** Whether onboarding is enabled in the [guild]. */
4646
public val isEnabled: Boolean get() = data.enabled
4747

48+
/** Current [mode][OnboardingMode] of onboarding. */
49+
public val mode: OnboardingMode get() = data.mode
50+
4851
/**
4952
* Requests the [Guild] this onboarding is part of.
5053
*

ksp-annotations/src/commonMain/kotlin/Generate.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ annotation class Generate(
2929
val hadFlagsProperty: Boolean = false,
3030
val flagsPropertyWasSet: Boolean = false,
3131
val builderHadFlagsFunction: Boolean = false,
32+
val unknownConstructorWasPublic: Boolean = true,
3233
) {
3334
enum class EntityType { INT_KORD_ENUM, STRING_KORD_ENUM, INT_FLAGS, BIT_SET_FLAGS }
3435

ksp-processors/src/main/kotlin/generation/GenerationEntity.kt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ internal sealed class GenerationEntity(
2626
class KordEnum(
2727
name: String, kDoc: String?, docUrl: String, valueName: String, entries: List<Entry>,
2828
override val valueType: ValueType,
29+
val unknownConstructorWasPublic: Boolean,
2930
) : GenerationEntity(name, kDoc, docUrl, valueName, entries) {
3031
enum class ValueType : GenerationEntity.ValueType { INT, STRING }
3132
}
@@ -72,7 +73,7 @@ internal fun Generate.toGenerationEntityOrNull(logger: KSPLogger, annotation: KS
7273
Generate::wasEnum, Generate::collectionWasDataClass, Generate::hadFlagsProperty,
7374
Generate::flagsPropertyWasSet, Generate::builderHadFlagsFunction,
7475
)
75-
INT_FLAGS, BIT_SET_FLAGS -> true
76+
INT_FLAGS, BIT_SET_FLAGS -> areNotSpecified(Generate::unknownConstructorWasPublic)
7677
}
7778

7879
val mappedEntries = (entries zip args[Generate::entries]!!).mapNotNull { (entry, annotation) ->
@@ -84,8 +85,12 @@ internal fun Generate.toGenerationEntityOrNull(logger: KSPLogger, annotation: KS
8485
} else {
8586
val kDoc = kDoc.toKDoc()
8687
when (entityType) {
87-
INT_KORD_ENUM -> KordEnum(name, kDoc, docUrl, valueName, mappedEntries, KordEnum.ValueType.INT)
88-
STRING_KORD_ENUM -> KordEnum(name, kDoc, docUrl, valueName, mappedEntries, KordEnum.ValueType.STRING)
88+
INT_KORD_ENUM -> KordEnum(
89+
name, kDoc, docUrl, valueName, mappedEntries, KordEnum.ValueType.INT, unknownConstructorWasPublic,
90+
)
91+
STRING_KORD_ENUM -> KordEnum(
92+
name, kDoc, docUrl, valueName, mappedEntries, KordEnum.ValueType.STRING, unknownConstructorWasPublic,
93+
)
8994
INT_FLAGS -> BitFlags(
9095
name, kDoc, docUrl, valueName, mappedEntries, BitFlags.ValueType.INT, wasEnum, collectionWasDataClass,
9196
hadFlagsProperty, flagsPropertyWasSet, builderHadFlagsFunction,

ksp-processors/src/main/kotlin/generation/kordenum/KordEnumGeneration.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@ internal fun KordEnum.generateFileSpec(originatingFile: KSFile) = fileSpecForGen
3333
primaryConstructor {
3434
addModifiers(INTERNAL)
3535
addParameter(valueName, valueCN)
36-
addParameter("unused", type = NOTHING.copy(nullable = true)) {
36+
if (unknownConstructorWasPublic) addParameter("unused", type = NOTHING.copy(nullable = true)) {
3737
@OptIn(DelicateKotlinPoetApi::class)
3838
addAnnotation(Suppress("UNUSED_PARAMETER"))
3939
}
4040
}
4141
addSuperclassConstructorParameter(valueName)
4242
// TODO bump deprecation level and remove eventually (also share code with bit flags then)
43-
addConstructor {
43+
if (unknownConstructorWasPublic) addConstructor {
4444
@OptIn(DelicateKotlinPoetApi::class)
4545
addAnnotation(
4646
Deprecated(
@@ -69,7 +69,7 @@ internal fun KordEnum.generateFileSpec(originatingFile: KSFile) = fileSpecForGen
6969
for (entry in entriesDistinctByValue) {
7070
addStatement("$valueFormat·->·${entry.nameWithSuppressedDeprecation}", entry.value)
7171
}
72-
addStatement("else·->·Unknown($valueName,·null)")
72+
addStatement(if (unknownConstructorWasPublic) "else·->·Unknown($valueName,·null)" else "else·->·Unknown($valueName)")
7373
}
7474
}
7575
}

0 commit comments

Comments
 (0)