Add Twitch actions

* Send shoutout
* Cancel raid
* Enable/disable shield mode
* Enable/disable branded content
* Snooze next ad
This commit is contained in:
WarmUpTill 2026-03-18 21:07:45 +01:00
parent a94e1d2e90
commit 75f1edf20c
2 changed files with 113 additions and 0 deletions

View File

@ -1253,7 +1253,12 @@ AdvSceneSwitcher.action.twitch.type.channel.info.category.set="Set stream catego
AdvSceneSwitcher.action.twitch.type.channel.info.tags.set="Set stream tags"
AdvSceneSwitcher.action.twitch.type.channel.info.language.set="Set stream language"
AdvSceneSwitcher.action.twitch.type.raid.start="Start raid"
AdvSceneSwitcher.action.twitch.type.raid.end="Cancel raid"
AdvSceneSwitcher.action.twitch.type.shoutout.send="Send shoutout"
AdvSceneSwitcher.action.twitch.type.shieldMode.start="Enable shield mode"
AdvSceneSwitcher.action.twitch.type.shieldMode.end="Disable shield mode"
AdvSceneSwitcher.action.twitch.type.commercial.start="Start commercial"
AdvSceneSwitcher.action.twitch.type.commercial.snooze="Snooze next ad"
AdvSceneSwitcher.action.twitch.type.marker.create="Create stream marker"
AdvSceneSwitcher.action.twitch.type.clip.create="Create stream clip"
AdvSceneSwitcher.action.twitch.type.chat.announcement.send="Send chat announcement"
@ -1302,6 +1307,8 @@ AdvSceneSwitcher.action.twitch.tags.duplicate.info="This tag is already in the l
AdvSceneSwitcher.action.twitch.tags.limit="Tag Limit Reached"
AdvSceneSwitcher.action.twitch.tags.limit.info="You can only have up to %1 tags."
AdvSceneSwitcher.action.twitch.type.channel.info.contentClassification.set="Set content classification labels"
AdvSceneSwitcher.action.twitch.type.channel.info.brandedContent.enable="Enable branded content"
AdvSceneSwitcher.action.twitch.type.channel.info.brandedContent.disable="Disable branded content"
AdvSceneSwitcher.action.twitch.contentClassification.debatedSocialIssuesAndPolitics="Discussions or debates about politics or sensitive social issues such as elections, civic integrity, military conflict, and civil rights."
AdvSceneSwitcher.action.twitch.contentClassification.drugsIntoxication="Excessive tobacco glorification or promotion, any marijuana consumption/use, legal drug and alcohol induced intoxication, discussions of illegal drugs."
AdvSceneSwitcher.action.twitch.contentClassification.sexualThemes="Content that focuses on sexualized activities, sexual topics, or experiences."

View File

