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

Телефон (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 для электронной почты