import 'dart:async'; import 'dart:math'; import 'package:desktopapp/classes/stream_element.dart'; import 'package:desktopapp/utils/logger.dart'; import 'package:desktopapp/utils/requests.dart'; import 'package:enough_mail/enough_mail.dart'; class Mailer { static final List customMessages = [ 'Un gueux vient de commander de la HOLY', 'Un nouveau gueux vient de commander de la HOLY' ]; static final List whiteListEmail = ['louis@holyenergy.fr']; static MailClient? _mailClient; /// High level mail API example static Future connect({ required String email, required String password, required StreamController streamController, }) async { Logger.log(LoggerType.info, Mailer, 'Discovering settings for $email'); final config = await Discover.discover(email); if (config == null) { Logger.log(LoggerType.info, Mailer, 'Unable to autodiscover settings for $email'); return false; } Logger.log(LoggerType.info, Mailer, 'Settings for $email : $config'); final account = MailAccount.fromDiscoveredSettings( 'my account', email, password, config); _mailClient = MailClient(account, isLogEnabled: true); try { await _mailClient!.connect(); Logger.log(LoggerType.info, Mailer, 'Connected to $email'); streamController .add(StreamElement(StreamElementType.log, 'Connected to $email')); await _mailClient!.selectInbox(); streamController.add( StreamElement(StreamElementType.log, 'INBOX selected for $email')); List whitelist = [email, ...whiteListEmail]; streamController.add(StreamElement( StreamElementType.log, 'Listen for emails: ${whitelist.join(', ')}')); _mailClient!.eventBus.on().listen((ImapEvent event) async { await _onMessage(event, streamController, email, whitelist); }); await _mailClient!.startPolling(); return true; } on MailException catch (e) { streamController.add(StreamElement(StreamElementType.log, e.toString())); Logger.log(LoggerType.error, Mailer, 'High level API failed with $e'); return false; } } static Future disconnect({ required StreamController streamController, }) async { if (_mailClient == null) return; Logger.log(LoggerType.info, Mailer, 'Disconnecting from mail'); await _mailClient!.stopPolling(); await _mailClient!.disconnect(); Logger.log(LoggerType.info, Mailer, 'Disconnected from mail'); _mailClient = null; streamController .add(StreamElement(StreamElementType.log, 'Disconnected from mail')); } static Future _onMessage( ImapEvent event, StreamController streamController, String email, List whitelist) async { if (event.eventType == ImapEventType.exists) { final evt = event as ImapMessagesExistEvent; if (evt.newMessagesExists <= evt.oldMessagesExists) return; final sequence = MessageSequence(); if (evt.newMessagesExists - evt.oldMessagesExists > 1) { sequence.addRange(evt.oldMessagesExists, evt.newMessagesExists); } else { sequence.add(evt.newMessagesExists); } final messages = await _mailClient!.fetchMessageSequence(sequence, fetchPreference: FetchPreference.envelope); for (final message in messages) { MailAddress? mail = message.from?.cast().firstWhere( (mEmail) => whitelist.contains(mEmail!.email), orElse: () => null); if (mail == null) continue; var mailEvt = MailLoadEvent(message, _mailClient!); _onMailEvent(mailEvt, streamController); } } } static Future _onMailEvent( MailLoadEvent mailLoadEvent, StreamController streamController) async { final message = customMessages[Random.secure().nextInt(customMessages.length)]; await Requests.sendAlert(message, type: AlertType.host); streamController.add(StreamElement(StreamElementType.alert, message)); } }