Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 11 additions & 15 deletions bin/beer_bot.dart
Original file line number Diff line number Diff line change
@@ -1,32 +1,28 @@
import 'dart:io';

import 'package:nyxx/nyxx.dart';
import 'package:nyxx_interactions/nyxx_interactions.dart';
import 'package:nyxx_commands/nyxx_commands.dart';

import 'commands.dart';
import 'modules/untappd/untapped_module.dart';

String BOT_TOKEN = Platform.environment['DISCORD_TOKEN'] ?? '';

late final INyxxWebsocket bot;

void main(List<String> arguments) {
bot =
NyxxFactory.createNyxxWebsocket(BOT_TOKEN, GatewayIntents.allUnprivileged)
..registerPlugin(Logging())
..registerPlugin(CliIntegration())
..registerPlugin(IgnoreExceptions())
..connect();

final interactions = IInteractions.create(WebsocketInteractionBackend(bot));
// late final INyxxWebsocket bot;

void main(List<String> arguments) async {
final commands = CommandsPlugin(prefix: mentionOr((_) => '!'));
Commands.getCommands().forEach((command) {
interactions.registerSlashCommand(command);
commands.addCommand(command);
});

interactions.syncOnReady();
final bot =
await Nyxx.connectGateway('<TOKEN>', GatewayIntents.allUnprivileged,
options: GatewayClientOptions(
plugins: [commands],
));

bot.eventsWs.onReady.listen((e) {
bot.onReady.listen((ReadyEvent e) {
print('Agent Hops is ready!');
});

Expand Down
41 changes: 18 additions & 23 deletions bin/commands.dart
Original file line number Diff line number Diff line change
@@ -1,38 +1,33 @@
import 'package:nyxx/nyxx.dart';
import 'package:nyxx_interactions/nyxx_interactions.dart';
import 'package:nyxx_commands/nyxx_commands.dart';

import 'modules/untappd/untapped_module.dart';

class Commands {
static List<SlashCommandBuilder> getCommands() => [
SlashCommandBuilder(
/// Get all commands available for the bot
static List<ChatCommand> getCommands() => [
ChatCommand(
'help',
'List commands available',
[],
)..registerHandler((event) async {
await event.acknowledge();
await _helpCommand(event);
}),
(ChatContext ctx) async {
await _helpCommand(ctx);
},
),
// Add all commands from the modules here
...UntappdModule().commands,
];

static Future<void> _helpCommand(ISlashCommandInteractionEvent ctx) async {
var helpMessage = MessageBuilder()
..append(ctx.interaction.userAuthor!.mention)
..appendNewLine()
..append(_mainHelpMessage)
..appendNewLine()
..appendNewLine()
..append(UntappdModule().helpMessage);
static Future<void> _helpCommand(ChatContext ctx) async {
var helpMessage = MessageBuilder(
content: '$_mainHelpMessage\n\n'
'${UntappdModule().helpMessage}');

await ctx.respond(helpMessage);
}

static MessageBuilder get _mainHelpMessage => MessageBuilder()
..append('Did anyone say beer? This is what I can do for you:')
..appendNewLine()
..appendNewLine()
..appendBold('/help')
..appendNewLine()
..append('Shows you this help message.');
static MessageBuilder get _mainHelpMessage => MessageBuilder(
content: 'Did anyone say beer? This is what I can do for you: \n\n'
'/help\n'
'Shows you this help message.',
);
}
153 changes: 72 additions & 81 deletions bin/modules/beer_agent/beer_agent_module.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:intl/intl.dart';
import 'package:nyxx/nyxx.dart';
import 'package:nyxx_interactions/nyxx_interactions.dart';
import 'package:nyxx_commands/nyxx_commands.dart';

import '../bot_module.dart';
import 'models/beer.dart';
Expand All @@ -19,7 +19,7 @@ class BeerAgentModule extends BotModule {

bool _isInitialized = false;

late INyxxWebsocket _bot;
late NyxxGateway _bot;

static final BeerAgentModule _singleton = BeerAgentModule._internal();

Expand Down Expand Up @@ -56,34 +56,32 @@ class BeerAgentModule extends BotModule {
}

if (shouldInform) {
for (var dmchannel in await _getSubChannels(_bot)) {
for (var userDmChannel in await _getSubbedUsers(_bot)) {
var beersStr = '';
beers.forEach((element) {
beersStr += '- ' + element.name + '\n';
});

var updateMessage = MessageBuilder()
..append(':beers: Hey!')
..appendNewLine()
..append('There is a fresh beer release tomorrow, ')
..appendBold(DateFormat('yyyy-MM-dd').format(saleDate))
..append('. Bolaget opens 10:00')
..appendNewLine()
..append('There are ')
..appendBold(beers.length.toString())
..append(' new beers tomorrow.')
..appendNewLine()
..append('For more info, visit https://systembevakningsagenten.se/')
..appendNewLine()
..appendNewLine()
..append(beersStr);
var updateMessage = MessageBuilder(
content: ':beers: Hey!'
'\n'
'There is a fresh beer release tomorrow, '
'${DateFormat('yyyy-MM-dd').format(saleDate)}. Bolaget opens 10:00'
'\n'
'There are ${beers.length} new beers tomorrow.'
'\n'
'For more info, visit https://systembevakningsagenten.se/'
'\n\n'
'$beersStr',
);

//To avoid hitting maximum characters for a message, limit output to 2000.
if (updateMessage.toString().length > 2000) {
updateMessage.content =
updateMessage.content.substring(0, 1992) + '...\n\n';
final content = updateMessage.content;
if (content != null && content.toString().length > 2000) {
updateMessage.content = content.substring(0, 1992) + '...\n\n';
}
await dmchannel.sendMessage(updateMessage);

await userDmChannel.sendMessage(updateMessage);
}
} else {
print('No sale, boring...');
Expand All @@ -103,24 +101,21 @@ class BeerAgentModule extends BotModule {
}
}

/// Returns a list of all channels (users) that are subscribed to beer updates.
Future<List<IDMChannel>> _getSubChannels(INyxxWebsocket bot) async {
/// Returns a list of all users that are subscribed to beer updates.
Future<List<DmChannel>> _getSubbedUsers(NyxxGateway bot) async {
var myFile = File('sub.dat');
var channelList = <IDMChannel>[];
var userList = <DmChannel>[];

var fileExists = await myFile.exists();
if (!fileExists) await myFile.create();

await myFile.readAsLines().then((value) async {
for (var line in value) {
var chan = await bot
.fetchChannel(Snowflake(line))
.then((value) => (value as IDMChannel));

channelList.add(chan);
var chan = await bot.channels.fetch(Snowflake(int.parse(line)));
userList.add(chan as DmChannel);
}
});
return channelList;
return userList;
}

/// Updates the list of beer sales.
Expand Down Expand Up @@ -159,9 +154,9 @@ class BeerAgentModule extends BotModule {
throw Exception('Beer agent service not initialized!');
}

var subs = await _getSubChannels(_bot);
var subs = await _getSubbedUsers(_bot);

if (subs.asSnowflakes().contains(userSnowflake)) {
if (subs.map((elemet) => elemet.id).contains(userSnowflake)) {
return true;
} else {
return false;
Expand All @@ -175,7 +170,7 @@ class BeerAgentModule extends BotModule {
throw Exception('Beer agent service not initialized!');
}

var currentSubs = await _getSubChannels(_bot);
var currentSubs = await _getSubbedUsers(_bot);

currentSubs.removeWhere((element) => element.id == userSnowflake);
var tempFile = File('temp.dat');
Expand Down Expand Up @@ -204,7 +199,7 @@ class BeerAgentModule extends BotModule {
}

@override
void init(INyxxWebsocket bot) {
void init(NyxxGateway bot) {
_bot = bot;
_elapsedSinceUpdate = Stopwatch();
_elapsedSinceUpdate.start();
Expand All @@ -215,67 +210,63 @@ class BeerAgentModule extends BotModule {
}

@override
List<SlashCommandBuilder> get commands => !_isInitialized
List<ChatCommand> get commands => !_isInitialized
? throw Exception('Beer agent module not initialized!')
: [
SlashCommandBuilder(
ChatCommand(
'oel',
'Show the latest beer releases.',
[],
)..registerHandler((event) async {
await event.acknowledge();
await _oelCommand(event);
}),
SlashCommandBuilder(
(ChatContext ctx) async {
await _oelCommand(ctx);
},
),
ChatCommand(
'subscribe',
'Subscribe to beer release reminders.',
[],
)..registerHandler((event) async {
await event.acknowledge();
await _regCommand(event);
}),
SlashCommandBuilder(
(ChatContext ctx) async {
await _regCommand(ctx, _bot);
},
),
ChatCommand(
'stop',
'Unsubscribe to beer release reminders.',
[],
)..registerHandler((event) async {
await event.acknowledge();
await _stopCommand(event);
}),
SlashCommandBuilder(
(ChatContext ctx) async {
await _stopCommand(ctx);
},
),
ChatCommand(
'release',
'Detailed info about a specific beer release e.g. /release 2022-07-15',
[
CommandOptionBuilder(
CommandOptionType.string, 'datum', 'YYYY-MM-dd',
required: true),
],
)..registerHandler((event) async {
await event.acknowledge();
await _releaseCommand(event);
}),
(ChatContext ctx,
[@Name('date')
@Description('The date of the release in the format YYYY-MM-dd')
String? date]) async {
if (date == null) {
await ctx.respond(MessageBuilder(
content: 'Please provide a date in the format YYYY-MM-dd'));
return;
}
await _releaseCommand(ctx);
},
)
];

@override
MessageBuilder get helpMessage => !_isInitialized
? throw Exception('Beer agent not initialized!')
: MessageBuilder()
..appendBold('/oel')
..appendNewLine()
..append('Lists all known beer releases.')
..appendNewLine()
..appendNewLine()
..appendBold('/subscribe')
..appendNewLine()
..append(
'Subscribe to automatic beer release reminders. Reminders will be posted 3 times during the day before release.')
..appendNewLine()
..appendNewLine()
..appendBold('/release YYYY-MM-dd')
..appendNewLine()
..append(
'Posts the beer release for given date in the format YYYY-MM-dd. e.g ')
..appendItalics('/release 1970-01-30');
: MessageBuilder(
content:
'Beer agent module is active! Here are the available commands:'
'\n\n'
'/oel\n'
'Lists all known beer releases.'
'\n\n'
'/subscribe\n'
'Subscribe to automatic beer release reminders. Reminders will be posted 3 times during the day before release.'
'\n\n'
'/release YYYY-MM-dd\n'
'Posts the beer release for given date in the format YYYY-MM-dd. e.g */release 1970-01-30*',
);

/// Returns a list of all current beer sales.
List<BeerList> get beerSales => _beerSales;
Expand Down
Loading
Loading