@ -64,10 +64,24 @@ const static std::map<MacroActionTwitch::Action, std::string> actionTypes = {
"AdvSceneSwitcher.action.twitch.type.channel.info.language.set"},
{MacroActionTwitch::Action::CHANNEL_INFO_CONTENT_LABELS_SET,
"AdvSceneSwitcher.action.twitch.type.channel.info.contentClassification.set"},
{MacroActionTwitch::Action::CHANNEL_INFO_BRANDED_CONTENT_ENABLE,
"AdvSceneSwitcher.action.twitch.type.channel.info.brandedContent.enable"},
{MacroActionTwitch::Action::CHANNEL_INFO_BRANDED_CONTENT_DISABLE,
"AdvSceneSwitcher.action.twitch.type.channel.info.brandedContent.disable"},
{MacroActionTwitch::Action::RAID_START,
"AdvSceneSwitcher.action.twitch.type.raid.start"},
{MacroActionTwitch::Action::RAID_END,
"AdvSceneSwitcher.action.twitch.type.raid.end"},
{MacroActionTwitch::Action::SHOUTOUT_SEND,
"AdvSceneSwitcher.action.twitch.type.shoutout.send"},
{MacroActionTwitch::Action::SHIELD_MODE_START,
"AdvSceneSwitcher.action.twitch.type.shieldMode.start"},
{MacroActionTwitch::Action::SHIELD_MODE_END,
"AdvSceneSwitcher.action.twitch.type.shieldMode.end"},
{MacroActionTwitch::Action::COMMERCIAL_START,
"AdvSceneSwitcher.action.twitch.type.commercial.start"},
{MacroActionTwitch::Action::COMMERCIAL_SNOOZE,
"AdvSceneSwitcher.action.twitch.type.commercial.snooze"},
{MacroActionTwitch::Action::MARKER_CREATE,
"AdvSceneSwitcher.action.twitch.type.marker.create"},
{MacroActionTwitch::Action::CLIP_CREATE,
@ -682,12 +696,104 @@ bool MacroActionTwitch::PerformAction()
case Action::CHANNEL_INFO_CONTENT_LABELS_SET:
_contentClassification.SetContentClassification(*token);
break;
case Action::CHANNEL_INFO_BRANDED_CONTENT_ENABLE:
case Action::CHANNEL_INFO_BRANDED_CONTENT_DISABLE: {
const auto id = token->GetUserID();
if (!id) {
vblog(LOG_INFO, "%s skip - invalid user id", __func__);
break;
}
OBSDataAutoRelease data = obs_data_create();
obs_data_set_bool(
data, "is_branded_content",
_action == Action::CHANNEL_INFO_BRANDED_CONTENT_ENABLE);
auto result = SendPatchRequest(*token, "https://api.twitch.tv",
"/helix/channels",
{{"broadcaster_id", *id}},
data.Get());
if (result.status != 204) {
blog(LOG_INFO,
"Failed to set branded content flag! (%d)",
result.status);
}
break;
}
case Action::RAID_START:
StartRaid(token);
break;
case Action::RAID_END: {
const auto id = token->GetUserID();
if (!id) {
vblog(LOG_INFO, "%s skip - invalid user id", __func__);
break;
}
auto result = SendDeleteRequest(*token, "https://api.twitch.tv",
"/helix/raids",
{{"broadcaster_id", *id}});
if (result.status != 204) {
blog(LOG_INFO, "Failed to cancel raid! (%d)",
result.status);
}
break;
}
case Action::SHOUTOUT_SEND: {
const auto id = token->GetUserID();
const auto toId = _channel.GetUserID(*token);
if (!id || toId.empty()) {
vblog(LOG_INFO, "%s skip - invalid user id", __func__);
break;
}
auto result = SendPostRequest(*token, "https://api.twitch.tv",
"/helix/chat/shoutouts",
{{"from_broadcaster_id", *id},
{"to_broadcaster_id", toId},
{"moderator_id", *id}});
if (result.status != 204) {
blog(LOG_INFO, "Failed to send shoutout! (%d)",
result.status);
}
break;
}
case Action::SHIELD_MODE_START:
case Action::SHIELD_MODE_END: {
const auto id = token->GetUserID();
if (!id) {
vblog(LOG_INFO, "%s skip - invalid user id", __func__);
break;
}
OBSDataAutoRelease data = obs_data_create();
obs_data_set_bool(data, "is_active",
_action == Action::SHIELD_MODE_START);
auto result = SendPutRequest(*token, "https://api.twitch.tv",
"/helix/moderation/shield_mode",
{{"broadcaster_id", *id},
{"moderator_id", *id}},
data.Get());
if (result.status != 200) {
blog(LOG_INFO, "Failed to set shield mode! (%d)",
result.status);
}
break;
}
case Action::COMMERCIAL_START:
StartCommercial(token);
break;
case Action::COMMERCIAL_SNOOZE: {
const auto id = token->GetUserID();
if (!id) {
vblog(LOG_INFO, "%s skip - invalid user id", __func__);
break;
}
auto result =
SendPostRequest(*token, "https://api.twitch.tv",
"/helix/channels/commercial/snooze",
{{"broadcaster_id", *id}});
if (result.status != 200) {
blog(LOG_INFO, "Failed to snooze commercial! (%d)",
result.status);
}
break;
}
case Action::MARKER_CREATE:
CreateStreamMarker(token);
break;