Перейти к основному содержимому

Email

Поле типа Email предназначено для хранения адресов электронной почты с автоматической валидацией.

Основные характеристики

  • Тип данных: Строка с валидацией email
  • Формат хранения: Нормализованный email (lowercase)
  • Автоматическая валидация: Проверка корректности формата
  • Уникальность: Часто используется с ограничением уникальности
  • Максимальная длина: 254 символа (стандарт RFC 5321)

Настройки поля

При создании поля типа "Email" доступны следующие настройки:

  • Название поля: Отображаемое имя поля
  • Системное имя: Уникальный идентификатор для API
  • Описание: Подсказка для пользователей
  • Обязательное поле: Требовать заполнения
  • Уникальное значение: Запретить дублирование email
  • Нормализация: Автоматическое приведение к нижнему регистру
  • Проверка DNS: Проверять существование домена (опционально)

Примеры использования

Email пользователя

{
"name": "email",
"type": "email",
"required": true,
"unique": true,
"normalize": true
}

Рабочий email

{
"name": "work_email",
"type": "email",
"required": false
}

Email для уведомлений

{
"name": "notification_email",
"type": "email",
"required": false
}

Работа через API

Создание записи

const record = await emd.database.collection('users').create({
name: 'Иван Иванов',
email: 'ivan@example.com'
});

// Email автоматически нормализуется
const record = await emd.database.collection('users').create({
name: 'Петр Петров',
email: 'PETR@EXAMPLE.COM' // Сохранится как petr@example.com
});

Получение email

const record = await emd.database.collection('users').get(recordId);

console.log(record.email);
// {
// address: "ivan@example.com",
// local: "ivan",
// domain: "example.com",
// verified: false
// }

Поиск по email

// Точное совпадение
const user = await emd.database.collection('users').findOne({
email: 'ivan@example.com'
});

// Поиск по домену
const users = await emd.database.collection('users').find({
'email.domain': 'example.com'
});

// Поиск по части email
const users = await emd.database.collection('users').find({
email: { $contains: 'ivan' }
});

Обновление email

await emd.database.collection('users').update(recordId, {
email: 'new.email@example.com'
});

Валидация

Автоматическая валидация формата

try {
await emd.database.collection('users').create({
name: 'Иван',
email: 'invalid-email' // Некорректный формат
});
} catch (error) {
console.error(error.message); // "Invalid email address"
}

Проверка уникальности

try {
await emd.database.collection('users').create({
name: 'Петр',
email: 'ivan@example.com' // Email уже существует
});
} catch (error) {
console.error(error.message); // "Email already exists"
}

Проверка существования домена

try {
await emd.database.collection('users').create({
name: 'Иван',
email: 'user@nonexistentdomain12345.com'
});
} catch (error) {
console.error(error.message); // "Email domain does not exist"
}

Верификация email

Отправка письма с подтверждением

const record = await emd.database.collection('users').get(recordId);

// Создать токен верификации
const token = generateVerificationToken();

await emd.database.collection('verification_tokens').create({
userId: record.id,
email: record.email.address,
token: token,
expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000) // 24 часа
});

// Отправить email
await emailService.send({
to: record.email.address,
subject: 'Подтвердите ваш email',
html: `
<p>Нажмите на ссылку для подтверждения:</p>
<a href="https://example.com/verify?token=${token}">Подтвердить email</a>
`
});

Подтверждение email

const verification = await emd.database.collection('verification_tokens').findOne({
token: token,
expiresAt: { $gt: new Date() }
});

if (verification) {
await emd.database.collection('users').update(verification.userId, {
email_verified: true,
verified_at: new Date()
});

await emd.database.collection('verification_tokens').delete(verification.id);
}

Отправка писем

Простое письмо

const record = await emd.database.collection('users').get(recordId);

await emailService.send({
to: record.email.address,
subject: 'Добро пожаловать!',
text: 'Спасибо за регистрацию!',
html: '<h1>Спасибо за регистрацию!</h1>'
});

Письмо с вложениями

