Телефон (Phone)
Поле типа Телефон предназначено для хранения телефонных номеров с автоматической валидацией и форматированием.
Основные характеристики
- Тип данных: Строка с валидацией телефонного номера
- Формат хранения: E.164 (международный формат)
- Автоматическое форматирование: Да
- Валидация: Проверка корректности номера
- Определение страны: Автоматическое определение кода страны
Форматы отображения
Телефонные номера могут отображаться в различных форматах:
- Международный: +7 (999) 123-45-67
- Национальный: 8 (999) 123-45-67
- E.164: +79991234567
- RFC3966: tel:+7-999-123-45-67
Настройки поля
При создании поля типа "Телефон" доступны следующие настройки:
- Название поля: Отображаемое имя поля
- Системное имя: Уникальный идентификатор для API
- Описание: Подсказка для пользователей
- Обязательное поле: Требовать заполнения
- Уникальное значение: Запретить дублирование номеров
- Страна по умолчанию: Код страны для автоподстановки
- Формат отображения: Выбор формата из списка
- Разрешенные страны: Ограничение по странам (опционально)
Примеры использования
Телефон пользователя
{
"name": "phone",
"type": "phone",
"required": true,
"unique": true,
"defaultCountry": "RU"
}
Рабочий телефон
{
"name": "work_phone",
"type": "phone",
"defaultCountry": "RU"
}
Мобильный телефон
{
"name": "mobile",
"type": "phone",
"required": true,
"allowedCountries": ["RU", "BY", "KZ", "UA"]
}
Работа через API
Создание записи
// Различные форматы ввода (все будут нормализованы)
const record = await emd.database.collection('users').create({
name: 'Иван Иванов',
phone: '+79991234567'
});
// Или
const record = await emd.database.collection('users').create({
name: 'Иван Иванов',
phone: '8 (999) 123-45-67'
});
// Или
const record = await emd.database.collection('users').create({
name: 'Иван Иванов',
phone: '9991234567' // Будет добавлен код страны по умолчанию
});
Получение номера
const record = await emd.database.collection('users').get(recordId);
console.log(record.phone);
// {
// raw: "+79991234567",
// formatted: "+7 (999) 123-45-67",
// national: "8 (999) 123-45-67",
// international: "+7 (999) 123-45-67",
// e164: "+79991234567",
// country: "RU",
// countryCode: "+7",
// nationalNumber: "9991234567"
// }
Поиск по номеру телефона
// Точное совпадение (формат не важен)
const users = await emd.database.collection('users').find({
phone: '+79991234567'
});
// Или
const users = await emd.database.collection('users').find({
phone: '8 (999) 123-45-67'
});
// Поиск по части номера
const users = await emd.database.collection('users').find({
phone: { $contains: '9991234' }
});
Обновление номера
await emd.database.collection('users').update(recordId, {
phone: '+79991234567'
});
Валидация
Автоматическая валидация
При сохранении номер автоматически проверяется на корректность:
try {
await emd.database.collection('users').create({
name: 'Иван',
phone: '123' // Некорректный номер
});
} catch (error) {
console.error(error.message); // "Invalid phone number"
}
Проверка уникальности
try {
await emd.database.collection('users').create({
name: 'Петр',
phone: '+79991234567' // Номер уже существует
});
} catch (error) {
console.error(error.message); // "Phone number already exists"
}
Форматирование
Получение в разных форматах
const record = await emd.database.collection('users').get(recordId);
const phone = record.phone;
// Для отображения пользователю
const displayPhone = phone.formatted; // "+7 (999) 123-45-67"
// Для ссылки tel:
const telLink = phone.e164; // "+79991234567"
// Для SMS API
const smsNumber = phone.e164; // "+79991234567"
// Национальный формат
const nationalPhone = phone.national; // "8 (999) 123-45-67"
Использование в HTML
const record = await emd.database.collection('users').get(recordId);
// Кликабельная ссылка
const phoneLink = `<a href="tel:${record.phone.e164}">${record.phone.formatted}</a>`;
Интеграция с телефонией
Отправка SMS
const record = await emd.database.collection('users').get(recordId);
await smsService.send({
to: record.phone.e164,
message: 'Ваш код подтверждения: 1234'
});
Звонок через VoIP
const record = await emd.database.collection('users').get(recordId);
await voipService.call({
to: record.phone.e164,
from: '+74951234567'
});
WhatsApp
const record = await emd.database.collection('users').get(recordId);
// Ссылка на WhatsApp
const whatsappUrl = `https://wa.me/${record.phone.e164.replace('+', '')}`;
Определение страны
const record = await emd.database.collection('users').get(recordId);
console.log(record.phone.country); // "RU"
console.log(record.phone.countryCode); // "+7"
// Получить название страны
const countryName = getCountryName(record.phone.country); // "Россия"
Маска ввода
В интерфейсе автоматически применяется маска ввода в зависимости от страны:
- Россия: +7 (__) --
- США: +1 (__) -
- Великобритания: +44 __ ____ ____
Операторы для телефонных полей
$eq— равно (формат не важен)$ne— не равно$contains— содержит (поиск по части номера)$in— входит в список номеров$exists— проверка наличия значения
Примеры запросов
Найти пользователей из России
const users = await emd.database.collection('users').find({
'phone.country': 'RU'
});
Найти номера с определенным кодом оператора
const users = await emd.database.collection('users').find({
'phone.nationalNumber': { $startsWith: '999' }
});
Верификация номера
Отправка кода подтверждения
// Создать код верификации
const code = Math.floor(100000 + Math.random() * 900000);
await emd.database.collection('verification_codes').create({
phone: record.phone.e164,
code: code,
expiresAt: new Date(Date.now() + 10 * 60 * 1000) // 10 минут
});
// Отправить SMS
await smsService.send({
to: record.phone.e164,
message: `Ваш код подтверждения: ${code}`
});
Проверка кода
const verification = await emd.database.collection('verification_codes').findOne({
phone: phoneNumber,
code: userCode,
expiresAt: { $gt: new Date() }
});
if (verification) {
await emd.database.collection('users').update(userId, {
phone_verified: true
});
}
Рекомендации
- Используйте уникальность для основных телефонов пользователей
- Храните номера в формате E.164 для совместимости
- Используйте валидацию для предотвращения ошибок ввода
- Добавляйте верификацию для подтверждения владения номером
- Учитывайте международные номера, если работаете с разными странами
- Используйте маску ввода для удобства пользователей
- Для отображения используйте локализованный формат
Конфиденциальность
Скрытие части номера
function maskPhone(phone) {
const formatted = phone.formatted;
return formatted.replace(/\d(?=\d{4})/g, '*');
}
// +7 (***) ***-45-67
Ограничение доступа
// Показывать полный номер только владельцу
const record = await emd.database.collection('users').get(recordId);
if (currentUser.id === record.id || currentUser.isAdmin) {
return record.phone.formatted;
} else {
return maskPhone(record.phone);
}
Отличие от других типов
- Phone vs String: Phone обеспечивает валидацию и форматирование
- Phone vs Number: Phone для телефонных номеров, Number для чисел
- Phone vs Email: Phone для телефонов, Email для электронной почты