Feature/documents pages (#118)
* apps/web: add generic privacy & offer pages * Update environment variables and enhance offer and privacy pages - Added `OFFER_URL` and `SUPPORT_TELEGRAM_URL` to environment variable configuration for better flexibility. - Updated the offer page to dynamically link to the offer URL and improved contact information presentation with a direct link to the support Telegram. - Revised the privacy policy page to reflect the service name and updated contact details, ensuring clarity and consistency in communication. * move offer & privacy -> (documents) sub directory * Update offer and privacy pages to include user consent for third-party data sharing - Added a clause in the offer page requiring users to ensure consent from third parties when adding their contact information. - Updated the privacy policy to clarify that users can share third-party data, emphasizing the need for consent for data processing within the service. * Add privacy agreement and update environment variables - Introduced `PRIVACY_URL` to the environment configuration for dynamic linking. - Updated localization files to include a user consent agreement for sharing phone numbers, linking to the offer and privacy URLs. - Enhanced welcome and contact addition messages to incorporate the new consent clause, improving user clarity on data handling. * Refactor phone agreement localization and enhance user consent messaging - Updated the Russian localization file to streamline the phone sharing agreement, improving clarity on user consent for data processing. - Modified the contact addition and welcome messages to incorporate the new agreement format, ensuring users are informed about their consent to share personal data. * Enhance Russian localization and update message formatting - Added a new payment agreement clause in the Russian localization file, clarifying user consent for payments. - Updated message formatting in the contact addition and subscription processes to support HTML parsing, improving message presentation and user experience. - Incorporated the new payment agreement into the subscription flow, ensuring users are informed about their consent to the terms. * Refactor Russian localization for contact agreements and enhance user consent messaging - Updated the Russian localization file to separate and clarify the phone sharing and contact sharing agreements, improving user understanding of consent requirements. - Modified the contact addition and welcome messages to utilize the new agreement format, ensuring users are informed about their consent to share personal data in a more structured manner. * Enhance Russian localization and add document handling features - Updated the Russian localization file to include new entries for privacy policy and public offer documents, improving user access to important information. - Added 'documents' command to the bot's command list, allowing users to easily access document-related features. - Integrated document handling in the main menu and handlers, enhancing user experience and navigation within the bot.
This commit is contained in:
parent
458a06a620
commit
0b64d8086c
@ -45,6 +45,8 @@ commands-list =
|
||||
Откройте приложение кнопкой "Открыть", чтобы отредактировать свой профиль или создать запись
|
||||
support =
|
||||
{ -support-contact }
|
||||
documents =
|
||||
.description = Документы
|
||||
|
||||
# Кнопки
|
||||
btn-add-contact = 👤 Добавить контакт
|
||||
@ -53,9 +55,26 @@ btn-pro = 👑 Pro доступ
|
||||
btn-subscribe = 👑 Приобрести Pro
|
||||
btn-pro-info = ℹ️ Мой Pro доступ
|
||||
btn-open-app = 📱 Открыть приложение
|
||||
btn-documents = 📋 Документы
|
||||
btn-back = ◀️ Назад
|
||||
|
||||
|
||||
# Согласие
|
||||
share-phone-agreement =
|
||||
<i> Нажимая кнопку <b>«Отправить номер телефона»</b></i>,
|
||||
<i>вы:
|
||||
- соглашаетесь с <a href='{ $offerUrl }'>Публичной офертой</a>
|
||||
- подтверждаете согласие на обработку персональных данных согласно <a href='{ $privacyUrl }'>Политике конфиденциальности</a></i>
|
||||
share-contact-agreement =
|
||||
<i> Отправляя контакт, имя и номер телефона, вы подтверждаете, что имеете согласие этого человека на передачу его контактных данных и на их обработку в рамках нашего сервиса.
|
||||
(Пункт 4.5 <a href='{ $privacyUrl }'>Политики конфиденциальности</a>)</i>
|
||||
payment-agreement =
|
||||
Совершая оплату, вы соглашаетесь с <a href='{ $offerUrl }'>Публичной офертой</a>
|
||||
agreement-links =
|
||||
<a href='{ $offerUrl }'>Публичная оферта</a>
|
||||
<a href='{ $privacyUrl }'>Политика конфиденциальности</a>
|
||||
|
||||
|
||||
# Приветственные сообщения
|
||||
msg-welcome =
|
||||
👋 Добро пожаловать!
|
||||
@ -64,14 +83,14 @@ msg-welcome-back = 👋 С возвращением, { $name }!
|
||||
|
||||
|
||||
# Сообщения о телефоне
|
||||
msg-need-phone = 📱 Чтобы добавить контакт, сначала поделитесь своим номером телефона
|
||||
msg-need-phone = 📱 Чтобы добавить контакт, сначала поделитесь своим номером телефона.
|
||||
msg-phone-saved =
|
||||
✅ Спасибо! Мы сохранили ваш номер телефона
|
||||
Теперь вы можете открыть приложение или воспользоваться командами бота
|
||||
msg-already-registered =
|
||||
✅ Вы уже зарегистрированы в системе
|
||||
|
||||
Для смены номера телефона обратитесь в поддержку (Контакты в профиле бота)
|
||||
<i>Для смены номера телефона обратитесь в поддержку (Контакты в профиле бота)</i>
|
||||
msg-invalid-phone = ❌ Некорректный номер телефона. Пример: +79999999999
|
||||
|
||||
# Сообщения о контактах
|
||||
@ -85,7 +104,7 @@ msg-contact-added =
|
||||
✅ Добавили { $fullname } в список ваших контактов
|
||||
|
||||
Пригласите пользователя в приложение, чтобы вы могли добавлять с ним записи
|
||||
msg-contact-forward = Перешлите пользователю следующее сообщение, чтобы он мог начать пользоваться ботом ⬇️
|
||||
msg-contact-forward = <i>Перешлите пользователю следующее сообщение, чтобы он мог начать пользоваться ботом ⬇️</i>
|
||||
|
||||
# Сообщения для шаринга
|
||||
msg-share-bot =
|
||||
@ -96,7 +115,7 @@ msg-share-bot =
|
||||
# Системные сообщения
|
||||
msg-cancel = ❌ Операция отменена
|
||||
msg-unhandled = ❓ Неизвестная команда. Попробуйте /start
|
||||
msg-cancel-operation = Для отмены операции используйте команду /cancel
|
||||
msg-cancel-operation = <i>Для отмены операции используйте команду /cancel</i>
|
||||
|
||||
# Ошибки
|
||||
err-generic = ⚠️ Что-то пошло не так. Попробуйте еще раз через несколько секунд
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* eslint-disable sonarjs/cognitive-complexity */
|
||||
/* eslint-disable id-length */
|
||||
import { type Context } from '@/bot/context';
|
||||
import { env } from '@/config/env';
|
||||
import { KEYBOARD_SHARE_BOT, KEYBOARD_SHARE_PHONE } from '@/config/keyboards';
|
||||
import { parseContact } from '@/utils/contact';
|
||||
import { combine } from '@/utils/messages';
|
||||
@ -21,16 +22,34 @@ export async function addContact(conversation: Conversation<Context, Context>, c
|
||||
|
||||
if (!customer) {
|
||||
return ctx.reply(
|
||||
await conversation.external(({ t }) => t('msg-need-phone')),
|
||||
KEYBOARD_SHARE_PHONE,
|
||||
await conversation.external(({ t }) =>
|
||||
combine(
|
||||
t('msg-need-phone'),
|
||||
t('share-phone-agreement', {
|
||||
offerUrl: env.OFFER_URL,
|
||||
privacyUrl: env.PRIVACY_URL,
|
||||
}),
|
||||
),
|
||||
),
|
||||
{ ...KEYBOARD_SHARE_PHONE, parse_mode: 'HTML' },
|
||||
);
|
||||
}
|
||||
|
||||
// Просим отправить контакт или номер телефона
|
||||
await ctx.reply(
|
||||
await conversation.external(({ t }) =>
|
||||
combine(t('msg-send-client-contact-or-phone'), t('msg-cancel-operation')),
|
||||
combine(
|
||||
t('msg-send-client-contact-or-phone'),
|
||||
t('msg-cancel-operation'),
|
||||
t('share-contact-agreement', {
|
||||
offerUrl: env.OFFER_URL,
|
||||
privacyUrl: env.PRIVACY_URL,
|
||||
}),
|
||||
),
|
||||
),
|
||||
{
|
||||
parse_mode: 'HTML',
|
||||
},
|
||||
);
|
||||
|
||||
// Ждём первое сообщение: контакт или текст с номером
|
||||
|
||||
@ -66,7 +66,7 @@ export async function subscription(conversation: Conversation<Context, Context>,
|
||||
return combine(statusLine, fmt`${i}${t('msg-cancel-operation')}${i}`.text);
|
||||
}),
|
||||
),
|
||||
{ reply_markup: keyboard },
|
||||
{ parse_mode: 'HTML', reply_markup: keyboard },
|
||||
);
|
||||
|
||||
// ждём выбора
|
||||
@ -95,6 +95,18 @@ export async function subscription(conversation: Conversation<Context, Context>,
|
||||
month: '2-digit',
|
||||
year: 'numeric',
|
||||
});
|
||||
|
||||
const agreementText = await conversation.external(({ t }) => {
|
||||
return t('payment-agreement', {
|
||||
offerUrl: env.OFFER_URL,
|
||||
privacyUrl: env.PRIVACY_URL,
|
||||
});
|
||||
});
|
||||
|
||||
await ctx.reply(agreementText, {
|
||||
parse_mode: 'HTML',
|
||||
});
|
||||
|
||||
return ctx.replyWithInvoice(
|
||||
'Оплата Pro доступа',
|
||||
combine(
|
||||
@ -110,6 +122,7 @@ export async function subscription(conversation: Conversation<Context, Context>,
|
||||
},
|
||||
],
|
||||
{
|
||||
protect_content: true,
|
||||
provider_token: env.BOT_PROVIDER_TOKEN,
|
||||
start_parameter: 'get_access',
|
||||
},
|
||||
|
||||
12
apps/bot/src/bot/features/documents.ts
Normal file
12
apps/bot/src/bot/features/documents.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { handleDocuments } from '../handlers/documents';
|
||||
import { type Context } from '@/bot/context';
|
||||
import { logHandle } from '@/bot/helpers/logging';
|
||||
import { Composer } from 'grammy';
|
||||
|
||||
const composer = new Composer<Context>();
|
||||
|
||||
const feature = composer.chatType('private');
|
||||
|
||||
feature.command('documents', logHandle('command-documents'), handleDocuments);
|
||||
|
||||
export { composer as documents };
|
||||
@ -1,4 +1,5 @@
|
||||
export * from './add-contact';
|
||||
export * from './documents';
|
||||
export * from './help';
|
||||
export * from './pro';
|
||||
export * from './registration';
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import { type Context } from '@/bot/context';
|
||||
import { logHandle } from '@/bot/helpers/logging';
|
||||
import { env } from '@/config/env';
|
||||
import { KEYBOARD_SHARE_PHONE, mainMenu } from '@/config/keyboards';
|
||||
import { combine } from '@/utils/messages';
|
||||
import { RegistrationService } from '@repo/graphql/api/registration';
|
||||
import { Composer } from 'grammy';
|
||||
|
||||
@ -22,7 +24,19 @@ feature.command('start', logHandle('command-start'), async (ctx) => {
|
||||
}
|
||||
|
||||
// Новый пользователь — просим поделиться номером
|
||||
return ctx.reply(ctx.t('msg-welcome'), { ...KEYBOARD_SHARE_PHONE, parse_mode: 'HTML' });
|
||||
return ctx.reply(
|
||||
combine(
|
||||
ctx.t('msg-welcome'),
|
||||
ctx.t('share-phone-agreement', {
|
||||
offerUrl: env.OFFER_URL,
|
||||
privacyUrl: env.PRIVACY_URL,
|
||||
}),
|
||||
),
|
||||
{
|
||||
...KEYBOARD_SHARE_PHONE,
|
||||
parse_mode: 'HTML',
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
export { composer as welcome };
|
||||
|
||||
18
apps/bot/src/bot/handlers/documents.ts
Normal file
18
apps/bot/src/bot/handlers/documents.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { type Context } from '@/bot/context';
|
||||
import { env } from '@/config/env';
|
||||
import { KEYBOARD_REMOVE } from '@/config/keyboards';
|
||||
|
||||
async function handler(ctx: Context) {
|
||||
await ctx.reply(
|
||||
ctx.t('agreement-links', {
|
||||
offerUrl: env.OFFER_URL,
|
||||
privacyUrl: env.PRIVACY_URL,
|
||||
}),
|
||||
{
|
||||
...KEYBOARD_REMOVE,
|
||||
parse_mode: 'HTML',
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export { handler as handleDocuments };
|
||||
@ -1,4 +1,5 @@
|
||||
export * from './add-contact';
|
||||
export * from './documents';
|
||||
export * from './pro';
|
||||
export * from './share-bot';
|
||||
export * from './subscription';
|
||||
|
||||
@ -5,7 +5,15 @@ import { type LanguageCode } from '@grammyjs/types';
|
||||
import { type Api, type Bot, type RawApi } from 'grammy';
|
||||
|
||||
export async function setCommands({ api }: Bot<Context, Api<RawApi>>) {
|
||||
const commands = createCommands(['start', 'addcontact', 'sharebot', 'help', 'subscribe', 'pro']);
|
||||
const commands = createCommands([
|
||||
'start',
|
||||
'addcontact',
|
||||
'sharebot',
|
||||
'help',
|
||||
'subscribe',
|
||||
'pro',
|
||||
'documents',
|
||||
]);
|
||||
|
||||
for (const command of commands) {
|
||||
addLocalizations(command);
|
||||
|
||||
@ -4,6 +4,8 @@ export const envSchema = z.object({
|
||||
BOT_PROVIDER_TOKEN: z.string(),
|
||||
BOT_TOKEN: z.string(),
|
||||
BOT_URL: z.string(),
|
||||
OFFER_URL: z.string(),
|
||||
PRIVACY_URL: z.string(),
|
||||
RATE_LIMIT: z
|
||||
.string()
|
||||
.transform((value) => Number.parseInt(value, 10))
|
||||
|
||||
@ -1,6 +1,12 @@
|
||||
import { env } from './env';
|
||||
import { type Context } from '@/bot/context';
|
||||
import { handleAddContact, handlePro, handleShareBot, handleSubscribe } from '@/bot/handlers';
|
||||
import {
|
||||
handleAddContact,
|
||||
handleDocuments,
|
||||
handlePro,
|
||||
handleShareBot,
|
||||
handleSubscribe,
|
||||
} from '@/bot/handlers';
|
||||
import { Menu } from '@grammyjs/menu';
|
||||
import {
|
||||
type InlineKeyboardMarkup,
|
||||
@ -50,6 +56,8 @@ export const mainMenu = new Menu<Context>('main-menu', { autoAnswer: true })
|
||||
.row()
|
||||
.text((ctx) => ctx.t('btn-share-bot'), handleShareBot)
|
||||
.row()
|
||||
.text((ctx) => ctx.t('btn-documents'), handleDocuments)
|
||||
.row()
|
||||
.url(
|
||||
(ctx) => ctx.t('btn-open-app'),
|
||||
() => {
|
||||
|
||||
242
apps/web/app/(documents)/offer/page.tsx
Normal file
242
apps/web/app/(documents)/offer/page.tsx
Normal file
@ -0,0 +1,242 @@
|
||||
import { Container } from '@/components/layout';
|
||||
import { PageHeader } from '@/components/navigation';
|
||||
import { env } from '@/config/env';
|
||||
|
||||
export default function OfferPage() {
|
||||
return (
|
||||
<>
|
||||
<PageHeader title="Публичная оферта" />
|
||||
<Container className="prose prose-neutral dark:prose-invert">
|
||||
<section className="mx-auto space-y-8">
|
||||
<h1 className="text-2xl font-bold">
|
||||
Договор-оферта на использование сервиса «Запишись.онлайн» (@zapishis_online_bot)
|
||||
</h1>
|
||||
<p className="mt-4">
|
||||
Настоящий документ является публичной офертой в соответствии с пунктом 2 статьи 437
|
||||
Гражданского кодекса Российской Федерации и представляет собой предложение
|
||||
индивидуального предпринимателя (самозанятого) — далее именуемого «Администрация»,
|
||||
заключить Договор на использование Сервиса (далее – «Договор», «Оферта») с любым
|
||||
физическим лицом, принявшим условия настоящей Оферты (далее – «Пользователь»).
|
||||
</p>
|
||||
|
||||
<div className="my-6 border-t border-gray-300 dark:border-gray-600" />
|
||||
|
||||
<h2 className="text-2xl font-semibold">1. Термины и определения</h2>
|
||||
<div className="space-y-3">
|
||||
<p>
|
||||
<strong>1.1.</strong> Оферта — настоящий документ, постоянно размещенный в сети
|
||||
Интернет по адресу <a href="#">{env.OFFER_URL}</a>.
|
||||
</p>
|
||||
<p>
|
||||
<strong>1.2.</strong> Акцепт — полное и безоговорочное принятие условий Оферты
|
||||
Пользователем путем оплаты доступа через встроенный платежный бот ЮKassa в Telegram.
|
||||
</p>
|
||||
<p>
|
||||
<strong>1.3.</strong> Сервис — Telegram-бот и мини-приложение, позволяющее
|
||||
пользователям создавать и принимать заказы, управлять расписанием и взаимодействовать
|
||||
друг с другом без необходимости регистрации.
|
||||
</p>
|
||||
<p>
|
||||
<strong>1.4.</strong> Администрация — самозанятое лицо, являющееся разработчиком и
|
||||
правообладателем Сервиса.
|
||||
</p>
|
||||
<p>
|
||||
<strong>1.5.</strong> Пользователь — любое физическое лицо, использующее Сервис в
|
||||
личных или профессиональных целях.
|
||||
</p>
|
||||
<p>
|
||||
<strong>1.6.</strong> Доступ — право использования функционала Сервиса на определённый
|
||||
оплаченный период (например, неделя, месяц, год).
|
||||
</p>
|
||||
<p>
|
||||
<strong>1.7.</strong> Оплата — денежные средства, перечисленные Пользователем через
|
||||
платёжный бот ЮKassa в Telegram.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="my-6 border-t border-gray-300 dark:border-gray-600" />
|
||||
|
||||
<h2 className="text-2xl font-semibold">2. Акцепт оферты и заключение договора</h2>
|
||||
<div className="space-y-3">
|
||||
<p>
|
||||
<strong>2.1.</strong> Акцептом настоящей Оферты считается оплата Пользователем доступа
|
||||
к Сервису любым доступным способом.
|
||||
</p>
|
||||
<p>
|
||||
<strong>2.2.</strong> С момента совершения оплаты Пользователь считается заключившим
|
||||
Договор с Администрацией на условиях, изложенных в настоящей Оферте.
|
||||
</p>
|
||||
<p>
|
||||
<strong>2.3.</strong> Пользователь подтверждает, что ему понятны все условия настоящей
|
||||
Оферты и он принимает их без ограничений.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="my-6 border-t border-gray-300 dark:border-gray-600" />
|
||||
|
||||
<h2 className="text-2xl font-semibold">3. Предмет договора</h2>
|
||||
<div className="space-y-3">
|
||||
<p>
|
||||
<strong>3.1.</strong> Администрация предоставляет Пользователю неисключительное право
|
||||
(доступ) на использование функционала Сервиса в пределах оплаченного периода времени.
|
||||
</p>
|
||||
<p>
|
||||
<strong>3.2.</strong> Сервис предоставляется в онлайн-формате через Telegram-бота без
|
||||
установки дополнительного программного обеспечения.
|
||||
</p>
|
||||
<p>
|
||||
<strong>3.3.</strong> Пользователь получает право использовать функционал Сервиса в
|
||||
личных целях, в том числе для организации и планирования заказов, встреч и тренировок.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="my-6 border-t border-gray-300 dark:border-gray-600" />
|
||||
|
||||
<h2 className="text-2xl font-semibold">4. Порядок оплаты и использование</h2>
|
||||
<div className="space-y-3">
|
||||
<p>
|
||||
<strong>4.1.</strong> Оплата производится через встроенные инструменты Telegram-бота с
|
||||
использованием платёжной системы ЮKassa.
|
||||
</p>
|
||||
<p>
|
||||
<strong>4.2.</strong> Комиссия платёжной системы включена в итоговую стоимость.
|
||||
Администрация не взимает дополнительных платежей.
|
||||
</p>
|
||||
<p>
|
||||
<strong>4.3.</strong> Доступ активируется автоматически после успешного подтверждения
|
||||
оплаты.
|
||||
</p>
|
||||
<p>
|
||||
<strong>4.4.</strong> Пользователь может продлить доступ путём повторной оплаты.
|
||||
Автоматическое продление не применяется.
|
||||
</p>
|
||||
<p>
|
||||
<strong>4.5.</strong> Возврат денежных средств возможен только в случае технических
|
||||
ошибок, по письменному обращению на адрес поддержки.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="my-6 border-t border-gray-300 dark:border-gray-600" />
|
||||
|
||||
<h2 className="text-2xl font-semibold">5. Права и обязанности сторон</h2>
|
||||
<div className="space-y-3">
|
||||
<p>
|
||||
<strong>5.1.</strong> Пользователь обязуется:
|
||||
</p>
|
||||
<ul className="list-inside list-disc space-y-1">
|
||||
<li>не использовать Сервис в противоправных целях;</li>
|
||||
<li>
|
||||
не вмешиваться в работу Сервиса и не предпринимать действий, направленных на
|
||||
нарушение его функционирования;
|
||||
</li>
|
||||
<li>предоставлять достоверную информацию при оплате и использовании Сервиса.</li>
|
||||
<li>
|
||||
при добавлении контактов других лиц (например, клиентов, мастеров) гарантировать,
|
||||
что у него есть согласие этих лиц на передачу и обработку их персональных данных в
|
||||
рамках Сервиса.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
<strong>5.2.</strong> Администрация обязуется:
|
||||
</p>
|
||||
<ul className="list-inside list-disc space-y-1">
|
||||
<li>
|
||||
обеспечивать бесперебойную работу Сервиса, за исключением периодов технического
|
||||
обслуживания;
|
||||
</li>
|
||||
<li>
|
||||
обрабатывать персональные данные Пользователей в соответствии с{' '}
|
||||
<a href="/privacy">Политикой конфиденциальности</a>;
|
||||
</li>
|
||||
<li>принимать обращения и запросы Пользователей по вопросам работы Сервиса.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="my-6 border-t border-gray-300 dark:border-gray-600" />
|
||||
|
||||
<h2 className="text-2xl font-semibold">6. Ответственность сторон</h2>
|
||||
<div className="space-y-3">
|
||||
<p>
|
||||
<strong>6.1.</strong> Сервис предоставляется «как есть». Администрация не несёт
|
||||
ответственности за временные сбои, потерю данных или недоступность Сервиса, возникшие
|
||||
по причинам, не зависящим от неё.
|
||||
</p>
|
||||
<p>
|
||||
<strong>6.2.</strong> Пользователь несёт полную ответственность за корректность
|
||||
совершаемых платежей и действий, совершаемых через свой Telegram-аккаунт.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="my-6 border-t border-gray-300 dark:border-gray-600" />
|
||||
|
||||
<h2 className="text-2xl font-semibold">7. Обработка персональных данных</h2>
|
||||
<div className="space-y-3">
|
||||
<p>
|
||||
<strong>7.1.</strong> Администрация обрабатывает персональные данные Пользователя в
|
||||
соответствии с Федеральным законом №152-ФЗ «О персональных данных» и{' '}
|
||||
<a href="/privacy">Политикой конфиденциальности</a>.
|
||||
</p>
|
||||
<p>
|
||||
<strong>7.2.</strong> Использование Сервиса означает согласие Пользователя на
|
||||
обработку его персональных данных.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="my-6 border-t border-gray-300 dark:border-gray-600" />
|
||||
|
||||
<h2 className="text-2xl font-semibold">8. Срок действия и расторжение договора</h2>
|
||||
<div className="space-y-3">
|
||||
<p>
|
||||
<strong>8.1.</strong> Договор вступает в силу с момента оплаты доступа и действует в
|
||||
течение оплаченного периода.
|
||||
</p>
|
||||
<p>
|
||||
<strong>8.2.</strong> Пользователь может прекратить использование Сервиса в любое
|
||||
время без возврата оплаченных средств.
|
||||
</p>
|
||||
<p>
|
||||
<strong>8.3.</strong> Администрация вправе приостановить доступ в случае нарушения
|
||||
Пользователем условий настоящей Оферты.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="my-6 border-t border-gray-300 dark:border-gray-600" />
|
||||
|
||||
<h2 className="text-2xl font-semibold">9. Заключительные положения</h2>
|
||||
<div className="space-y-3">
|
||||
<p>
|
||||
<strong>9.1.</strong> Настоящий Договор регулируется законодательством Российской
|
||||
Федерации.
|
||||
</p>
|
||||
<p>
|
||||
<strong>9.2.</strong> Все споры и разногласия решаются путём переговоров, а при
|
||||
недостижении соглашения — в судебном порядке по месту нахождения Администрации.
|
||||
</p>
|
||||
<p>
|
||||
<strong>9.3.</strong> Администрация оставляет за собой право изменять условия Оферты с
|
||||
размещением новой редакции на сайте.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="my-6 border-t border-gray-300 dark:border-gray-600" />
|
||||
|
||||
<h2 className="text-2xl font-semibold">10. Контакты</h2>
|
||||
<p>
|
||||
Если у Вас есть вопросы по настоящему договору публичной оферты персональных данных,
|
||||
пожалуйста, свяжитесь с Разработчиком:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
Telegram:{' '}
|
||||
<strong>
|
||||
<a href={env.SUPPORT_TELEGRAM_URL}>{env.SUPPORT_TELEGRAM_URL}</a>
|
||||
</strong>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div className="h-10" />
|
||||
</section>
|
||||
</Container>
|
||||
</>
|
||||
);
|
||||
}
|
||||
266
apps/web/app/(documents)/privacy/page.tsx
Normal file
266
apps/web/app/(documents)/privacy/page.tsx
Normal file
@ -0,0 +1,266 @@
|
||||
import { Container } from '@/components/layout';
|
||||
import { PageHeader } from '@/components/navigation';
|
||||
import { env } from '@/config/env';
|
||||
|
||||
export default function PrivacyPolicyPage() {
|
||||
return (
|
||||
<>
|
||||
<PageHeader title="Политика конфиденциальности" />
|
||||
<Container className="prose prose-neutral md:prose-lg dark:prose-invert max-w-none">
|
||||
<h1 className="text-2xl font-bold">
|
||||
Политика конфиденциальности бота / мини-приложения «Запишись.онлайн»
|
||||
(@zapishis_online_bot)
|
||||
</h1>
|
||||
|
||||
<h2 className="text-2xl font-semibold">1. Термины и определения</h2>
|
||||
<ol>
|
||||
<li>
|
||||
<strong>Telegram</strong> – Telegram Messenger Inc. (платформа, на которой работает бот
|
||||
и мини-приложение).
|
||||
</li>
|
||||
<li>
|
||||
<strong>Платформа</strong> – экосистема ботов и мини-приложений Telegram.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Разработчик</strong> – физическое лицо, самозанятый, владелец и оператор сервиса
|
||||
«Запишись.онлайн» (@zapishis_online_bot) (далее — «Разработчик»).
|
||||
</li>
|
||||
<li>
|
||||
<strong>Сторонний сервис</strong> – бот/мини-приложение Разработчика, предоставляемое в
|
||||
Платформе.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Пользователь</strong> – лицо, использующее Сторонний сервис через свою учетную
|
||||
запись Telegram (далее — «Вы»).
|
||||
</li>
|
||||
<li>
|
||||
<strong>Политика</strong> – настоящий документ, регулирующий отношения между
|
||||
Разработчиком и Пользователем в части сбора и обработки персональных данных.
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<h2 className="text-2xl font-semibold">2. Общие положения</h2>
|
||||
<p>
|
||||
2.1. Настоящая Политика регулирует исключительно отношения между Разработчиком и
|
||||
Пользователем. Она не заменяет и не изменяет Политику конфиденциальности Telegram:{' '}
|
||||
<a href="https://telegram.org/privacy">https://telegram.org/privacy</a>.
|
||||
</p>
|
||||
<p>
|
||||
2.2. Разработчик соблюдает применимые требования платформы Telegram к конфиденциальности и
|
||||
защите данных.
|
||||
</p>
|
||||
<p>
|
||||
2.3. Использование Сервиса Пользователем и/или активация платного доступа означает
|
||||
согласие Пользователя с условиями настоящей Политики.
|
||||
</p>
|
||||
<p>2.4. Если Вы не согласны с условиями Политики — прекратите использование Сервиса.</p>
|
||||
|
||||
<h2 className="text-2xl font-semibold">3. Отказ от ответственности</h2>
|
||||
<p>
|
||||
3.1. Сторонний сервис является независимым приложением и не поддерживается, не одобряется
|
||||
и не аффилирован с Telegram (за исключением использования API и инфраструктуры Telegram).
|
||||
</p>
|
||||
<p>
|
||||
3.2. Разработчик вправе изменять настоящую Политику — изменения вступают в силу с момента
|
||||
их публикации. Вы обязаны самостоятельно отслеживать обновления.
|
||||
</p>
|
||||
<p>
|
||||
3.3. Используя Сервис, Вы подтверждаете, что ознакомлены и согласны с условиями
|
||||
использования Telegram для ботов и мини-приложений:{' '}
|
||||
<a href="https://telegram.org/tos/bots">https://telegram.org/tos/bots</a>,{' '}
|
||||
<a href="https://telegram.org/tos/mini-apps">https://telegram.org/tos/mini-apps</a>.
|
||||
</p>
|
||||
<p>
|
||||
3.4. Вы гарантируете, что используете Сервис в соответствии с действующим
|
||||
законодательством и обладаете правом взаимодействовать с ним (например, достигли возраста,
|
||||
необходимого для использования услуг).
|
||||
</p>
|
||||
<p>
|
||||
3.5. Вы обязуетесь предоставлять точную и актуальную информацию, если Сервис запрашивает
|
||||
её.
|
||||
</p>
|
||||
<p>
|
||||
3.6. Любая информация, которую Вы делаете общедоступной самостоятельно (через профиль
|
||||
Telegram, публичные сообщения и т.п.), может стать доступна другим пользователям и не
|
||||
подпадает под защиту настоящей Политики в части конфиденциальности этой общедоступной
|
||||
информации.
|
||||
</p>
|
||||
|
||||
<h2 className="text-2xl font-semibold">4. Сбор персональных данных</h2>
|
||||
<p>
|
||||
4.1. Telegram по умолчанию предоставляет сторонним сервисам ограниченный набор данных о
|
||||
Пользователе — подробнее:{' '}
|
||||
<a href="https://telegram.org/privacy#6-bot-messages">
|
||||
https://telegram.org/privacy#6-bot-messages
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
<p>
|
||||
4.2. Сторонний сервис может дополнительно получать данные, которые Вы передаёте в чате
|
||||
бота или в мини-приложении (например, контакт, телефон), если Вы явно их отправляете.
|
||||
</p>
|
||||
<p>
|
||||
4.3. В случае мини-приложения дополнительно могут передаваться данные в соответствии с
|
||||
правилами мини-приложений Telegram:{' '}
|
||||
<a href="https://telegram.org/tos/mini-apps#4-privacy">
|
||||
https://telegram.org/tos/mini-apps#4-privacy
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
<p>
|
||||
4.4. Сторонний сервис может собирать также анонимную статистику использования
|
||||
(диагностика, события взаимодействия), не связываемую напрямую с персоной.
|
||||
</p>
|
||||
<p>
|
||||
4.5. Пользователь может передавать данные третьих лиц (например, контактные данные
|
||||
клиентов или мастеров) для использования в Сервисе. При этом пользователь гарантирует, что
|
||||
эти лица дали согласие на обработку их персональных данных в рамках Сервиса.
|
||||
</p>
|
||||
|
||||
<h2 className="text-2xl font-semibold">5. Какие данные мы собираем и как используем</h2>
|
||||
<p>
|
||||
5.1. Разработчик запрашивает, собирает и обрабатывает только те данные, которые необходимы
|
||||
для корректной работы функций Сервиса, в частности:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Telegram ID и (опционально) отображаемое имя пользователя;</li>
|
||||
<li>телефон, только если Вы предоставили его добровольно (например, при регистрации);</li>
|
||||
<li>данные о заказах: дата/время, описание заказа, статус;</li>
|
||||
<li>
|
||||
информация о факте покупки Pro-доступа: период доступа, тип покупки (детали платёжной
|
||||
транзакции обрабатывает платёжный оператор — ЮKassa).
|
||||
</li>
|
||||
</ul>
|
||||
<p>5.2. Цели обработки:</p>
|
||||
<ul>
|
||||
<li>
|
||||
предоставление и поддержка работы Сервиса (создание заказов, напоминания, управление
|
||||
доступом);
|
||||
</li>
|
||||
<li>
|
||||
подтверждение и учет оплат (взаимодействие с платёжным оператором для актуализации
|
||||
статуса доступа);
|
||||
</li>
|
||||
<li>
|
||||
реализация реферальной программы (хранение связей «кто пригласил/кого пригласили»);
|
||||
</li>
|
||||
<li>анализ использования и улучшение сервиса;</li>
|
||||
<li>выполнение юридических обязательств (хранение информации о транзакциях и др.).</li>
|
||||
</ul>
|
||||
<p className="note">
|
||||
Важно: детальные платёжные данные (реквизиты карт и т.д.) не хранятся у Разработчика — их
|
||||
обрабатывает платёжный оператор (ЮKassa) и Telegram-платежный бот.
|
||||
</p>
|
||||
|
||||
<h2 className="text-2xl font-semibold">6. Передача данных третьим лицам</h2>
|
||||
<p>
|
||||
6.1. Разработчик не передаёт персональные данные третьим лицам, за исключением следующих
|
||||
случаев:
|
||||
</p>
|
||||
<ul>
|
||||
<li>платёжному оператору (ЮKassa) и связанным службам для обработки платежей;</li>
|
||||
<li>Telegram как платформе для функционирования бота и мини-приложения;</li>
|
||||
<li>
|
||||
в случае необходимости — исполнителям, оказывающим техническую поддержку, при условии
|
||||
подписания ими обязательств о конфиденциальности;
|
||||
</li>
|
||||
<li>если передача требуется по закону (запросы уполномоченных органов и т.п.).</li>
|
||||
</ul>
|
||||
<p>
|
||||
6.2. Разработчик не продаёт и не передаёт персональные данные для рекламных целей третьим
|
||||
лицам без Вашего отдельного согласия.
|
||||
</p>
|
||||
|
||||
<h2 className="text-2xl font-semibold">7. Защита и хранение данных</h2>
|
||||
<p>
|
||||
7.1. Разработчик применяет разумные технические и организационные меры для защиты
|
||||
персональных данных (использование надежного VPS, ограничения доступа, резервное
|
||||
копирование и т.п.).
|
||||
</p>
|
||||
<p>
|
||||
7.2. Доступ к персональным данным имеет только Разработчик (и/или доверенные исполнители
|
||||
технической поддержки при необходимости).
|
||||
</p>
|
||||
<p>
|
||||
7.3. Данные хранятся на серверах, указанных Разработчиком. Если используются внешние
|
||||
сервисы/облачные хранилища — это будет указано в соответствующих местах Политики или
|
||||
сообщения при сборе данных.
|
||||
</p>
|
||||
|
||||
<h2 className="text-2xl font-semibold">8. Права и обязанности сторон</h2>
|
||||
<p>8.1. Права Разработчика:</p>
|
||||
<ul>
|
||||
<li>вносить изменения в Политику с публикацией новой версии;</li>
|
||||
<li>ограничивать доступ к API/сервису при подозрении в злоупотреблениях;</li>
|
||||
<li>
|
||||
запросить подтверждение личности при необходимости обработки привилегированных запросов.
|
||||
</li>
|
||||
</ul>
|
||||
<p>8.2. Обязанности Разработчика:</p>
|
||||
<ul>
|
||||
<li>обеспечивать доступность Политики и исполнять её условия;</li>
|
||||
<li>
|
||||
обрабатывать законные запросы пользователей о доступе, изменении или удалении данных в
|
||||
разумные сроки (не позднее 30 дней, если иное не установлено законом);
|
||||
</li>
|
||||
<li>соблюдать применимое законодательство о защите персональных данных.</li>
|
||||
</ul>
|
||||
<p>8.3. Права Пользователя:</p>
|
||||
<ul>
|
||||
<li>запросить копию своих персональных данных, хранящихся у Разработчика;</li>
|
||||
<li>потребовать исправления неточных данных;</li>
|
||||
<li>
|
||||
потребовать удаления персональных данных в пределах, допустимых законом (с сохранением
|
||||
данных, необходимых для выполнения юридических обязательств, например, по учёту
|
||||
платежей);
|
||||
</li>
|
||||
<li>
|
||||
отозвать согласие на обработку персональных данных, если такое согласие предоставлялось
|
||||
добровольно;
|
||||
</li>
|
||||
<li>
|
||||
подать жалобу в уполномоченные органы по защите персональных данных, если считает, что
|
||||
его права нарушены.
|
||||
</li>
|
||||
</ul>
|
||||
<p>8.4. Обязанности Пользователя:</p>
|
||||
<ul>
|
||||
<li>предоставлять точную и актуальную информацию;</li>
|
||||
<li>не использовать Сервис в нарушении законодательства и условий Telegram.</li>
|
||||
</ul>
|
||||
|
||||
<h2 className="text-2xl font-semibold">9. Реклама и использование данных для аналитики</h2>
|
||||
<p>
|
||||
9.1. На текущем этапе Разработчик не использует персональные данные для демонстрации
|
||||
таргетированной рекламы третьих лиц без явного согласия Пользователя.
|
||||
</p>
|
||||
<p>
|
||||
9.2. Разработчик может собирать агрегированную (анонимную) статистику использования
|
||||
Сервиса для улучшения функционала.
|
||||
</p>
|
||||
|
||||
<h2 className="text-2xl font-semibold">10. Изменения Политики</h2>
|
||||
<p>
|
||||
10.1. Разработчик вправе вносить изменения в настоящую Политику. Все изменения публикуются
|
||||
на этой странице и вступают в силу с момента публикации.
|
||||
</p>
|
||||
|
||||
<h2 className="text-2xl font-semibold">11. Контакты</h2>
|
||||
<p>
|
||||
Если у Вас есть вопросы по Политике конфиденциальности или запросы в отношении
|
||||
персональных данных, пожалуйста, свяжитесь с Разработчиком:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
Telegram:{' '}
|
||||
<strong>
|
||||
<a href={env.SUPPORT_TELEGRAM_URL}>{env.SUPPORT_TELEGRAM_URL}</a>
|
||||
</strong>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div className="h-10" />
|
||||
</Container>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@ -4,6 +4,8 @@ import { z } from 'zod';
|
||||
export const envSchema = z.object({
|
||||
__DEV_TELEGRAM_ID: z.string().default(''),
|
||||
BOT_URL: z.string(),
|
||||
OFFER_URL: z.string(),
|
||||
SUPPORT_TELEGRAM_URL: z.string(),
|
||||
});
|
||||
|
||||
export const env = envSchema.parse(process.env);
|
||||
|
||||
@ -11,5 +11,7 @@ export default withAuth({
|
||||
});
|
||||
|
||||
export const config = {
|
||||
matcher: ['/((?!auth|browser|telegram|unregistered|api|_next/static|_next/image|favicon.ico).*)'],
|
||||
matcher: [
|
||||
'/((?!auth|browser|telegram|unregistered|privacy|public-offer|api|_next/static|_next/image|favicon.ico).*)',
|
||||
],
|
||||
};
|
||||
|
||||
@ -13,10 +13,13 @@
|
||||
"BOT_TOKEN",
|
||||
"NEXTAUTH_SECRET",
|
||||
"BOT_URL",
|
||||
"SUPPORT_TELEGRAM_URL",
|
||||
"BOT_PROVIDER_TOKEN",
|
||||
"REDIS_HOST",
|
||||
"REDIS_PORT",
|
||||
"REDIS_PASSWORD"
|
||||
"REDIS_PASSWORD",
|
||||
"OFFER_URL",
|
||||
"PRIVACY_URL"
|
||||
]
|
||||
},
|
||||
"lint": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user