116 lines
3.7 KiB
GDScript
116 lines
3.7 KiB
GDScript
@icon("../assets/chat-icon.svg")
|
|
@tool
|
|
extends Twitcher
|
|
|
|
## Grants access to read and write to a chat
|
|
class_name TwitchChat
|
|
|
|
static var _log: TwitchLogger = TwitchLogger.new("TwitchChat")
|
|
|
|
static var instance: TwitchChat
|
|
|
|
@export var broadcaster_user: TwitchUser:
|
|
set(val):
|
|
broadcaster_user = val
|
|
update_configuration_warnings()
|
|
## Can be null. Then the owner of the access token will be used to send message aka the current user.
|
|
@export var sender_user: TwitchUser
|
|
@export var media_loader: TwitchMediaLoader
|
|
@export var eventsub: TwitchEventsub:
|
|
set(val):
|
|
eventsub = val
|
|
update_configuration_warnings()
|
|
@export var api: TwitchAPI:
|
|
set(val):
|
|
api = val
|
|
update_configuration_warnings()
|
|
|
|
## Should it subscribe on ready
|
|
@export var subscribe_on_ready: bool = true
|
|
|
|
|
|
## Triggered when a chat message got received
|
|
signal message_received(message: TwitchChatMessage)
|
|
|
|
|
|
func _ready() -> void:
|
|
_log.d("is ready")
|
|
if media_loader == null: media_loader = TwitchMediaLoader.instance
|
|
if api == null: api = TwitchAPI.instance
|
|
if eventsub == null: eventsub = TwitchEventsub.instance
|
|
eventsub.event.connect(_on_event_received)
|
|
if not Engine.is_editor_hint() && subscribe_on_ready:
|
|
subscribe()
|
|
|
|
|
|
func _enter_tree() -> void:
|
|
if instance == null: instance = self
|
|
|
|
|
|
func _exit_tree() -> void:
|
|
if instance == self: instance = null
|
|
|
|
|
|
## Subscribe to eventsub and preload data if not happend yet
|
|
func subscribe() -> void:
|
|
if broadcaster_user == null:
|
|
printerr("BroadcasterUser is not set. Can't subscribe to chat.")
|
|
return
|
|
|
|
if is_instance_valid(media_loader):
|
|
media_loader.preload_badges(broadcaster_user.id)
|
|
media_loader.preload_emotes(broadcaster_user.id)
|
|
|
|
for subscription: TwitchEventsubConfig in eventsub.get_subscriptions():
|
|
if subscription.type == TwitchEventsubDefinition.Type.CHANNEL_CHAT_MESSAGE and \
|
|
subscription.condition.broadcaster_user_id == broadcaster_user.id:
|
|
# it is already subscribed
|
|
return
|
|
|
|
if sender_user == null:
|
|
var current_user: TwitchGetUsers.Response = await api.get_users(null)
|
|
sender_user = current_user.data[0]
|
|
|
|
var config: TwitchEventsubConfig = TwitchEventsubConfig.new()
|
|
config.type = TwitchEventsubDefinition.Type.CHANNEL_CHAT_MESSAGE
|
|
config.condition = {
|
|
"broadcaster_user_id": broadcaster_user.id,
|
|
"user_id": sender_user.id
|
|
}
|
|
eventsub.subscribe(config)
|
|
_log.i("Listen to Chat of %s (%s)" % [broadcaster_user.display_name, broadcaster_user.id])
|
|
|
|
|
|
func _on_event_received(type: StringName, data: Dictionary) -> void:
|
|
if type != TwitchEventsubDefinition.CHANNEL_CHAT_MESSAGE.value: return
|
|
var message: TwitchChatMessage = TwitchChatMessage.from_json(data)
|
|
if message.broadcaster_user_id == broadcaster_user.id:
|
|
message_received.emit(message)
|
|
|
|
|
|
func send_message(message: String, reply_parent_message_id: String = "") -> Array[TwitchSendChatMessage.ResponseData]:
|
|
var message_body: TwitchSendChatMessage.Body = TwitchSendChatMessage.Body.new()
|
|
message_body.broadcaster_id = broadcaster_user.id
|
|
message_body.sender_id = sender_user.id
|
|
message_body.message = message
|
|
if reply_parent_message_id:
|
|
message_body.reply_parent_message_id = reply_parent_message_id
|
|
|
|
var response: TwitchSendChatMessage.Response = await api.send_chat_message(message_body)
|
|
if _log.enabled:
|
|
for message_data: TwitchSendChatMessage.ResponseData in response.data:
|
|
if not message_data.is_sent:
|
|
_log.w(message_data.drop_reason)
|
|
|
|
return response.data
|
|
|
|
|
|
func _get_configuration_warnings() -> PackedStringArray:
|
|
var result: PackedStringArray = []
|
|
if eventsub == null:
|
|
result.append("TwitchEventsub not assigned")
|
|
if api == null:
|
|
result.append("TwitchAPI not assigned")
|
|
if broadcaster_user == null:
|
|
result.append("Target broadcaster not specified")
|
|
return result
|