enough_mail 0.2.0 copy "enough_mail: ^0.2.0" to clipboard
enough_mail: ^0.2.0 copied to clipboard

outdated

IMAP, POP3 and SMTP email clients in pure Dart. Choose between a low level and a high level API for mailing.

IMAP, POP3 and SMTP clients for Dart developers.

Available under the commercial friendly MPL Mozilla Public License 2.0.

Installation #

Add this dependency your pubspec.yaml file:

dependencies:
  enough_mail: ^0.1.0

The latest version or enough_mail is enough_mail version.

API Documentation #

Check out the full API documentation at https://pub.dev/documentation/enough_mail/latest/

High Level API Usage #

The high level API abstracts away from IMAP and POP3 details, reconnects automatically and allows to easily watch a mailbox for new messages. A simple usage example for using the high level API:

import 'dart:io';
import 'package:enough_mail/enough_mail.dart';

String userName = 'user.name';
String password = 'password';

void main() async {
  await mailExample();
}

/// High level mail API example
Future<void> mailExample() async {
  final email = '$userName@$domain';
  print('discovering settings for  $email...');
  final config = await Discover.discover(email);
  if (config == null) {
    print('Unable to autodiscover settings for $email');
    return;
  }
  print('connecting to ${config.displayName}.');
  final account =
      MailAccount.fromDiscoveredSettings('my account', email, password, config);
  final mailClient = MailClient(account, isLogEnabled: true);
  try {
    await mailClient.connect();
    print('connected');
    final mailboxes =
        await mailClient.listMailboxesAsTree(createIntermediate: false);
    print(mailboxes);
    await mailClient.selectInbox();
    final messages = await mailClient.fetchMessages(count: 20);
    for (final msg in messages) {
      printMessage(msg);
    }
    mailClient.eventBus.on<MailLoadEvent>().listen((event) {
      print('New message at ${DateTime.now()}:');
      printMessage(event.message);
    });
    await mailClient.startPolling();
  } on MailException catch (e) {
    print('High level API failed with $e');
  }
}

Low Level Usage #

A simple usage example for using the low level API:

import 'dart:io';
import 'package:enough_mail/enough_mail.dart';

String userName = 'user.name';
String password = 'password';
String imapServerHost = 'imap.domain.com';
int imapServerPort = 993;
bool isImapServerSecure = true;
String popServerHost = 'pop.domain.com';
int popServerPort = 995;
bool isPopServerSecure = true;
String smtpServerHost = 'smtp.domain.com';
int smtpServerPort = 465;
bool isSmtpServerSecure = true;

void main() async {
  await discoverExample();
  await imapExample();
  await smtpExample();
  await popExample();
  exit(0);
}

Future<void> discoverExample() async {
  var email = 'someone@enough.de';
  var config = await Discover.discover(email, isLogEnabled: false);
  if (config == null) {
    print('Unable to discover settings for $email');
  } else {
    print('Settings for $email:');
    for (var provider in config.emailProviders) {
      print('provider: ${provider.displayName}');
      print('provider-domains: ${provider.domains}');
      print('documentation-url: ${provider.documentationUrl}');
      print('Incoming:');
      print(provider.preferredIncomingServer);
      print('Outgoing:');
      print(provider.preferredOutgoingServer);
    }
  }
}

/// Low level IMAP API usage example
Future<void> imapExample() async {
  final client = ImapClient(isLogEnabled: false);
  try {
    await client.connectToServer(imapServerHost, imapServerPort,
        isSecure: isImapServerSecure);
    await client.login(userName, password);
    final mailboxes = await client.listMailboxes();
    print('mailboxes: $mailboxes');
    await client.selectInbox();
    // fetch 10 most recent messages:
    final fetchResult = await client.fetchRecentMessages(
        messageCount: 10, criteria: 'BODY.PEEK[]');
    for (final message in fetchResult.messages) {
      printMessage(message);
    }
    await client.logout();
  } on ImapException catch (e) {
    print('IMAP failed with $e');
  }
}

/// Low level SMTP API example
Future<void> smtpExample() async {
  final client = SmtpClient('enough.de', isLogEnabled: true);
  try {
    await client.connectToServer(smtpServerHost, smtpServerPort,
        isSecure: isSmtpServerSecure);
    await client.ehlo();
    await client.login('user.name', 'password');
    final builder = MessageBuilder.prepareMultipartAlternativeMessage();
    builder.from = [MailAddress('My name', 'sender@domain.com')];
    builder.to = [MailAddress('Your name', 'recipient@domain.com')];
    builder.subject = 'My first message';
    builder.addTextPlain('hello world.');
    builder.addTextHtml('<p>hello <b>world</b></p>');
    final mimeMessage = builder.buildMimeMessage();
    final sendResponse = await client.sendMessage(mimeMessage);
    print('message sent: ${sendResponse.isOkStatus}');
  } on SmtpException catch (e) {
    print('SMTP failed with $e');
  }
}

