Shoutout para YouTube
Arte original: Cosmic Wolf
Sinta-se á vontade para testar, mas esteja ciente que podem conter bugs. Use por sua conta e risco.
Use um comando de destaque para chamar atenção dos espectadores para uma pessoa importante no seu chat, como um raider, e convidar seu chat para conhecer o canal da pessoa!
Agradecimentos especiais para a Cosmic Wolf, por me permitir publicar este widget que eu fiz pra uso dela ^^
☕ Te ajudei? Me manda um cafézinho ^^
[email protected]
Índice:
Introdução
Na Twitch, este comando é conhecido como /shoutout ou !s2, e é bem mais simples de se implementar, já que envolve simplesmente criar um comando que escreve twitch.tv/usuárioMarcado. Esse método não é possível no YouTube, já que o nome que aparece no chat não é seu nome de usuário.
Sendo assim, eu desenvolvi uma abordagem diferente que usa os dados que um widget tem do chat para enviar o link do usuário destacado para o chat! Entretanto, este é um código mais complexo que um widget normal, e ele se divide em 3 partes:
- Um arquivo de script no seu Google Drive;
- Um comando no chatbot do StreamElements;
- Um widget do StreamElements que precisa estar ativo no seu OBS.
Parte 1: Instalando o script no Google Drive
Abra o seu Google Drive e vá em ➕ Novo > Mais > Script do Google Apps.
Você pode criar esse script em qualquer pasta do seu Google Drive, desde não corra o risco de você deletá-lo por acidente. Vale inclusive renomear depois o arquivo para você não o perder :)
Cole o código abaixo na janela que se abrir:
/** Função acionada quando a API é chamada.
* @param {'store'|'find'} e.parameter.action - Ação a ser executada pela API
* @param {string} e.parameter.username - Nome do usuário a executar a ação
* @param {string} e.parameter.message - Mensagem a armazenar, obrigatório apenas caso action = store
*/
function doGet(e) {
switch (e.parameter.action) { // A depender da ação requisitada, executar
case 'store': // Caso seja para armazenar:
store(decodeURI(e.parameter.username), decodeURI(e.parameter.message)); // Armazenar URL
return ContentService.createTextOutput(JSON.stringify({ status: 'stored' })); // Retornar status de sucesso
case 'find': // Caso seja para encontrar:
return ContentService.createTextOutput(find(e.parameter.username)); // Retornar URL
}
}
/** Armazena dados do usuário na memória do GAS.
* @param {string} username - Nome do usuário a executar a ação
* @param {string} message - Mensagem a armazenar
*/
function store(username, message) {
PropertiesService.getScriptProperties().setProperty(username, message) // Armazena URL nas propriedades
}
/** Obter dados do usuário na memória do GAS.
* @param {string} username - Nome do usuário a executar a ação
*/
function find(username) {
let url = null // Declara variável de URL
for (let tries = 0; tries < 10; tries++) { // Tenta achar o URL 10x
Utilities.sleep(3000); // Espera 3seg
url = PropertiesService.getScriptProperties().getProperty(username.replaceAll("@","")) // Obtém URL das propriedades
if (url != null) break; // Se URL encontrada, sair do loop
}
if (url == null) return "" // Se URL não encontrada, retornar vazio
return url // Retornar URL
}
Clique em Implantar > Nova implantação.
Na nova janela, clique em ⚙️ > App da Web.
A opção "Executar como" deve estar marcada como "Eu", e "Quem pode acessar" como "Qualquer pessoa". Depois disso, clique em Implantar.
Copie o URL do App da Web e guarde temporariamente num Bloco de Notas; ele será importante nas próximas partes.
Parte 2: Configurando o comando no Chatbot
Existem 2 comandos de destaques diferentes:
- Um silencioso, que apenas mostra a mensagem no chat; e
- Um que também mostra um alerta no widget.
No video do tutorial, vou utilizar shoutout como comando silencioso, e raid como comando de alerta, mas você pode personalizar para qual texto preferir, desde que você use a mesma configuração de comando no chatbot e no widget.
Acesse https://streamelements.com/dashboard/bot/commands/custom.
Clique em Add new command.
Em Command name, informe o nome do comando silencioso.
Em Response type, copie e cole o texto abaixo, substituindo [URL do Apps Script] pelo URL que você anotou na parte anterior.
${urlfetch [URL do Apps Script]?action=find&username=${1:}}
Vá em Advanced settings > Command aliases e informe o nome do comando de alerta.
E finalize clicando em Activate command.
Opcionalmente, você também pode definir o User level, caso queira restringir o uso do comando apenas para moderadores, por exemplo.
Parte 3: Configurando o widget
Agora nós vamos instalar o widget no overlay. Eu já fiz um tutorial ensinando a instalar um widget no StreamElements, que você pode ver clicando aqui. Depois de instalado, entraremos diretamente na configuração do widget em si.
O código que você deve instalar é o seguinte:
HTML
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family={{alert_googleFont}}" rel="stylesheet">
<div id="alert_container" data-fade="{{alert_fade}}">
<img id="image" src="{{alert_image}}">
<p id="alert_text" data-value="{{alert_text}}" data-shadow="{{alert_shadow}}" style="--text-color: {{alert_textcolor}}; --shoutout-text-color: {{alert_shoutouttextcolor}}"></p>
<audio id="alert_audio" src="{{alert_audio}}"></audio>
</div>
CSS
body,
#alert_container {
display: flex;
align-items: center;
flex-direction: column;
margin: 0;
padding: 0;
overflow: hidden;
font-family: "{{alert_googleFont}}", sans-serif;
}
#alert_container {
opacity: 0%;
transition: 500ms ease;
&[data-show="true"] {
opacity: 100%;
}
}
#image {
height: 66vh;
}
#alert_text {
margin: 0;
margin-top: 3vh;
font-size: 10vh;
font-weight: 800;
text-align: center;
color: var(--text-color);
span {
color: var(--shoutout-text-color);
}
&[data-shadow="true"] {
filter: drop-shadow(0 0 1vh #00000050);
}
}
#audios {
display: none;
}
Javascript
// Definição de variáveis
let chatUsers = new Map() // Objeto para armazenar os dados de quem fala no chat
let await_start = true // Variável para aguardar a inicialização do código
let apiUrl = "{{api_url}}" // URL da API do Google Apps Script
let cmdSilent = "!{{cmd_silentCommand}}" // Comando que chama o shoutout silenciosamente
let cmdAlert = "!{{cmd_alertCommand}}" // Comando que chama o alerta de shoutout
let cmdText = "{{cmd_text}}" // Texto que o comando vai retornar
let cmdPermissionLevel = "{{cmd_permissionLevel}}" // Nível de permissão para usar o comando
// Executar assim que iniciar
window.onload = () => {
// Definição de variáveis
let alert_textHTML = document.querySelector(`#alert_text`)
// Insere os elementos de texto na descrição do alerta
alert_textHTML.innerHTML = alert_textHTML.dataset.value
.replaceAll("{username}", '<span id="username">USER</span>')
// Aguardar 5seg antes de disparar alertas
setTimeout(() => {
await_start = false;
console.log("Shoutout inicializado.")
}, 5000)
}
// Executar quando receber um evento
window.addEventListener('onEventReceived', function (obj) {
if (await_start) return // Caso esteja aguardando ligar, ignorar
let data = obj.detail.event.data // Armazena dados do evento
// Executa uma ação baseada em um evento
switch (obj.detail.listener) {
case "message":
// Definição de variáveis
let text = data.text // Armazena texto da mensagem
let user = data.authorDetails // Armazena usuário da mensagem
let userAccess = user.isChatOwner ? 2 : // Usuário é dono do canal?
user.isChatModerator ? 1 : 0 // Usuário é mod do canal?
let command = /^![^\s]{0,}/.exec(text) // Armazena comando
let userCalled = /(?<=@).*$/.exec(text) // Armazena usuário marcado
// Armazena usuário na database interna
chatUsers.set(user.displayName, { url: user.channelUrl, pict: data.avatar })
// Se não há comando ou usuário marcado, encerrar execução
if (command == null || userCalled == null) return
// Se há um comando do shoutout, enviar usuário para a API
if (command[0] == cmdAlert || command[0] == cmdSilent) storeInAPI(userCalled[0])
// Se o comando de alerta foi chamado e usuário tem permissão, mostrar alerta
if (command[0] == cmdAlert && userAccess - cmdPermissionLevel >= 0 ) showAlert(userCalled[0])
// Encerrar execução
return;
case "event:test":
showAlert("DaniFluffyTesty") // Executa alerta de teste
return; // Encerra execução
}
});
// Envia informações do usuário para API
function storeInAPI(username) {
// Declaração de variáveis
let user = undefined
let loopCount = 0
// Executar loop
let loop = setInterval(() => {
if (loopCount < 10) clearInterval(loop) // Caso mais de 10 loops, encerrar loop
loopCount++ // Acrescenta 1 ao contador do loop
user = chatUsers.get(username) // Procura o username
if (user == undefined) return // Caso não tenha achado o usuário, partir para próxima tentativa
// Envia os dados para a API
let message = cmdText.replaceAll("{username}", username).replaceAll("{url}", user.url)
fetch(`${apiUrl}?action=store&username=${decodeURI(username)}&message=${decodeURI(message)}`)
clearInterval(loop)
}, 3000);
}
// Mostra alerta na tela
function showAlert(username) {
// Declaração de variáveis
let alertHTML = document.querySelector(`#alert_container`)
let usernameHTML = document.querySelector(`#username`)
let audioHTML = document.querySelector("#alert_audio")
usernameHTML.textContent = username // Definir nome de usuário
audioHTML.play() // Tocar audio do alerta
alertHTML.dataset.show = true // Exibir overlay
setTimeout(() =>
alertHTML.dataset.show = false, // Oculta overlay
alertHTML.dataset.fade * 1000 // Aguarda xx segundos para isso
)
}
Fields
{
"credits1": {
"type": "checkbox",
"value": true,
"label": "Detalhes de como fazer a configuração podem ser encontrados no site toolbox.danifluffy.dev :)",
"group": "Shoutout | DaniFluffyCat ^^"
},
"credits2": {
"type": "text",
"label": "Você pode copiar o link abaixo:",
"value": "toolbox.danifluffy.dev",
"group": "Shoutout | DaniFluffyCat ^^"
},
"important": {
"type": "checkbox",
"label": "⚠️IMPORTANTE: Este widget é composto por 3 componentes: uma API, um comando e o widget em si. Para saber como configurar, acesse o site.",
"value": true,
"group": "Shoutout | DaniFluffyCat ^^"
},
"api_url": {
"type": "text",
"label": "URL da API do Google Apps Script",
"value": "https://script.google.com/macros/s/abc123/exec",
"group": "API"
},
"alert_image": {
"type": "image-input",
"label": "Imagem do alerta",
"group": "Alerta"
},
"alert_audio": {
"type": "sound-input",
"label": "Som do alerta",
"group": "Alerta"
},
"alert_text": {
"type": "text",
"label": "Texto do alerta",
"value": "Confira o canal de {username}!",
"group": "Alerta"
},
"alert_googleFont": {
"type": "googleFont",
"label": "Selecione a fonte:",
"value": "Roboto",
"group": "Alerta"
},
"alert_textcolor": {
"type": "colorpicker",
"label": "Cor do texto",
"value": "#ffffff",
"group": "Alerta"
},
"alert_shoutouttextcolor": {
"type": "colorpicker",
"label": "Cor de destaque do texto",
"value": "#cccc00",
"group": "Alerta"
},
"alert_shadow": {
"type": "checkbox",
"label": "Sombra do texto",
"value": false,
"group": "Alerta"
},
"alert_fade": {
"type": "number",
"label": "Duração do alerta (em seg)",
"value": 10,
"min": 5,
"max": 30,
"step": 1,
"group": "Alerta"
},
"alert_test": {
"type": "button",
"label": "Testar alerta",
"group": "Alerta"
},
"cmd_silentCommand": {
"type": "text",
"label": "Comando silencioso de destaque",
"value": "shoutout",
"group": "Comando"
},
"cmd_alertCommand": {
"type": "text",
"label": "Comando para chamar o alerta",
"value": "raid",
"group": "Comando"
},
"cmd_text": {
"type": "text",
"label": "Texto do comando",
"value": "Chat, confira o canal de {username}! {url}",
"group": "Comando"
},
"cmd_permissionLevel": {
"type": "dropdown",
"label": "Quem pode usar o comando?",
"value": "1",
"options": {
"0": "Todo mundo",
"1": "Apenas moderador e dono do canal",
"2": "Apenas dono do canal"
},
"group": "Comando"
}
}
Configuração "API"
Aqui você deve colar o URL que você anotou na parte 1 do tutorial.
Configuração "Alerta"
Aqui você vai configurar como o alerta irá aparecer na sua live. Tem 2 pontos importantes para destacar:
- Se você quiser inserir um video ao invés de uma imagem, sugiro converter para GIF com uma ferramenta como o EzGif.
- Em Texto do alerta você deve escrever
{username}
onde irá aparecer o nome da pessoa destacada.
Configuração "Comando"
Aqui você vai configurar como o comando irá responder no seu chat. Destaco uma configuração importante no Texto do comando: você deve escrever {username}
onde irá aparecer o nome da pessoa destacada, e {url}
onde irá aparecer o link do canal da pessoa.
Para o comando funcionar corretamente, o overlay com este widget precisa estar ativo no seu OBS, mesmo para usar o comando silencioso.
☕ Te ajudei? Me manda um cafézinho ^^
[email protected]