feat(eventsub): implement (shared-chat-)ban (#5985)
This commit is contained in:
+1
-1
@@ -30,7 +30,7 @@
|
||||
- Bugfix: Fixed the input font not immediately updating when zooming in/out. (#5960)
|
||||
- Bugfix: Fixed color input thinking blue is also red. (#5982)
|
||||
- Dev: Subscriptions to PubSub channel points redemption topics now use no auth token, making it continue to work during PubSub shutdown. (#5947)
|
||||
- Dev: Add initial experimental EventSub support. (#5837, #5895, #5897, #5904, #5910, #5903, #5915, #5916, #5930, #5935, #5932, #5943, #5952, #5953, #5968, #5973, #5974, #5980, #5981)
|
||||
- Dev: Add initial experimental EventSub support. (#5837, #5895, #5897, #5904, #5910, #5903, #5915, #5916, #5930, #5935, #5932, #5943, #5952, #5953, #5968, #5973, #5974, #5980, #5981, #5985)
|
||||
- Dev: Remove unneeded platform specifier for toasts. (#5914)
|
||||
- Dev: Highlight checks now use non-capturing groups for the boundaries. (#5784)
|
||||
- Dev: Removed unused PubSub whisper code. (#5898)
|
||||
|
||||
@@ -55,12 +55,6 @@ def _is_trivially_copyable(type: clang.cindex.Type) -> bool:
|
||||
return _is_chrono_like_type(type)
|
||||
|
||||
|
||||
def _has_no_fields(type: clang.cindex.Type) -> bool:
|
||||
for _ in type.get_fields():
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
@dataclass
|
||||
class VariantType:
|
||||
name: str
|
||||
@@ -179,7 +173,7 @@ class Member:
|
||||
VariantType(
|
||||
name=name,
|
||||
trivial=_is_trivially_copyable(inner),
|
||||
empty=_has_no_fields(inner),
|
||||
empty=inner.get_size() <= 1,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List
|
||||
from typing import List, Optional
|
||||
|
||||
import logging
|
||||
|
||||
@@ -20,6 +20,7 @@ class Struct:
|
||||
self.comment_commands = CommentCommands()
|
||||
self.inner_root: str = ""
|
||||
self.namespace = namespace
|
||||
self.base: Optional[str] = None
|
||||
|
||||
@property
|
||||
def full_name(self) -> str:
|
||||
@@ -48,3 +49,8 @@ class Struct:
|
||||
|
||||
def apply_comment_commands(self, comment_commands: CommentCommands) -> None:
|
||||
self.inner_root = comment_commands.inner_root
|
||||
|
||||
def validate(self) -> None:
|
||||
assert not (self.base and self.members), (
|
||||
f"Unsupported: Struct {self.name} has both a base class as well as additional members"
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
boost::json::result_for<{{struct.full_name}}, boost::json::value>::type tag_invoke(
|
||||
boost::json::try_value_to_tag<{{struct.full_name}}> /* tag */, const boost::json::value &{%- if struct.members|length -%}jvRoot{%- else -%}/* jvRoot */{%- endif -%})
|
||||
boost::json::try_value_to_tag<{{struct.full_name}}> /* tag */, const boost::json::value &{%- if struct.members|length or struct.base -%}jvRoot{%- else -%}/* jvRoot */{%- endif -%})
|
||||
{
|
||||
{% if struct.inner_root %}
|
||||
if (!jvRoot.is_object())
|
||||
@@ -24,6 +24,12 @@ boost::json::result_for<{{struct.full_name}}, boost::json::value>::type tag_invo
|
||||
EVENTSUB_BAIL_HERE(error::Kind::ExpectedObject);
|
||||
}
|
||||
const auto &root = jvRoot.get_object();
|
||||
{% elif struct.base %}
|
||||
auto base = boost::json::try_value_to<{{struct.base}}>(jvRoot);
|
||||
if (base.has_error())
|
||||
{
|
||||
return base.error();
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
{% for field in struct.members %}
|
||||
@@ -56,6 +62,9 @@ boost::json::result_for<{{struct.full_name}}, boost::json::value>::type tag_invo
|
||||
{%- elif field.member_type == MemberType.VARIANT -%}
|
||||
{% include 'initializer-variant.tmpl' indent content %}
|
||||
{%- endif -%}
|
||||
{% endfor %}
|
||||
{% endfor -%}
|
||||
{%- if struct.base %}
|
||||
std::move(*base)
|
||||
{% endif -%}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ class Walker:
|
||||
for child in node.get_children():
|
||||
self.handle_node(child, new_struct, None)
|
||||
|
||||
new_struct.validate()
|
||||
self.structs.append(new_struct)
|
||||
|
||||
return True
|
||||
@@ -83,6 +84,11 @@ class Walker:
|
||||
self.namespace = self.namespace[:-1]
|
||||
return True
|
||||
|
||||
case CursorKind.CXX_BASE_SPECIFIER:
|
||||
assert struct
|
||||
struct.base = node.type.spelling
|
||||
return False
|
||||
|
||||
case CursorKind.FUNCTION_DECL:
|
||||
# Ignore function declarations
|
||||
pass
|
||||
|
||||
@@ -161,13 +161,11 @@ struct Unmod {
|
||||
|
||||
struct Ban {
|
||||
static constexpr std::string_view TAG = "ban";
|
||||
static constexpr std::string_view FIELD = "ban";
|
||||
|
||||
std::string userID;
|
||||
std::string userLogin;
|
||||
std::string userName;
|
||||
// TODO: Verify that we handle null here
|
||||
std::string reason;
|
||||
String userID;
|
||||
String userLogin;
|
||||
String userName;
|
||||
String reason;
|
||||
};
|
||||
struct SharedChatBan : public Ban {
|
||||
static constexpr std::string_view TAG = "shared_chat_ban";
|
||||
@@ -179,7 +177,6 @@ struct SharedChatBan : public Ban {
|
||||
|
||||
struct Unban {
|
||||
static constexpr std::string_view TAG = "unban";
|
||||
static constexpr std::string_view FIELD = "unban";
|
||||
|
||||
std::string userID;
|
||||
std::string userLogin;
|
||||
@@ -199,7 +196,6 @@ struct SharedChatUnban : public Ban {
|
||||
|
||||
struct Timeout {
|
||||
static constexpr std::string_view TAG = "timeout";
|
||||
static constexpr std::string_view FIELD = "timeout";
|
||||
|
||||
std::string userID;
|
||||
std::string userLogin;
|
||||
@@ -219,7 +215,6 @@ struct SharedChatTimeout : public Ban {
|
||||
|
||||
struct Untimeout {
|
||||
static constexpr std::string_view TAG = "untimeout";
|
||||
static constexpr std::string_view FIELD = "untimeout";
|
||||
|
||||
std::string userID;
|
||||
std::string userLogin;
|
||||
@@ -261,7 +256,6 @@ struct Unraid {
|
||||
|
||||
struct Delete {
|
||||
static constexpr std::string_view TAG = "delete";
|
||||
static constexpr std::string_view FIELD = "delete";
|
||||
|
||||
std::string userID;
|
||||
std::string userLogin;
|
||||
|
||||
@@ -325,7 +325,7 @@ boost::json::result_for<Ban, boost::json::value>::type tag_invoke(
|
||||
EVENTSUB_BAIL_HERE(error::Kind::FieldMissing);
|
||||
}
|
||||
|
||||
auto userID = boost::json::try_value_to<std::string>(*jvuserID);
|
||||
auto userID = boost::json::try_value_to<String>(*jvuserID);
|
||||
|
||||
if (userID.has_error())
|
||||
{
|
||||
@@ -338,7 +338,7 @@ boost::json::result_for<Ban, boost::json::value>::type tag_invoke(
|
||||
EVENTSUB_BAIL_HERE(error::Kind::FieldMissing);
|
||||
}
|
||||
|
||||
auto userLogin = boost::json::try_value_to<std::string>(*jvuserLogin);
|
||||
auto userLogin = boost::json::try_value_to<String>(*jvuserLogin);
|
||||
|
||||
if (userLogin.has_error())
|
||||
{
|
||||
@@ -351,7 +351,7 @@ boost::json::result_for<Ban, boost::json::value>::type tag_invoke(
|
||||
EVENTSUB_BAIL_HERE(error::Kind::FieldMissing);
|
||||
}
|
||||
|
||||
auto userName = boost::json::try_value_to<std::string>(*jvuserName);
|
||||
auto userName = boost::json::try_value_to<String>(*jvuserName);
|
||||
|
||||
if (userName.has_error())
|
||||
{
|
||||
@@ -364,7 +364,7 @@ boost::json::result_for<Ban, boost::json::value>::type tag_invoke(
|
||||
EVENTSUB_BAIL_HERE(error::Kind::FieldMissing);
|
||||
}
|
||||
|
||||
auto reason = boost::json::try_value_to<std::string>(*jvreason);
|
||||
auto reason = boost::json::try_value_to<String>(*jvreason);
|
||||
|
||||
if (reason.has_error())
|
||||
{
|
||||
@@ -381,9 +381,15 @@ boost::json::result_for<Ban, boost::json::value>::type tag_invoke(
|
||||
|
||||
boost::json::result_for<SharedChatBan, boost::json::value>::type tag_invoke(
|
||||
boost::json::try_value_to_tag<SharedChatBan> /* tag */,
|
||||
const boost::json::value & /* jvRoot */)
|
||||
const boost::json::value &jvRoot)
|
||||
{
|
||||
return SharedChatBan{};
|
||||
auto base = boost::json::try_value_to<Ban>(jvRoot);
|
||||
if (base.has_error())
|
||||
{
|
||||
return base.error();
|
||||
}
|
||||
|
||||
return SharedChatBan{std::move(*base)};
|
||||
}
|
||||
|
||||
boost::json::result_for<Unban, boost::json::value>::type tag_invoke(
|
||||
@@ -444,9 +450,15 @@ boost::json::result_for<Unban, boost::json::value>::type tag_invoke(
|
||||
|
||||
boost::json::result_for<SharedChatUnban, boost::json::value>::type tag_invoke(
|
||||
boost::json::try_value_to_tag<SharedChatUnban> /* tag */,
|
||||
const boost::json::value & /* jvRoot */)
|
||||
const boost::json::value &jvRoot)
|
||||
{
|
||||
return SharedChatUnban{};
|
||||
auto base = boost::json::try_value_to<Ban>(jvRoot);
|
||||
if (base.has_error())
|
||||
{
|
||||
return base.error();
|
||||
}
|
||||
|
||||
return SharedChatUnban{std::move(*base)};
|
||||
}
|
||||
|
||||
boost::json::result_for<Timeout, boost::json::value>::type tag_invoke(
|
||||
@@ -535,9 +547,15 @@ boost::json::result_for<Timeout, boost::json::value>::type tag_invoke(
|
||||
|
||||
boost::json::result_for<SharedChatTimeout, boost::json::value>::type tag_invoke(
|
||||
boost::json::try_value_to_tag<SharedChatTimeout> /* tag */,
|
||||
const boost::json::value & /* jvRoot */)
|
||||
const boost::json::value &jvRoot)
|
||||
{
|
||||
return SharedChatTimeout{};
|
||||
auto base = boost::json::try_value_to<Ban>(jvRoot);
|
||||
if (base.has_error())
|
||||
{
|
||||
return base.error();
|
||||
}
|
||||
|
||||
return SharedChatTimeout{std::move(*base)};
|
||||
}
|
||||
|
||||
boost::json::result_for<Untimeout, boost::json::value>::type tag_invoke(
|
||||
@@ -598,9 +616,15 @@ boost::json::result_for<Untimeout, boost::json::value>::type tag_invoke(
|
||||
|
||||
boost::json::result_for<SharedChatUntimeout, boost::json::value>::type
|
||||
tag_invoke(boost::json::try_value_to_tag<SharedChatUntimeout> /* tag */,
|
||||
const boost::json::value & /* jvRoot */)
|
||||
const boost::json::value &jvRoot)
|
||||
{
|
||||
return SharedChatUntimeout{};
|
||||
auto base = boost::json::try_value_to<Ban>(jvRoot);
|
||||
if (base.has_error())
|
||||
{
|
||||
return base.error();
|
||||
}
|
||||
|
||||
return SharedChatUntimeout{std::move(*base)};
|
||||
}
|
||||
|
||||
boost::json::result_for<Raid, boost::json::value>::type tag_invoke(
|
||||
@@ -817,9 +841,15 @@ boost::json::result_for<Delete, boost::json::value>::type tag_invoke(
|
||||
|
||||
boost::json::result_for<SharedChatDelete, boost::json::value>::type tag_invoke(
|
||||
boost::json::try_value_to_tag<SharedChatDelete> /* tag */,
|
||||
const boost::json::value & /* jvRoot */)
|
||||
const boost::json::value &jvRoot)
|
||||
{
|
||||
return SharedChatDelete{};
|
||||
auto base = boost::json::try_value_to<Ban>(jvRoot);
|
||||
if (base.has_error())
|
||||
{
|
||||
return base.error();
|
||||
}
|
||||
|
||||
return SharedChatDelete{std::move(*base)};
|
||||
}
|
||||
|
||||
boost::json::result_for<AutomodTerms, boost::json::value>::type tag_invoke(
|
||||
@@ -898,30 +928,54 @@ boost::json::result_for<AutomodTerms, boost::json::value>::type tag_invoke(
|
||||
|
||||
boost::json::result_for<AddBlockedTerm, boost::json::value>::type tag_invoke(
|
||||
boost::json::try_value_to_tag<AddBlockedTerm> /* tag */,
|
||||
const boost::json::value & /* jvRoot */)
|
||||
const boost::json::value &jvRoot)
|
||||
{
|
||||
return AddBlockedTerm{};
|
||||
auto base = boost::json::try_value_to<AutomodTerms>(jvRoot);
|
||||
if (base.has_error())
|
||||
{
|
||||
return base.error();
|
||||
}
|
||||
|
||||
return AddBlockedTerm{std::move(*base)};
|
||||
}
|
||||
|
||||
boost::json::result_for<AddPermittedTerm, boost::json::value>::type tag_invoke(
|
||||
boost::json::try_value_to_tag<AddPermittedTerm> /* tag */,
|
||||
const boost::json::value & /* jvRoot */)
|
||||
const boost::json::value &jvRoot)
|
||||
{
|
||||
return AddPermittedTerm{};
|
||||
auto base = boost::json::try_value_to<AutomodTerms>(jvRoot);
|
||||
if (base.has_error())
|
||||
{
|
||||
return base.error();
|
||||
}
|
||||
|
||||
return AddPermittedTerm{std::move(*base)};
|
||||
}
|
||||
|
||||
boost::json::result_for<RemoveBlockedTerm, boost::json::value>::type tag_invoke(
|
||||
boost::json::try_value_to_tag<RemoveBlockedTerm> /* tag */,
|
||||
const boost::json::value & /* jvRoot */)
|
||||
const boost::json::value &jvRoot)
|
||||
{
|
||||
return RemoveBlockedTerm{};
|
||||
auto base = boost::json::try_value_to<AutomodTerms>(jvRoot);
|
||||
if (base.has_error())
|
||||
{
|
||||
return base.error();
|
||||
}
|
||||
|
||||
return RemoveBlockedTerm{std::move(*base)};
|
||||
}
|
||||
|
||||
boost::json::result_for<RemovePermittedTerm, boost::json::value>::type
|
||||
tag_invoke(boost::json::try_value_to_tag<RemovePermittedTerm> /* tag */,
|
||||
const boost::json::value & /* jvRoot */)
|
||||
const boost::json::value &jvRoot)
|
||||
{
|
||||
return RemovePermittedTerm{};
|
||||
auto base = boost::json::try_value_to<AutomodTerms>(jvRoot);
|
||||
if (base.has_error())
|
||||
{
|
||||
return base.error();
|
||||
}
|
||||
|
||||
return RemovePermittedTerm{std::move(*base)};
|
||||
}
|
||||
|
||||
boost::json::result_for<UnbanRequest, boost::json::value>::type tag_invoke(
|
||||
@@ -1013,16 +1067,28 @@ boost::json::result_for<UnbanRequest, boost::json::value>::type tag_invoke(
|
||||
|
||||
boost::json::result_for<ApproveUnbanRequest, boost::json::value>::type
|
||||
tag_invoke(boost::json::try_value_to_tag<ApproveUnbanRequest> /* tag */,
|
||||
const boost::json::value & /* jvRoot */)
|
||||
const boost::json::value &jvRoot)
|
||||
{
|
||||
return ApproveUnbanRequest{};
|
||||
auto base = boost::json::try_value_to<UnbanRequest>(jvRoot);
|
||||
if (base.has_error())
|
||||
{
|
||||
return base.error();
|
||||
}
|
||||
|
||||
return ApproveUnbanRequest{std::move(*base)};
|
||||
}
|
||||
|
||||
boost::json::result_for<DenyUnbanRequest, boost::json::value>::type tag_invoke(
|
||||
boost::json::try_value_to_tag<DenyUnbanRequest> /* tag */,
|
||||
const boost::json::value & /* jvRoot */)
|
||||
const boost::json::value &jvRoot)
|
||||
{
|
||||
return DenyUnbanRequest{};
|
||||
auto base = boost::json::try_value_to<UnbanRequest>(jvRoot);
|
||||
if (base.has_error())
|
||||
{
|
||||
return base.error();
|
||||
}
|
||||
|
||||
return DenyUnbanRequest{std::move(*base)};
|
||||
}
|
||||
|
||||
boost::json::result_for<Warn, boost::json::value>::type tag_invoke(
|
||||
@@ -1519,19 +1585,70 @@ boost::json::result_for<Event, boost::json::value>::type tag_invoke(
|
||||
}
|
||||
else if (actionTag == AddBlockedTerm::TAG)
|
||||
{
|
||||
action.emplace<AddBlockedTerm>();
|
||||
const auto *actionVal =
|
||||
root.if_contains(detail::fieldFor<AddBlockedTerm>());
|
||||
if (!actionVal)
|
||||
{
|
||||
EVENTSUB_BAIL_HERE(error::Kind::FieldMissing);
|
||||
}
|
||||
auto actionAddBlockedTerm =
|
||||
boost::json::try_value_to<AddBlockedTerm>(*actionVal);
|
||||
if (actionAddBlockedTerm.has_error())
|
||||
{
|
||||
return actionAddBlockedTerm.error();
|
||||
}
|
||||
action.emplace<AddBlockedTerm>(std::move(actionAddBlockedTerm.value()));
|
||||
}
|
||||
else if (actionTag == AddPermittedTerm::TAG)
|
||||
{
|
||||
action.emplace<AddPermittedTerm>();
|
||||
const auto *actionVal =
|
||||
root.if_contains(detail::fieldFor<AddPermittedTerm>());
|
||||
if (!actionVal)
|
||||
{
|
||||
EVENTSUB_BAIL_HERE(error::Kind::FieldMissing);
|
||||
}
|
||||
auto actionAddPermittedTerm =
|
||||
boost::json::try_value_to<AddPermittedTerm>(*actionVal);
|
||||
if (actionAddPermittedTerm.has_error())
|
||||
{
|
||||
return actionAddPermittedTerm.error();
|
||||
}
|
||||
action.emplace<AddPermittedTerm>(
|
||||
std::move(actionAddPermittedTerm.value()));
|
||||
}
|
||||
else if (actionTag == RemoveBlockedTerm::TAG)
|
||||
{
|
||||
action.emplace<RemoveBlockedTerm>();
|
||||
const auto *actionVal =
|
||||
root.if_contains(detail::fieldFor<RemoveBlockedTerm>());
|
||||
if (!actionVal)
|
||||
{
|
||||
EVENTSUB_BAIL_HERE(error::Kind::FieldMissing);
|
||||
}
|
||||
auto actionRemoveBlockedTerm =
|
||||
boost::json::try_value_to<RemoveBlockedTerm>(*actionVal);
|
||||
if (actionRemoveBlockedTerm.has_error())
|
||||
{
|
||||
return actionRemoveBlockedTerm.error();
|
||||
}
|
||||
action.emplace<RemoveBlockedTerm>(
|
||||
std::move(actionRemoveBlockedTerm.value()));
|
||||
}
|
||||
else if (actionTag == RemovePermittedTerm::TAG)
|
||||
{
|
||||
action.emplace<RemovePermittedTerm>();
|
||||
const auto *actionVal =
|
||||
root.if_contains(detail::fieldFor<RemovePermittedTerm>());
|
||||
if (!actionVal)
|
||||
{
|
||||
EVENTSUB_BAIL_HERE(error::Kind::FieldMissing);
|
||||
}
|
||||
auto actionRemovePermittedTerm =
|
||||
boost::json::try_value_to<RemovePermittedTerm>(*actionVal);
|
||||
if (actionRemovePermittedTerm.has_error())
|
||||
{
|
||||
return actionRemovePermittedTerm.error();
|
||||
}
|
||||
action.emplace<RemovePermittedTerm>(
|
||||
std::move(actionRemovePermittedTerm.value()));
|
||||
}
|
||||
else if (actionTag == Mod::TAG)
|
||||
{
|
||||
@@ -1563,11 +1680,37 @@ boost::json::result_for<Event, boost::json::value>::type tag_invoke(
|
||||
}
|
||||
else if (actionTag == ApproveUnbanRequest::TAG)
|
||||
{
|
||||
action.emplace<ApproveUnbanRequest>();
|
||||
const auto *actionVal =
|
||||
root.if_contains(detail::fieldFor<ApproveUnbanRequest>());
|
||||
if (!actionVal)
|
||||
{
|
||||
EVENTSUB_BAIL_HERE(error::Kind::FieldMissing);
|
||||
}
|
||||
auto actionApproveUnbanRequest =
|
||||
boost::json::try_value_to<ApproveUnbanRequest>(*actionVal);
|
||||
if (actionApproveUnbanRequest.has_error())
|
||||
{
|
||||
return actionApproveUnbanRequest.error();
|
||||
}
|
||||
action.emplace<ApproveUnbanRequest>(
|
||||
std::move(actionApproveUnbanRequest.value()));
|
||||
}
|
||||
else if (actionTag == DenyUnbanRequest::TAG)
|
||||
{
|
||||
action.emplace<DenyUnbanRequest>();
|
||||
const auto *actionVal =
|
||||
root.if_contains(detail::fieldFor<DenyUnbanRequest>());
|
||||
if (!actionVal)
|
||||
{
|
||||
EVENTSUB_BAIL_HERE(error::Kind::FieldMissing);
|
||||
}
|
||||
auto actionDenyUnbanRequest =
|
||||
boost::json::try_value_to<DenyUnbanRequest>(*actionVal);
|
||||
if (actionDenyUnbanRequest.has_error())
|
||||
{
|
||||
return actionDenyUnbanRequest.error();
|
||||
}
|
||||
action.emplace<DenyUnbanRequest>(
|
||||
std::move(actionDenyUnbanRequest.value()));
|
||||
}
|
||||
else if (actionTag == Warn::TAG)
|
||||
{
|
||||
@@ -1585,23 +1728,87 @@ boost::json::result_for<Event, boost::json::value>::type tag_invoke(
|
||||
}
|
||||
else if (actionTag == SharedChatBan::TAG)
|
||||
{
|
||||
action.emplace<SharedChatBan>();
|
||||
const auto *actionVal =
|
||||
root.if_contains(detail::fieldFor<SharedChatBan>());
|
||||
if (!actionVal)
|
||||
{
|
||||
EVENTSUB_BAIL_HERE(error::Kind::FieldMissing);
|
||||
}
|
||||
auto actionSharedChatBan =
|
||||
boost::json::try_value_to<SharedChatBan>(*actionVal);
|
||||
if (actionSharedChatBan.has_error())
|
||||
{
|
||||
return actionSharedChatBan.error();
|
||||
}
|
||||
action.emplace<SharedChatBan>(std::move(actionSharedChatBan.value()));
|
||||
}
|
||||
else if (actionTag == SharedChatTimeout::TAG)
|
||||
{
|
||||
action.emplace<SharedChatTimeout>();
|
||||
const auto *actionVal =
|
||||
root.if_contains(detail::fieldFor<SharedChatTimeout>());
|
||||
if (!actionVal)
|
||||
{
|
||||
EVENTSUB_BAIL_HERE(error::Kind::FieldMissing);
|
||||
}
|
||||
auto actionSharedChatTimeout =
|
||||
boost::json::try_value_to<SharedChatTimeout>(*actionVal);
|
||||
if (actionSharedChatTimeout.has_error())
|
||||
{
|
||||
return actionSharedChatTimeout.error();
|
||||
}
|
||||
action.emplace<SharedChatTimeout>(
|
||||
std::move(actionSharedChatTimeout.value()));
|
||||
}
|
||||
else if (actionTag == SharedChatUnban::TAG)
|
||||
{
|
||||
action.emplace<SharedChatUnban>();
|
||||
const auto *actionVal =
|
||||
root.if_contains(detail::fieldFor<SharedChatUnban>());
|
||||
if (!actionVal)
|
||||
{
|
||||
EVENTSUB_BAIL_HERE(error::Kind::FieldMissing);
|
||||
}
|
||||
auto actionSharedChatUnban =
|
||||
boost::json::try_value_to<SharedChatUnban>(*actionVal);
|
||||
if (actionSharedChatUnban.has_error())
|
||||
{
|
||||
return actionSharedChatUnban.error();
|
||||
}
|
||||
action.emplace<SharedChatUnban>(
|
||||
std::move(actionSharedChatUnban.value()));
|
||||
}
|
||||
else if (actionTag == SharedChatUntimeout::TAG)
|
||||
{
|
||||
action.emplace<SharedChatUntimeout>();
|
||||
const auto *actionVal =
|
||||
root.if_contains(detail::fieldFor<SharedChatUntimeout>());
|
||||
if (!actionVal)
|
||||
{
|
||||
EVENTSUB_BAIL_HERE(error::Kind::FieldMissing);
|
||||
}
|
||||
auto actionSharedChatUntimeout =
|
||||
boost::json::try_value_to<SharedChatUntimeout>(*actionVal);
|
||||
if (actionSharedChatUntimeout.has_error())
|
||||
{
|
||||
return actionSharedChatUntimeout.error();
|
||||
}
|
||||
action.emplace<SharedChatUntimeout>(
|
||||
std::move(actionSharedChatUntimeout.value()));
|
||||
}
|
||||
else if (actionTag == SharedChatDelete::TAG)
|
||||
{
|
||||
action.emplace<SharedChatDelete>();
|
||||
const auto *actionVal =
|
||||
root.if_contains(detail::fieldFor<SharedChatDelete>());
|
||||
if (!actionVal)
|
||||
{
|
||||
EVENTSUB_BAIL_HERE(error::Kind::FieldMissing);
|
||||
}
|
||||
auto actionSharedChatDelete =
|
||||
boost::json::try_value_to<SharedChatDelete>(*actionVal);
|
||||
if (actionSharedChatDelete.has_error())
|
||||
{
|
||||
return actionSharedChatDelete.error();
|
||||
}
|
||||
action.emplace<SharedChatDelete>(
|
||||
std::move(actionSharedChatDelete.value()));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -73,52 +73,8 @@ void Connection::onChannelBan(
|
||||
const lib::payload::channel_ban::v1::Payload &payload)
|
||||
{
|
||||
(void)metadata;
|
||||
|
||||
auto roomID = QString::fromStdString(payload.event.broadcasterUserID);
|
||||
|
||||
BanAction action{};
|
||||
|
||||
if (!getApp()->isTest())
|
||||
{
|
||||
action.timestamp = std::chrono::steady_clock::now();
|
||||
}
|
||||
action.roomID = roomID;
|
||||
action.source = ActionUser{
|
||||
.id = QString::fromStdString(payload.event.moderatorUserID),
|
||||
.login = QString::fromStdString(payload.event.moderatorUserLogin),
|
||||
.displayName = QString::fromStdString(payload.event.moderatorUserName),
|
||||
};
|
||||
action.target = ActionUser{
|
||||
.id = QString::fromStdString(payload.event.userID),
|
||||
.login = QString::fromStdString(payload.event.userLogin),
|
||||
.displayName = QString::fromStdString(payload.event.userName),
|
||||
};
|
||||
action.reason = QString::fromStdString(payload.event.reason);
|
||||
if (payload.event.isPermanent)
|
||||
{
|
||||
action.duration = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto timeoutDuration = payload.event.timeoutDuration();
|
||||
auto timeoutDurationInSeconds =
|
||||
std::chrono::duration_cast<std::chrono::seconds>(timeoutDuration)
|
||||
.count();
|
||||
action.duration = timeoutDurationInSeconds;
|
||||
}
|
||||
|
||||
auto chan = getApp()->getTwitch()->getChannelOrEmptyByID(roomID);
|
||||
|
||||
runInGuiThread([action{std::move(action)}, chan{std::move(chan)}] {
|
||||
auto time = QDateTime::currentDateTime();
|
||||
if (getApp()->isTest())
|
||||
{
|
||||
time = QDateTime::fromSecsSinceEpoch(0).toUTC();
|
||||
}
|
||||
MessageBuilder msg(action, time);
|
||||
msg->flags.set(MessageFlag::PubSub);
|
||||
chan->addOrReplaceTimeout(msg.release(), QDateTime::currentDateTime());
|
||||
});
|
||||
qCDebug(LOG) << "On channel ban event for channel"
|
||||
<< payload.event.broadcasterUserLogin.c_str();
|
||||
}
|
||||
|
||||
void Connection::onStreamOnline(
|
||||
|
||||
@@ -107,4 +107,37 @@ void makeModerateMessage(EventSubMessageBuilder &builder,
|
||||
builder.message().searchText = text;
|
||||
}
|
||||
|
||||
void makeModerateMessage(EventSubMessageBuilder &builder,
|
||||
const lib::payload::channel_moderate::v2::Event &event,
|
||||
const lib::payload::channel_moderate::v2::Ban &action)
|
||||
{
|
||||
QString text;
|
||||
bool isShared = event.isFromSharedChat();
|
||||
|
||||
builder.appendUser(event.moderatorUserName, event.moderatorUserLogin, text);
|
||||
builder.emplaceSystemTextAndUpdate("banned", text);
|
||||
builder.appendUser(action.userName, action.userLogin, text, isShared);
|
||||
|
||||
if (isShared)
|
||||
{
|
||||
builder.emplaceSystemTextAndUpdate("in", text);
|
||||
builder.appendUser(*event.sourceBroadcasterUserName,
|
||||
*event.sourceBroadcasterUserLogin, text, false);
|
||||
}
|
||||
|
||||
if (action.reason.view().empty())
|
||||
{
|
||||
builder.emplaceSystemTextAndUpdate(".", text);
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.emplaceSystemTextAndUpdate(":", text);
|
||||
builder.emplaceSystemTextAndUpdate(action.reason.qt(), text);
|
||||
}
|
||||
|
||||
builder->messageText = text;
|
||||
builder->searchText = text;
|
||||
builder->timeoutUser = action.userLogin.qt();
|
||||
}
|
||||
|
||||
} // namespace chatterino::eventsub
|
||||
|
||||
@@ -43,4 +43,9 @@ void makeModerateMessage(
|
||||
const lib::payload::channel_moderate::v2::Event &event,
|
||||
const lib::payload::channel_moderate::v2::Warn &action);
|
||||
|
||||
/// <MODERATOR> banned <USER>[ in <CHANNEL>]: <REASON>
|
||||
void makeModerateMessage(EventSubMessageBuilder &builder,
|
||||
const lib::payload::channel_moderate::v2::Event &event,
|
||||
const lib::payload::channel_moderate::v2::Ban &action);
|
||||
|
||||
} // namespace chatterino::eventsub
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "providers/twitch/eventsub/MessageHandlers.hpp"
|
||||
|
||||
#include "Application.hpp"
|
||||
#include "messages/Message.hpp"
|
||||
#include "messages/MessageBuilder.hpp"
|
||||
#include "providers/twitch/TwitchChannel.hpp"
|
||||
#include "singletons/Settings.hpp"
|
||||
@@ -26,4 +27,19 @@ void handleModerateMessage(
|
||||
});
|
||||
}
|
||||
|
||||
void addModerateMessage(
|
||||
TwitchChannel *channel, MessagePtr message, const QDateTime &time,
|
||||
const lib::payload::channel_moderate::v2::Ban & /*action*/)
|
||||
{
|
||||
runInGuiThread([channel, msg{std::move(message)}, time] {
|
||||
channel->addOrReplaceTimeout(msg, time);
|
||||
if (getSettings()->hideModerated)
|
||||
{
|
||||
// XXX: This is expensive. We could use a layout request if the layout
|
||||
// would store the previous message flags.
|
||||
getApp()->getWindows()->forceLayoutChannelViews();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace chatterino::eventsub
|
||||
|
||||
@@ -2,10 +2,17 @@
|
||||
|
||||
#include "twitch-eventsub-ws/payloads/channel-moderate-v2.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
class QDateTime;
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
class TwitchChannel;
|
||||
|
||||
struct Message;
|
||||
using MessagePtr = std::shared_ptr<const Message>;
|
||||
|
||||
} // namespace chatterino
|
||||
|
||||
namespace chatterino::eventsub {
|
||||
|
||||
@@ -15,117 +15,5 @@
|
||||
"user_name": "testFromUser"
|
||||
},
|
||||
"output": [
|
||||
{
|
||||
"badgeInfos": {
|
||||
},
|
||||
"badges": [
|
||||
],
|
||||
"channelName": "",
|
||||
"count": 1,
|
||||
"displayName": "",
|
||||
"elements": [
|
||||
{
|
||||
"element": {
|
||||
"color": "System",
|
||||
"flags": "Timestamp",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"0:00"
|
||||
]
|
||||
},
|
||||
"flags": "Timestamp",
|
||||
"format": "",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"time": "00:00:00",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TimestampElement"
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "UserInfo",
|
||||
"value": "CLIModerator"
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"CLIModerator"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"banned"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "UserInfo",
|
||||
"value": "testFromUser"
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"testFromUser:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"\"This",
|
||||
"is",
|
||||
"a",
|
||||
"test",
|
||||
"event\"."
|
||||
]
|
||||
}
|
||||
],
|
||||
"flags": "System|Timeout|PubSub",
|
||||
"id": "",
|
||||
"localizedName": "",
|
||||
"loginName": "CLIModerator",
|
||||
"messageText": "CLIModerator banned testFromUser: \"This is a test event\". ",
|
||||
"searchText": "CLIModerator banned testFromUser: \"This is a test event\". ",
|
||||
"serverReceivedTime": "1970-01-01T00:00:00Z",
|
||||
"timeoutUser": "testFromUser",
|
||||
"userID": "",
|
||||
"usernameColor": "#ff000000"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -15,120 +15,5 @@
|
||||
"user_name": "testFromUser"
|
||||
},
|
||||
"output": [
|
||||
{
|
||||
"badgeInfos": {
|
||||
},
|
||||
"badges": [
|
||||
],
|
||||
"channelName": "",
|
||||
"count": 1,
|
||||
"displayName": "",
|
||||
"elements": [
|
||||
{
|
||||
"element": {
|
||||
"color": "System",
|
||||
"flags": "Timestamp",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"0:00"
|
||||
]
|
||||
},
|
||||
"flags": "Timestamp",
|
||||
"format": "",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"time": "00:00:00",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TimestampElement"
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "UserInfo",
|
||||
"value": "CLIModerator"
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"CLIModerator"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"timed",
|
||||
"out"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "UserInfo",
|
||||
"value": "testFromUser"
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"testFromUser"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"for",
|
||||
"10m:",
|
||||
"\"This",
|
||||
"is",
|
||||
"a",
|
||||
"test",
|
||||
"event\"."
|
||||
]
|
||||
}
|
||||
],
|
||||
"flags": "System|Timeout|PubSub",
|
||||
"id": "",
|
||||
"localizedName": "",
|
||||
"loginName": "CLIModerator",
|
||||
"messageText": "CLIModerator timed out testFromUser for 10m: \"This is a test event\". ",
|
||||
"searchText": "CLIModerator timed out testFromUser for 10m: \"This is a test event\". ",
|
||||
"serverReceivedTime": "1970-01-01T00:00:00Z",
|
||||
"timeoutUser": "testFromUser",
|
||||
"userID": "",
|
||||
"usernameColor": "#ff000000"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
{
|
||||
"input": {
|
||||
"action": "ban",
|
||||
"automod_terms": null,
|
||||
"ban": {
|
||||
"reason": "my reason",
|
||||
"user_id": "489584266",
|
||||
"user_login": "uint128",
|
||||
"user_name": "uint128"
|
||||
},
|
||||
"broadcaster_user_id": "11148817",
|
||||
"broadcaster_user_login": "pajlada",
|
||||
"broadcaster_user_name": "pajlada",
|
||||
"delete": null,
|
||||
"followers": null,
|
||||
"mod": null,
|
||||
"moderator_user_id": "129546453",
|
||||
"moderator_user_login": "nerixyz",
|
||||
"moderator_user_name": "nerixyz",
|
||||
"raid": null,
|
||||
"shared_chat_ban": null,
|
||||
"shared_chat_delete": null,
|
||||
"shared_chat_timeout": null,
|
||||
"shared_chat_unban": null,
|
||||
"shared_chat_untimeout": null,
|
||||
"slow": null,
|
||||
"source_broadcaster_user_id": null,
|
||||
"source_broadcaster_user_login": null,
|
||||
"source_broadcaster_user_name": null,
|
||||
"timeout": null,
|
||||
"unban": null,
|
||||
"unban_request": null,
|
||||
"unmod": null,
|
||||
"unraid": null,
|
||||
"untimeout": null,
|
||||
"unvip": null,
|
||||
"vip": null,
|
||||
"warn": null
|
||||
},
|
||||
"output": [
|
||||
{
|
||||
"badgeInfos": {
|
||||
},
|
||||
"badges": [
|
||||
],
|
||||
"channelName": "",
|
||||
"count": 1,
|
||||
"displayName": "",
|
||||
"elements": [
|
||||
{
|
||||
"element": {
|
||||
"color": "System",
|
||||
"flags": "Timestamp",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"0:00"
|
||||
]
|
||||
},
|
||||
"flags": "Timestamp",
|
||||
"format": "",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"time": "00:00:00",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TimestampElement"
|
||||
},
|
||||
{
|
||||
"color": "Text",
|
||||
"fallbackColor": "System",
|
||||
"flags": "Text|Mention",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "MentionElement",
|
||||
"userColor": "System",
|
||||
"userLoginName": "nerixyz",
|
||||
"words": [
|
||||
"nerixyz"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"banned"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "Text",
|
||||
"fallbackColor": "System",
|
||||
"flags": "Text|Mention",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": false,
|
||||
"type": "MentionElement",
|
||||
"userColor": "System",
|
||||
"userLoginName": "uint128",
|
||||
"words": [
|
||||
"uint128"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
":"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"my",
|
||||
"reason"
|
||||
]
|
||||
}
|
||||
],
|
||||
"flags": "System|Timeout",
|
||||
"id": "",
|
||||
"localizedName": "",
|
||||
"loginName": "nerixyz",
|
||||
"messageText": "nerixyz banned uint128: my reason ",
|
||||
"searchText": "nerixyz banned uint128: my reason ",
|
||||
"serverReceivedTime": "1970-01-01T00:00:00Z",
|
||||
"timeoutUser": "uint128",
|
||||
"userID": "",
|
||||
"usernameColor": "#ff000000"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
{
|
||||
"input": {
|
||||
"action": "ban",
|
||||
"automod_terms": null,
|
||||
"ban": {
|
||||
"reason": "",
|
||||
"user_id": "489584266",
|
||||
"user_login": "uint128",
|
||||
"user_name": "uint128"
|
||||
},
|
||||
"broadcaster_user_id": "11148817",
|
||||
"broadcaster_user_login": "pajlada",
|
||||
"broadcaster_user_name": "pajlada",
|
||||
"delete": null,
|
||||
"followers": null,
|
||||
"mod": null,
|
||||
"moderator_user_id": "129546453",
|
||||
"moderator_user_login": "nerixyz",
|
||||
"moderator_user_name": "nerixyz",
|
||||
"raid": null,
|
||||
"shared_chat_ban": null,
|
||||
"shared_chat_delete": null,
|
||||
"shared_chat_timeout": null,
|
||||
"shared_chat_unban": null,
|
||||
"shared_chat_untimeout": null,
|
||||
"slow": null,
|
||||
"source_broadcaster_user_id": null,
|
||||
"source_broadcaster_user_login": null,
|
||||
"source_broadcaster_user_name": null,
|
||||
"timeout": null,
|
||||
"unban": null,
|
||||
"unban_request": null,
|
||||
"unmod": null,
|
||||
"unraid": null,
|
||||
"untimeout": null,
|
||||
"unvip": null,
|
||||
"vip": null,
|
||||
"warn": null
|
||||
},
|
||||
"output": [
|
||||
{
|
||||
"badgeInfos": {
|
||||
},
|
||||
"badges": [
|
||||
],
|
||||
"channelName": "",
|
||||
"count": 1,
|
||||
"displayName": "",
|
||||
"elements": [
|
||||
{
|
||||
"element": {
|
||||
"color": "System",
|
||||
"flags": "Timestamp",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"0:00"
|
||||
]
|
||||
},
|
||||
"flags": "Timestamp",
|
||||
"format": "",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"time": "00:00:00",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TimestampElement"
|
||||
},
|
||||
{
|
||||
"color": "Text",
|
||||
"fallbackColor": "System",
|
||||
"flags": "Text|Mention",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "MentionElement",
|
||||
"userColor": "System",
|
||||
"userLoginName": "nerixyz",
|
||||
"words": [
|
||||
"nerixyz"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"banned"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "Text",
|
||||
"fallbackColor": "System",
|
||||
"flags": "Text|Mention",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": false,
|
||||
"type": "MentionElement",
|
||||
"userColor": "System",
|
||||
"userLoginName": "uint128",
|
||||
"words": [
|
||||
"uint128"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"."
|
||||
]
|
||||
}
|
||||
],
|
||||
"flags": "System|Timeout",
|
||||
"id": "",
|
||||
"localizedName": "",
|
||||
"loginName": "nerixyz",
|
||||
"messageText": "nerixyz banned uint128. ",
|
||||
"searchText": "nerixyz banned uint128. ",
|
||||
"serverReceivedTime": "1970-01-01T00:00:00Z",
|
||||
"timeoutUser": "uint128",
|
||||
"userID": "",
|
||||
"usernameColor": "#ff000000"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
{
|
||||
"input": {
|
||||
"action": "shared_chat_ban",
|
||||
"automod_terms": null,
|
||||
"ban": null,
|
||||
"broadcaster_user_id": "11148817",
|
||||
"broadcaster_user_login": "pajlada",
|
||||
"broadcaster_user_name": "pajlada",
|
||||
"delete": null,
|
||||
"followers": null,
|
||||
"mod": null,
|
||||
"moderator_user_id": "129546453",
|
||||
"moderator_user_login": "nerixyz",
|
||||
"moderator_user_name": "nerixyz",
|
||||
"raid": null,
|
||||
"shared_chat_ban": {
|
||||
"reason": "a reason 😂",
|
||||
"user_id": "141981764",
|
||||
"user_login": "twitchdev",
|
||||
"user_name": "TwitchDev"
|
||||
},
|
||||
"shared_chat_delete": null,
|
||||
"shared_chat_timeout": null,
|
||||
"shared_chat_unban": null,
|
||||
"shared_chat_untimeout": null,
|
||||
"slow": null,
|
||||
"source_broadcaster_user_id": "117166826",
|
||||
"source_broadcaster_user_login": "testaccount_420",
|
||||
"source_broadcaster_user_name": "테스트계정420",
|
||||
"timeout": null,
|
||||
"unban": null,
|
||||
"unban_request": null,
|
||||
"unmod": null,
|
||||
"unraid": null,
|
||||
"untimeout": null,
|
||||
"unvip": null,
|
||||
"vip": null,
|
||||
"warn": null
|
||||
},
|
||||
"output": [
|
||||
{
|
||||
"badgeInfos": {
|
||||
},
|
||||
"badges": [
|
||||
],
|
||||
"channelName": "",
|
||||
"count": 1,
|
||||
"displayName": "",
|
||||
"elements": [
|
||||
{
|
||||
"element": {
|
||||
"color": "System",
|
||||
"flags": "Timestamp",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"0:00"
|
||||
]
|
||||
},
|
||||
"flags": "Timestamp",
|
||||
"format": "",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"time": "00:00:00",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TimestampElement"
|
||||
},
|
||||
{
|
||||
"color": "Text",
|
||||
"fallbackColor": "System",
|
||||
"flags": "Text|Mention",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "MentionElement",
|
||||
"userColor": "System",
|
||||
"userLoginName": "nerixyz",
|
||||
"words": [
|
||||
"nerixyz"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"banned"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "Text",
|
||||
"fallbackColor": "System",
|
||||
"flags": "Text|Mention",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "MentionElement",
|
||||
"userColor": "System",
|
||||
"userLoginName": "twitchdev",
|
||||
"words": [
|
||||
"TwitchDev"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"in"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "Text",
|
||||
"fallbackColor": "System",
|
||||
"flags": "Text|Mention",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": false,
|
||||
"type": "MentionElement",
|
||||
"userColor": "System",
|
||||
"userLoginName": "testaccount_420",
|
||||
"words": [
|
||||
"테스트계정420"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
":"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"a",
|
||||
"reason",
|
||||
"😂"
|
||||
]
|
||||
}
|
||||
],
|
||||
"flags": "System|Timeout",
|
||||
"id": "",
|
||||
"localizedName": "",
|
||||
"loginName": "nerixyz",
|
||||
"messageText": "nerixyz banned twitchdev in testaccount_420: a reason 😂 ",
|
||||
"searchText": "nerixyz banned twitchdev in testaccount_420: a reason 😂 ",
|
||||
"serverReceivedTime": "1970-01-01T00:00:00Z",
|
||||
"timeoutUser": "twitchdev",
|
||||
"userID": "",
|
||||
"usernameColor": "#ff000000"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
{
|
||||
"input": {
|
||||
"action": "shared_chat_ban",
|
||||
"automod_terms": null,
|
||||
"ban": null,
|
||||
"broadcaster_user_id": "11148817",
|
||||
"broadcaster_user_login": "pajlada",
|
||||
"broadcaster_user_name": "pajlada",
|
||||
"delete": null,
|
||||
"followers": null,
|
||||
"mod": null,
|
||||
"moderator_user_id": "129546453",
|
||||
"moderator_user_login": "nerixyz",
|
||||
"moderator_user_name": "nerixyz",
|
||||
"raid": null,
|
||||
"shared_chat_ban": {
|
||||
"reason": "",
|
||||
"user_id": "141981764",
|
||||
"user_login": "twitchdev",
|
||||
"user_name": "TwitchDev"
|
||||
},
|
||||
"shared_chat_delete": null,
|
||||
"shared_chat_timeout": null,
|
||||
"shared_chat_unban": null,
|
||||
"shared_chat_untimeout": null,
|
||||
"slow": null,
|
||||
"source_broadcaster_user_id": "117166826",
|
||||
"source_broadcaster_user_login": "testaccount_420",
|
||||
"source_broadcaster_user_name": "테스트계정420",
|
||||
"timeout": null,
|
||||
"unban": null,
|
||||
"unban_request": null,
|
||||
"unmod": null,
|
||||
"unraid": null,
|
||||
"untimeout": null,
|
||||
"unvip": null,
|
||||
"vip": null,
|
||||
"warn": null
|
||||
},
|
||||
"output": [
|
||||
{
|
||||
"badgeInfos": {
|
||||
},
|
||||
"badges": [
|
||||
],
|
||||
"channelName": "",
|
||||
"count": 1,
|
||||
"displayName": "",
|
||||
"elements": [
|
||||
{
|
||||
"element": {
|
||||
"color": "System",
|
||||
"flags": "Timestamp",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"0:00"
|
||||
]
|
||||
},
|
||||
"flags": "Timestamp",
|
||||
"format": "",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"time": "00:00:00",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TimestampElement"
|
||||
},
|
||||
{
|
||||
"color": "Text",
|
||||
"fallbackColor": "System",
|
||||
"flags": "Text|Mention",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "MentionElement",
|
||||
"userColor": "System",
|
||||
"userLoginName": "nerixyz",
|
||||
"words": [
|
||||
"nerixyz"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"banned"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "Text",
|
||||
"fallbackColor": "System",
|
||||
"flags": "Text|Mention",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "MentionElement",
|
||||
"userColor": "System",
|
||||
"userLoginName": "twitchdev",
|
||||
"words": [
|
||||
"TwitchDev"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"in"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "Text",
|
||||
"fallbackColor": "System",
|
||||
"flags": "Text|Mention",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": false,
|
||||
"type": "MentionElement",
|
||||
"userColor": "System",
|
||||
"userLoginName": "testaccount_420",
|
||||
"words": [
|
||||
"테스트계정420"
|
||||
]
|
||||
},
|
||||
{
|
||||
"color": "System",
|
||||
"flags": "Text",
|
||||
"link": {
|
||||
"type": "None",
|
||||
"value": ""
|
||||
},
|
||||
"style": "ChatMedium",
|
||||
"tooltip": "",
|
||||
"trailingSpace": true,
|
||||
"type": "TextElement",
|
||||
"words": [
|
||||
"."
|
||||
]
|
||||
}
|
||||
],
|
||||
"flags": "System|Timeout",
|
||||
"id": "",
|
||||
"localizedName": "",
|
||||
"loginName": "nerixyz",
|
||||
"messageText": "nerixyz banned twitchdev in testaccount_420. ",
|
||||
"searchText": "nerixyz banned twitchdev in testaccount_420. ",
|
||||
"serverReceivedTime": "1970-01-01T00:00:00Z",
|
||||
"timeoutUser": "twitchdev",
|
||||
"userID": "",
|
||||
"usernameColor": "#ff000000"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user