/// Low level POP3 API example
Future<void> popExample() async {
  final client = PopClient(isLogEnabled: false);
  try {
    await client.connectToServer(popServerHost, popServerPort,
        isSecure: isPopServerSecure);
    await client.login(userName, password);
    // alternative login:
    // await client.loginWithApop(userName, password); // optional different login mechanism
    final status = await client.status();
    print(
        'status: messages count=${status.numberOfMessages}, messages size=${status.totalSizeInBytes}');
    final messageList = await client.list(status.numberOfMessages);
    print(
        'last message: id=${messageList?.first?.id} size=${messageList?.first?.sizeInBytes}');
    var message = await client.retrieve(status.numberOfMessages);
    printMessage(message);
    message = await client.retrieve(status.numberOfMessages + 1);
    print('trying to retrieve newer message succeeded');
    await client.quit();
  } on PopException catch (e) {
    print('POP failed with $e');
  }
}

void printMessage(MimeMessage message) {
  print('from: ${message.from} with subject "${message.decodeSubject()}"');
  if (!message.isTextPlainMessage()) {
    print(' content-type: ${message.mediaType}');
  } else {
    final plainText = message.decodeTextPlainPart();
    if (plainText != null) {
      final lines = plainText.split('\r\n');
      for (final line in lines) {
        if (line.startsWith('>')) {
          // break when quoted text starts
          break;
        }
        print(line);
      }
    }
  }
}

Migrating #

If you have been using a 0.0.x version of the API you need to switch from evaluating responses to just getting the data and handling exceptions if something went wrong.

Old code example:

final client = ImapClient(isLogEnabled: false);
await client.connectToServer(imapServerHost, imapServerPort,
    isSecure: isImapServerSecure);
final loginResponse = await client.login(userName, password);
if (loginResponse.isOkStatus) {
  final listResponse = await client.listMailboxes();
  if (listResponse.isOkStatus) {
    print('mailboxes: ${listResponse.result}');
    final inboxResponse = await client.selectInbox();
    if (inboxResponse.isOkStatus) {
      // fetch 10 most recent messages:
      final fetchResponse = await client.fetchRecentMessages(
          messageCount: 10, criteria: 'BODY.PEEK[]');
      if (fetchResponse.isOkStatus) {
        final messages = fetchResponse.result.messages;
        for (var message in messages) {
          printMessage(message);
        }
      }
    }
  }
  await client.logout();
}

Migrated code example:

final client = ImapClient(isLogEnabled: false);
try {
  await client.connectToServer(imapServerHost, imapServerPort,
    isSecure: isImapServerSecure);
  await client.login(userName, password);
  final mailboxes = await client.listMailboxes();
  print('mailboxes: ${mailboxes}');
  await client.selectInbox();
  // fetch 10 most recent messages:
  final fetchResult = await client.fetchRecentMessages(
      messageCount: 10, criteria: 'BODY.PEEK[]');
  for (var message in fetchResult.messages) {
    printMessage(message);
  }
  await client.logout();
} on ImapException catch (e) {
  print('imap failed with $e');
}

As you can see the code is now much simpler and shorter.

Depending on which API you use there are different exceptions to handle:

  • MailException for the high level API
  • ImapException for the low level IMAP API
  • PopException for the low level POP3 API
  • SmtpException for the low level SMTP API

Check out these related projects:

Miss a feature or found a bug? #

Please file feature requests and bugs at the issue tracker.

Contribute #

Want to contribute? Please check out contribute. This is an open-source community project. Anyone, even beginners, can contribute.

This is how you contribute:

  • Fork the enough_mail project by pressing the fork button.
  • Clone your fork to your computer: git clone github.com/$your_username/enough_mail
  • Do your changes. When you are done, commit changes with git add -A and git commit.
  • Push changes to your personal repository: git push origin
  • Go to enough_mail and create a pull request.

Thank you in advance!

Features #

Done #

The following IMAP extensions are supported:

Supported encodings #

Character encodings:

  • ASCII (7bit)
  • UTF-8 (uft8, 8bit)
  • ISO-8859-1 (latin-1)
  • ISO-8859-2 - 16 (latin-2 - 16)
  • Windows-1250, 1251, 1252

Transfer encodings:

To do #

Develop and Contribute #

  • To start check out the package and then run pub run test to run all tests.
  • Public facing library classes are in lib, lib/imap and lib/smtp.
  • Private classes are in lib/src.
  • Test cases are in test.
  • Please file a pull request for each improvement/fix that you are create - your contributions are welcome.
  • Check out https://github.com/enough-Software/enough_mail/contribute for good first issues.

License #

enough_mail is licensed under the commecial friendly Mozilla Public License 2.0.

117
likes
0
pub points
91%
popularity

Publisher

verified publisherenough.de

IMAP, POP3 and SMTP email clients in pure Dart. Choose between a low level and a high level API for mailing.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

basic_utils, crypto, enough_convert, enough_serialization, event_bus, http, intl, pedantic, xml

More

Packages that depend on enough_mail