throw new \Exception('channel has no twitch chat set');
}
$validatedData = $request->validate([
+ 'adlib' => 'boolean',
'bot_nick' => 'string',
'category' => 'string',
'text' => 'string',
]);
$this->authorize('editRestream', $channel);
$nick = empty($validatedData['bot_nick']) ? 'localhorsttv' : $validatedData['bot_nick'];
- if (empty($validatedData['category'])) {
+ if (isset($validatedData['adlib']) && $validatedData['adlib']) {
+ TwitchBotCommand::adlibChat($channel, $request->user());
+ } else if (empty($validatedData['category'])) {
TwitchBotCommand::chat($channel->twitch_chat, $validatedData['text'], $request->user(), $nick);
} else {
TwitchBotCommand::randomChat($channel, $validatedData['category'], $request->user(), $nick);
throw new \Exception('channel has no twitch chat set');
}
$validatedData = $request->validate([
+ 'adlib' => 'integer|min:0|max:100',
'language' => 'string|in:de,en,es,fr',
'min_age' => 'integer|min:1',
'respond' => 'string|in:50,no,yes',
{
use HasFactory;
+ public static function adlibChat(Channel $channel, User $user = null) {
+ $cmd = new TwitchBotCommand();
+ $cmd->command = 'adlib-chat';
+ $cmd->parameters = [
+ 'channel' => $channel->id,
+ ];
+ $cmd->status = 'pending';
+ $cmd->user()->associate($user);
+ $cmd->bot_nick = 'horstiebot';
+ $cmd->save();
+ }
+
public static function chat($channel, $text, User $user = null, $nick = 'localhorsttv') {
$cmd = new TwitchBotCommand();
$cmd->command = 'chat';
use App\Models\Channel;
use App\Models\ChatBotLog;
+use App\Models\ChatLib;
use App\Models\ChatLog;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
$this->updateChannels();
$this->startTimer();
$this->listenCommands();
+ $this->chatlib = new ChatLib();
+ $this->chatlib->loadFrom('de');
}
public function joinChannels() {
$this->tagChannelRead($channel, $msg);
}
+ public function getChatlibDatabase(Channel $channel) {
+ return $this->chatlib;
+ }
+
private function startTimer() {
$this->getLoop()->addPeriodicTimer(1, function () {
return;
}
$text = $this->contextualMsg($channel);
+ if ($this->shouldAdlib($channel)) {
+ $this->performAdlib($channel);
+ return;
+ }
if (!$text) $text = $this->randomChat($channel);
if (!$text) return;
$actual_text = is_object($text) ? $text->text_content : $text;
return $channel->queryChatlog()->first();
}
+ private function performAdlib(Channel $channel) {
+ $db = $this->getChatlibDatabase($channel);
+ $text = $db->generate();
+ $this->tagChannelWrite($channel);
+ $this->sendIRCMessage(IRCMessage::privmsg($channel->twitch_chat, $text));
+ $log = new ChatBotLog();
+ $log->channel()->associate($channel);
+ $log->category = 'adlib';
+ $log->text = $text;
+ $log->save();
+ }
+
private function randomWaitMsgs(Channel $channel) {
$min = $channel->getChatSetting('wait_msgs_min', 1);
$max = $channel->getChatSetting('wait_msgs_max', 10);
return false;
}
+ private function shouldAdlib(Channel $channel) {
+ $setting = $channel->getChatSetting('adlib', 50);
+ if ($setting == 0) {
+ return false;
+ }
+ if ($setting == 100) {
+ return true;
+ }
+ return random_int(0, 100) <= $setting;
+ }
+
private function shouldRespond(Channel $channel) {
$setting = $channel->getChatSetting('respond', 'yes');
if ($setting == 'yes') {
private $channels;
private $notes = [];
+ private $chatlib;
}
--- /dev/null
+<?php
+
+namespace App\TwitchBotCommands;
+
+use App\Models\Channel;
+use App\Models\ChatBotLog;
+use App\Models\TwitchBotCommand;
+use App\TwitchBot\IRCMessage;
+use App\TwitchBot\TwitchBot;
+use React\Promise\Promise;
+
+class AdlibChatCommand extends BaseCommand {
+
+ public function __construct(TwitchBot $bot, TwitchBotCommand $cmd) {
+ parent::__construct($bot, $cmd);
+ }
+
+ public function execute() {
+ return new Promise(function($resolve) {
+ $channel = Channel::findOrFail($this->getParameter('channel'));
+ $db = $this->bot->getChatlibDatabase($channel);
+ $text = $db->generate();
+ $this->bot->sendIRCMessage(IRCMessage::privmsg($channel->twitch_chat, $text));
+ $log = new ChatBotLog();
+ $log->channel()->associate($channel);
+ $log->text = $text;
+ $log->user()->associate($this->getExecutingUser());
+ $log->category = 'adlib';
+ $log->save();
+ $resolve();
+ });
+ }
+
+}
public static function resolve(TwitchBot $bot, TwitchBotCommand $cmd) {
switch ($cmd->command) {
+ case 'adlib-chat':
+ return new AdlibChatCommand($bot, $cmd);
case 'chat':
return new ChatCommand($bot, $cmd);
case 'join':
</Form.Control.Feedback>
: null}
</Form.Group>
+ <Form.Group as={Col} md={6} controlId="chatSettings.adlib">
+ <Form.Label>{t('twitchBot.chatAdlibChance')}</Form.Label>
+ <Form.Control
+ isInvalid={!!(touched.adlib && errors.adlib)}
+ name="adlib"
+ min="0"
+ max="100"
+ onBlur={handleBlur}
+ onChange={handleChange}
+ type="number"
+ value={values.adlib || 1}
+ />
+ </Form.Group>
</Row>
<div className="button-bar mt-3">
<Button disabled={!dirty || isSubmitting} type="submit" variant="primary">
ChatSettingsForm.propTypes = {
dirty: PropTypes.bool,
errors: PropTypes.shape({
+ adlib: PropTypes.string,
language: PropTypes.string,
min_age: PropTypes.string,
respond: PropTypes.string,
handleSubmit: PropTypes.func,
isSubmitting: PropTypes.bool,
touched: PropTypes.shape({
+ adlib: PropTypes.bool,
language: PropTypes.bool,
min_age: PropTypes.bool,
respond: PropTypes.bool,
wait_time_max: PropTypes.bool,
}),
values: PropTypes.shape({
+ adlib: PropTypes.number,
language: PropTypes.string,
min_age: PropTypes.number,
respond: PropTypes.string,
});
},
mapPropsToValues: ({ channel }) => ({
+ adlib: channel.chat_settings.adlib || 50,
language: channel.chat_settings.language || channel.languages[0] || 'de',
min_age: channel.chat_settings.min_age || 1,
respond: channel.chat_settings.respond || 'yes',
? formatTime({ time: channel.chat_settings.wait_time_max }) : '15:00',
}),
validationSchema: yup.object().shape({
+ adlib: yup.number().min(0).max(100),
language: yup.string(),
min_age: yup.number().min(1),
respond: yup.string(),
}
}, [channel, chatText, t]);
+ const adlibChat = React.useCallback(async () => {
+ try {
+ await axios.post(`/api/channels/${channel.id}/chat`, {
+ bot_nick: 'horstiebot',
+ adlib: true,
+ });
+ toastr.success(t('twitchBot.chatSuccess'));
+ } catch (e) {
+ toastr.error(t('twitchBot.chatError'));
+ }
+ }, [channel, chatText, t]);
+
const join = React.useCallback(async (bot_nick) => {
try {
const rsp = await axios.post(`/api/channels/${channel.id}/join`, { bot_nick });
</Button>
)}
</div>
+ <div className="mt-3">
+ <Button
+ onClick={() => { adlibChat(); }}
+ title={t('twitchBot.adlibChatDesc')}
+ variant="outline-secondary"
+ >
+ {t('twitchBot.adlibChat')}
+ </Button>
+ <p className="text-muted">{t('twitchBot.adlibChatNote')}</p>
+ </div>
</Col>
<Col className="mt-5" md={6}>
<div className="d-flex justify-content-between">
},
twitchBot: {
addCommand: 'Command hinzufügen',
+ adlibChat: 'ad lib Chat',
+ adlibChatDesc: 'Generier eine Nachricht basierend auf alten.',
+ adlibChatNote: 'Aufgrund der benötigten Datenmenge aktuell nur in deutsch verfügbar.',
channel: 'Channel',
chat: 'Chat',
+ chatAdlibChance: 'ad lib Chance',
chatCategories: {
+ adlib: 'ad lib',
eyes: 'Augen',
gg: 'Good Game',
gl: 'Good Luck',
},
twitchBot: {
addCommand: 'Add command',
+ adlibChat: 'ad lib Chat',
+ adlibChatDesc: 'Generate a message inspired by the chatlog.',
+ adlibChatNote: 'Due to the amount of data required currently only supported in german.',
channel: 'Channel',
chat: 'Chat',
+ chatAdlibChance: 'ad lib chance',
chatCategories: {
+ adlib: 'ad lib',
eyes: 'Eyes',
gg: 'Good Game',
gl: 'Good Luck',