await emailService.send({
to: record.email.address,
subject: 'Ваш счет',
html: '<p>Во вложении ваш счет</p>',
attachments: [
{
filename: 'invoice.pdf',
path: '/path/to/invoice.pdf'
}
]
});

Массовая рассылка

const users = await emd.database.collection('users').find({
email_verified: true,
notifications_enabled: true
});

for (const user of users) {
await emailService.send({
to: user.email.address,
subject: 'Новости недели',
html: getNewsletterTemplate(user)
});
}

Операторы для email полей

  • $eq — равно
  • $ne — не равно
  • $contains — содержит подстроку
  • $startsWith — начинается с
  • $endsWith — заканчивается на
  • $in — входит в список
  • $exists — проверка наличия значения

Примеры запросов

Найти пользователей с корпоративными email

const users = await emd.database.collection('users').find({
'email.domain': { $in: ['company.com', 'company.ru'] }
});

Найти пользователей с Gmail

const users = await emd.database.collection('users').find({
'email.domain': 'gmail.com'
});

Найти неподтвержденные email

const users = await emd.database.collection('users').find({
email_verified: false
});

Нормализация

Автоматическое приведение к нижнему регистру

// Ввод: IVAN@EXAMPLE.COM
// Сохранено: ivan@example.com

const record = await emd.database.collection('users').create({
email: 'IVAN@EXAMPLE.COM'
});

console.log(record.email.address); // "ivan@example.com"

Удаление пробелов

// Ввод: " ivan@example.com "
// Сохранено: ivan@example.com

const record = await emd.database.collection('users').create({
email: ' ivan@example.com '
});

console.log(record.email.address); // "ivan@example.com"

Извлечение частей email

const record = await emd.database.collection('users').get(recordId);
const email = record.email;

console.log(email.address); // "ivan.ivanov@example.com"
console.log(email.local); // "ivan.ivanov"
console.log(email.domain); // "example.com"

// Получить имя пользователя из email
const username = email.local.split('.')[0]; // "ivan"

Граватар

Получение аватара из Gravatar

import md5 from 'md5';

const record = await emd.database.collection('users').get(recordId);
const hash = md5(record.email.address.toLowerCase().trim());
const gravatarUrl = `https://www.gravatar.com/avatar/${hash}?s=200&d=identicon`;

Конфиденциальность

Скрытие части email

function maskEmail(email) {
const [local, domain] = email.split('@');
const maskedLocal = local[0] + '***' + local[local.length - 1];
return `${maskedLocal}@${domain}`;
}

// ivan@example.com -> i***n@example.com

Показ только домена

const record = await emd.database.collection('users').get(recordId);

if (currentUser.id === record.id || currentUser.isAdmin) {
return record.email.address;
} else {
return `***@${record.email.domain}`;
}

Проверка одноразовых email

const disposableEmailDomains = [
'tempmail.com',
'10minutemail.com',
'guerrillamail.com'
];

function isDisposableEmail(email) {
return disposableEmailDomains.includes(email.domain);
}

// При создании пользователя
const record = await emd.database.collection('users').create({
email: userEmail
});

if (isDisposableEmail(record.email)) {
throw new Error('Disposable email addresses are not allowed');
}

Рекомендации

  • Всегда используйте уникальность для основного email пользователя
  • Включайте нормализацию для предотвращения дубликатов
  • Реализуйте верификацию email для подтверждения владения
  • Используйте валидацию формата на клиенте и сервере
  • Храните статус верификации в отдельном поле
  • Не показывайте полный email публично (маскируйте)
  • Проверяйте одноразовые email, если это критично
  • Используйте HTTPS для передачи email

Интеграция с сервисами

Проверка email через API

const response = await fetch(`https://api.emailverification.com/verify?email=${email}`);
const data = await response.json();

if (!data.valid) {
throw new Error('Invalid email address');
}

Подписка на рассылку (Mailchimp, SendGrid)

await mailchimpService.subscribe({
email: record.email.address,
firstName: record.first_name,
lastName: record.last_name
});

Отличие от других типов

  • Email vs String: Email обеспечивает валидацию формата
  • Email vs Phone: Email для электронной почты, Phone для телефонов
  • Email vs URL: Email для адресов почты, URL для веб-ссылок