diff --git a/src/grom.gleam b/src/grom.gleam index 83c2f1c..d97b592 100644 --- a/src/grom.gleam +++ b/src/grom.gleam @@ -421,8 +421,72 @@ pub type UserPrimaryGuild { ManuallyClearedUserPrimaryGuild } -// TODO: GET RID OF ME, ACTUALLY USE SKUs -pub type Sku +/// A SKU represents premium offerings that [applications](#Application) sell through Discord. +pub type Sku { + Sku( + id: Snowflake(Sku), + type_: SkuType, + /// The parent application's ID. + application_id: Snowflake(Application), + name: String, + /// The SKU's URL slug. + slug: String, + flags: List(SkuFlag), + ) +} + +fn sku_decoder() -> Decoder(Sku) { + use id <- decode.field("id", snowflake_decoder()) + use type_ <- decode.field("type", sku_type_decoder()) + use application_id <- decode.field("application_id", snowflake_decoder()) + use name <- decode.field("name", decode.string) + use slug <- decode.field("slug", decode.string) + use flags <- decode.field("flags", flags_decoder(bits_sku_flags())) + decode.success(Sku(id:, type_:, application_id:, name:, slug:, flags:)) +} + +pub type SkuType { + /// A durable one-time purchase + DurableSku + /// A consumable one-time-purchase + ConsumableSku + SubscriptionSku + /// An internal SKU used by Discord in their secret programs... for all intents + /// and purposes, Subscription Group SKUs don't exist. + SubscriptionGroupSku +} + +fn sku_type_decoder() -> Decoder(SkuType) { + use variant <- decode.then(decode.int) + case variant { + 2 -> decode.success(DurableSku) + 3 -> decode.success(ConsumableSku) + 5 -> decode.success(SubscriptionSku) + 6 -> decode.success(SubscriptionGroupSku) + _ -> decode.failure(DurableSku, "SkuType") + } +} + +pub type SkuFlag { + /// The SKU is available for purchase + SkuIsAvailable + /// The SKU is a subscription purchased by a user and applied to a single guild. + /// + /// Everyone in that server gets premium benefits. + SkuIsGuildSubscription + /// The SKU is a subscription purchased by a user and applied to themselves. + /// + /// They get premium benefits in all guilds. + SkuIsUserSubscription +} + +fn bits_sku_flags() -> List(#(Int, SkuFlag)) { + [ + #(int.bitwise_shift_left(1, 2), SkuIsAvailable), + #(int.bitwise_shift_left(1, 7), SkuIsGuildSubscription), + #(int.bitwise_shift_left(1, 8), SkuIsUserSubscription), + ] +} pub type UserAvatarDecoration { UserAvatarDecoration(hash: ImageHash, sku_id: Snowflake(Sku)) @@ -16153,3 +16217,20 @@ pub fn unpin_message_response( ) -> Result(Nil, RestError) { handle_no_content_response(response) } + +pub fn get_application_skus_request( + token token: Token, + application_with_id application_id: Snowflake(Application), +) -> Request(String) { + new_request( + token:, + to: "/applications/" <> snowflake_to_string(application_id) <> "/skus", + method: http.Get, + ) +} + +pub fn get_application_skus_response( + response: Response(String), +) -> Result(List(Sku), RestError) { + handle_response(response, decode_with: decode.list(sku_decoder())) +}