pub mod request;
pub mod response;
pub mod types;
use request::{
ExtensionChatMessageIntoRequestBody, RequiredConfiguration, UpdateExtensoinBitsProductsRequest,
};
use response::{
ConfigurationSegmentResponse, ExtensionLiveChannelsRespnose, ExtensionSecretsResponse,
ExtensionsBitsProductsResponse, ExtensionsResponse,
};
use serde_json::json;
use types::Segment;
use crate::{
extensions::request::RequestConfigurationSegment,
request::{NoContent, RequestBody},
types::{
constants::{BITS, BROADCASTER_ID, CHAT, EXTENSIONS, EXTENSION_ID},
BroadcasterId, Cost, ExtensionId, JWTToken, PaginationQuery,
},
};
endpoints! {
ExtensionsAPI {
fn get_extension_configuration_segment(
&self,
jwt_token: JWTToken,
extension_id: &ExtensionId,
segment: &[Segment],
broadcaster_id: Option<&BroadcasterId>,
) -> ConfigurationSegmentResponse {
endpoint_type: GetExtensionConfigurationSegment,
method: GET,
path: [EXTENSIONS, "configurations"],
query_params: {
opt(BROADCASTER_ID, broadcaster_id),
query(EXTENSION_ID, extension_id),
extend(segment.iter().map(|s| ("segment", s)))
},
headers: [jwt, jwt_token]
}
fn set_extension_configuration_segment(
&self,
extension_id: &ExtensionId,
segment: Segment,
opts: Option<RequestConfigurationSegment>,
) -> NoContent {
endpoint_type: SetExtensionConfigurationSegment,
method: PUT,
path: [EXTENSIONS, "configurations"],
headers: [json],
body: {
let req = json!({
"extension_id": extension_id,
"segment": segment,
});
RequestBody::new(req, opts).into_json()
}
}
fn set_extension_required_configuration(
&self,
broadcaster_id: &BroadcasterId,
extension_id: &ExtensionId,
extension_version: &str,
required_configuration: &str,
) -> NoContent {
endpoint_type: SetExtensionRequiredConfiguration,
method: PUT,
path: [EXTENSIONS, "required_configuration"],
query_params: {
query(BROADCASTER_ID, broadcaster_id)
},
headers: [json],
body: RequiredConfiguration::new(extension_id, extension_version, required_configuration).into_json()
}
fn send_extension_pubsub_message(
&self,
target: &[&str],
message: &str,
broadcaster_id: &BroadcasterId,
is_global_broadcast: Option<bool>,
) -> NoContent {
endpoint_type: SendExtensionPubSubMessage,
method: POST,
path: [EXTENSIONS, "pubsub"],
headers: [json],
body: {
let required = if let Some(is_global) = is_global_broadcast {
serde_json::json!({
"target": target,
"message": message,
BROADCASTER_ID: broadcaster_id,
"is_global_broadcast": is_global
})
} else {
serde_json::json!({
"target": target,
"message": message,
BROADCASTER_ID: broadcaster_id,
})
};
RequestBody::new(required, None::<NoContent>).into_json()
}
}
fn get_extension_live_channels(
&self,
extension_id: &ExtensionId,
pagination: Option<PaginationQuery>,
) -> ExtensionLiveChannelsRespnose {
endpoint_type: GetExtensionLiveChannels,
method: GET,
path: [EXTENSIONS, "live"],
query_params: {
query(EXTENSION_ID, extension_id),
opt_into_query(pagination)
}
}
fn get_extension_secrets(
&self,
extension_id: &ExtensionId,
) -> ExtensionSecretsResponse {
endpoint_type: GetExtensionSecrets,
method: GET,
path: [EXTENSIONS, "jwt", "secrets"],
query_params: {
query(EXTENSION_ID, extension_id)
}
}
fn create_extension_secret(
&self,
extension_id: &ExtensionId,
delay: Option<u64>,
) -> ExtensionSecretsResponse {
endpoint_type: CreateExtensionSecret,
method: POST,
path: [EXTENSIONS, "jwt", "secrets"],
query_params: {
query("extension_id", extension_id),
opt("delay", delay.as_ref().map(|d| d.to_string()))
}
}
fn send_extension_chat_message(
&self,
broadcaster_id: &BroadcasterId,
text: &str,
extension_id: &ExtensionId,
extension_version: &str,
) -> NoContent {
endpoint_type: SendExtensionChatMessage,
method: POST,
path: [EXTENSIONS, CHAT],
query_params: {
query(BROADCASTER_ID, broadcaster_id)
},
headers: [json],
body: ExtensionChatMessageIntoRequestBody::new(text, extension_id, extension_version).into_json()
}
fn get_extensions(
&self,
extension_id: &ExtensionId,
extension_version: Option<&str>,
) -> ExtensionsResponse {
endpoint_type: GetExtensions,
method: GET,
path: [EXTENSIONS],
query_params: {
query(EXTENSION_ID, extension_id),
opt("extension_version", extension_version)
}
}
fn get_released_extensions(
&self,
extension_id: &ExtensionId,
extension_version: Option<&str>,
) -> ExtensionsResponse {
endpoint_type: GetReleasedExtensions,
method: GET,
path: [EXTENSIONS, "released"],
query_params: {
query(EXTENSION_ID, extension_id),
opt("extension_version", extension_version)
}
}
fn get_extension_bits_products(
&self,
should_inclue_all: Option<bool>,
) -> ExtensionsBitsProductsResponse {
endpoint_type: GetExtensionBitsProducts,
method: GET,
path: [BITS, EXTENSIONS],
query_params: {
opt("should_include_all", should_inclue_all.as_ref().map(|b| b.to_string()))
}
}
fn update_extension_bits_product(
&self,
sku: &str,
cost: Cost,
display_name: &str,
opts: Option<UpdateExtensoinBitsProductsRequest>,
) -> ExtensionsBitsProductsResponse {
endpoint_type: GetReleasedExtensions,
method: PUT,
path: [BITS, EXTENSIONS],
headers: [json],
body: {
let required = serde_json::json!({
"sku": sku,
"cost": cost,
"display_name": display_name,
});
RequestBody::new(required, opts).into_json()
}
}
}
}
#[cfg(test)]
mod tests {
use crate::{
extensions::{
request::{RequestConfigurationSegment, UpdateExtensoinBitsProductsRequest},
types::Segment,
ExtensionsAPI,
},
types::{BroadcasterId, Cost, CostType, ExtensionId, JWTToken},
};
api_test!(
get_extension_configuration_segment,
[
JWTToken::from("test_jwt_token"),
&ExtensionId::from("uo6dggojyb8d6soh92zknwmi5ej1q2"),
&[Segment::Global],
None,
]
);
api_test!(
set_extension_configuration_segment,
[
&ExtensionId::from("uo6dggojyb8d6soh92zknwmi5ej1q2"),
Segment::Global,
Some(
RequestConfigurationSegment::new()
.version("0.0.1")
.content("hello config!")
)
]
);
api_test!(
set_extension_required_configuration,
[
&BroadcasterId::from("274637212"),
&ExtensionId::from("uo6dggojyb8d6soh92zknwmi5ej1q2"),
"0.0.1",
"RCS",
]
);
api_test!(
send_extension_pubsub_message,
[
&["broadcast"],
"hello world!",
&BroadcasterId::from("141981764"),
None
]
);
api_test!(
get_extension_live_channels,
[&ExtensionId::from("uo6dggojyb8d6soh92zknwmi5ej1q2"), None]
);
api_test!(
get_extension_secrets,
[&ExtensionId::from("uo6dggojyb8d6soh92zknwmi5ej1q2")]
);
api_test!(
create_extension_secret,
[
&ExtensionId::from("uo6dggojyb8d6soh92zknwmi5ej1q2"),
Some(600)
]
);
api_test!(
send_extension_chat_message,
[
&BroadcasterId::from("237757755"),
"Hello",
&ExtensionId::from("uo6dggojyb8d6soh92zknwmi5ej1q2"),
"0.0.9",
]
);
api_test!(
get_extensions,
[
&ExtensionId::from("uo6dggojyb8d6soh92zknwmi5ej1q2"),
Some("0.0.9")
]
);
api_test!(
get_released_extensions,
[
&ExtensionId::from("uo6dggojyb8d6soh92zknwmi5ej1q2"),
Some("0.0.9")
]
);
api_test!(get_extension_bits_products, [Some(true)]);
api_test!(
update_extension_bits_product,
[
"1010",
Cost::new(990, CostType::Bits),
"Rusty Crate 2",
Some(
UpdateExtensoinBitsProductsRequest::new()
.in_development(true)
.is_broadcast(true)
.expiration("2021-05-18T09:10:13.397Z")
),
]
);
api_test!(extra
get_extension_configuration_segment,
get_extension_configuration_segment2,
[
JWTToken::from("test_jwt_token"),
&ExtensionId::from("uo6dggojyb8d6soh92zknwmi5ej1q2"),
&[Segment::Global],
None,
]
);
}