order: notify to telegram messages

This commit is contained in:
vchikalkin 2025-06-27 13:24:34 +03:00
parent 1e3ef51eb0
commit bb65863f81
13 changed files with 132 additions and 9 deletions

View File

@ -13,7 +13,7 @@
"lint-staged": "lint-staged"
},
"dependencies": {
"telegraf": "^4.16.3",
"telegraf": "catalog:",
"zod": "catalog:"
},
"devDependencies": {

View File

@ -0,0 +1,77 @@
import type * as GQL from '../types';
import { notifyByTelegramId } from '../utils/notify';
import { BaseService } from './base';
import { CustomersService } from './customers';
import { OrdersService } from './orders';
import { ServicesService } from './services';
import { SlotsService } from './slots';
import { type VariablesOf } from '@graphql-typed-document-node/core';
import { formatDate, formatTime, sumTime } from '@repo/utils/datetime-format';
export class NotifyService extends BaseService {
async orderCreated(variables: {
input: Omit<VariablesOf<typeof GQL.CreateOrderDocument>['input'], 'time_end'>;
}) {
const customersService = new CustomersService(this.customer);
const slotsService = new SlotsService(this.customer);
const servicesService = new ServicesService(this.customer);
const slotId = String(variables.input.slot ?? '');
const serviceId = String(variables.input.services?.[0] ?? '');
const timeStart = String(variables.input.time_start ?? '');
const clientId = String(variables.input.client ?? '');
const { slot } = await slotsService.getSlot({ documentId: slotId });
const { service } = await servicesService.getService({ documentId: serviceId });
const { customer: master } = await customersService.getCustomer({
documentId: slot?.master?.documentId ?? '',
});
const { customer: client } = await customersService.getCustomer({ documentId: clientId });
const slotDate = formatDate(slot?.date).user();
const timeStartString = formatTime(timeStart).user();
const timeEndString = formatTime(
service?.duration ? sumTime(timeStart, service.duration) : timeStart,
).user();
// Мастеру
if (master?.telegramId) {
const message = `✅ <b>Запись создана!</b>\n<b>Дата:</b> ${slotDate}\n<b>Время:</b> ${timeStartString} - ${timeEndString}\n<b>Клиент:</b> ${client?.name ?? '-'}\n<b>Услуга:</b> ${service?.name ?? '-'}`;
await notifyByTelegramId(String(master.telegramId), message);
}
// Клиенту
if (client?.telegramId) {
const message = `✅ <b>Запись создана!</b>\n<b>Дата:</b> ${slotDate}\n<b>Время:</b> ${timeStartString} - ${timeEndString}\n<b>Мастер:</b> ${master?.name ?? '-'}\n<b>Услуга:</b> ${service?.name ?? '-'}`;
await notifyByTelegramId(String(client.telegramId), message);
}
}
async orderUpdated(variables: VariablesOf<typeof GQL.UpdateOrderDocument>) {
// Получаем order через OrdersService
const ordersService = new OrdersService(this.customer);
const { order } = await ordersService.getOrder({ documentId: variables.documentId });
if (!order) return;
const slot = order.slot;
const service = order.services[0];
const master = slot?.master;
const client = order.client;
const slotDate = formatDate(slot?.date).user();
const timeStartString = formatTime(order.time_start ?? '').user();
const timeEndString = formatTime(order.time_end ?? '').user();
// Мастеру
if (master?.telegramId) {
const message = `✏️ <b>Запись изменена!</b>\n<b>Дата:</b> ${slotDate}\n<b>Время:</b> ${timeStartString} - ${timeEndString}\n<b>Клиент:</b> ${client?.name ?? '-'}\n<b>Услуга:</b> ${service?.name ?? '-'}`;
await notifyByTelegramId(String(master.telegramId), message);
}
// Клиенту
if (client?.telegramId) {
const message = `✏️ <b>Запись изменена!</b>\n<b>Дата:</b> ${slotDate}\n<b>Время:</b> ${timeStartString} - ${timeEndString}\n<b>Мастер:</b> ${master?.name ?? '-'}\n<b>Услуга:</b> ${service?.name ?? '-'}`;
await notifyByTelegramId(String(client.telegramId), message);
}
}
}

View File

@ -4,6 +4,7 @@ import * as GQL from '../types';
import { Enum_Customer_Role, Enum_Slot_State } from '../types';
import { BaseService } from './base';
import { CustomersService } from './customers';
import { NotifyService } from './notify';
import { ServicesService } from './services';
import { SlotsService } from './slots';
import { type VariablesOf } from '@graphql-typed-document-node/core';
@ -90,6 +91,10 @@ export class OrdersService extends BaseService {
const error = mutationResult.errors?.at(0);
if (error) throw new Error(error.message);
// Уведомление об создании заказа
const notifyService = new NotifyService(this.customer);
notifyService.orderCreated(variables);
return mutationResult.data;
}
@ -150,6 +155,10 @@ export class OrdersService extends BaseService {
const error = mutationResult.errors?.at(0);
if (error) throw new Error(error.message);
// Уведомление об изменении заказа
const notifyService = new NotifyService(this.customer);
notifyService.orderUpdated(variables);
return mutationResult.data;
}
}

View File

@ -2,6 +2,7 @@
import { z } from 'zod';
export const envSchema = z.object({
BOT_TOKEN: z.string(),
LOGIN_GRAPHQL: z.string(),
PASSWORD_GRAPHQL: z.string(),
URL_GRAPHQL: z.string(),

View File

@ -14,8 +14,16 @@ mutation CreateCustomer($name: String!, $telegramId: Long, $phone: String) {
}
}
query GetCustomer($phone: String, $telegramId: Long) {
customers(filters: { or: [{ phone: { eq: $phone } }, { telegramId: { eq: $telegramId } }] }) {
query GetCustomer($phone: String, $telegramId: Long, $documentId: ID) {
customers(
filters: {
or: [
{ phone: { eq: $phone } }
{ telegramId: { eq: $telegramId } }
{ documentId: { eq: $documentId } }
]
}
) {
...CustomerFields
}
}

View File

@ -13,6 +13,7 @@
"dayjs": "catalog:",
"jsonwebtoken": "catalog:",
"radashi": "catalog:",
"telegraf": "catalog:",
"zod": "catalog:"
},
"devDependencies": {

View File

@ -664,6 +664,7 @@ export type CreateCustomerMutation = { __typename?: 'Mutation', createCustomer?:
export type GetCustomerQueryVariables = Exact<{
phone?: InputMaybe<Scalars['String']['input']>;
telegramId?: InputMaybe<Scalars['Long']['input']>;
documentId?: InputMaybe<Scalars['ID']['input']>;
}>;
@ -794,7 +795,7 @@ export const SlotFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"
export const RegisterDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"Register"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"identifier"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"password"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"register"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"username"},"value":{"kind":"Variable","name":{"kind":"Name","value":"identifier"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"password"},"value":{"kind":"Variable","name":{"kind":"Name","value":"password"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"jwt"}},{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"username"}}]}}]}}]}}]} as unknown as DocumentNode<RegisterMutation, RegisterMutationVariables>;
export const LoginDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"Login"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"identifier"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"password"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"login"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"identifier"},"value":{"kind":"Variable","name":{"kind":"Name","value":"identifier"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"password"},"value":{"kind":"Variable","name":{"kind":"Name","value":"password"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"jwt"}}]}}]}}]} as unknown as DocumentNode<LoginMutation, LoginMutationVariables>;
export const CreateCustomerDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateCustomer"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"name"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"telegramId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Long"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"phone"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createCustomer"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"name"},"value":{"kind":"Variable","name":{"kind":"Name","value":"name"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"telegramId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"telegramId"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"phone"},"value":{"kind":"Variable","name":{"kind":"Name","value":"phone"}}},{"kind":"ObjectField","name":{"kind":"Name","value":"role"},"value":{"kind":"EnumValue","value":"client"}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}}]}}]}}]} as unknown as DocumentNode<CreateCustomerMutation, CreateCustomerMutationVariables>;
export const GetCustomerDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetCustomer"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"phone"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"telegramId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Long"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"customers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"or"},"value":{"kind":"ListValue","values":[{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"phone"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"eq"},"value":{"kind":"Variable","name":{"kind":"Name","value":"phone"}}}]}}]},{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"telegramId"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"eq"},"value":{"kind":"Variable","name":{"kind":"Name","value":"telegramId"}}}]}}]}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}}]} as unknown as DocumentNode<GetCustomerQuery, GetCustomerQueryVariables>;
export const GetCustomerDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetCustomer"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"phone"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"telegramId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Long"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"customers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"or"},"value":{"kind":"ListValue","values":[{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"phone"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"eq"},"value":{"kind":"Variable","name":{"kind":"Name","value":"phone"}}}]}}]},{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"telegramId"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"eq"},"value":{"kind":"Variable","name":{"kind":"Name","value":"telegramId"}}}]}}]},{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"documentId"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"eq"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}}]}}]}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}}]} as unknown as DocumentNode<GetCustomerQuery, GetCustomerQueryVariables>;
export const GetMastersDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetMasters"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"phone"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"telegramId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Long"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"customers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"or"},"value":{"kind":"ListValue","values":[{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"phone"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"eq"},"value":{"kind":"Variable","name":{"kind":"Name","value":"phone"}}}]}}]},{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"telegramId"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"eq"},"value":{"kind":"Variable","name":{"kind":"Name","value":"telegramId"}}}]}}]},{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"documentId"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"eq"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}}]}}]}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"masters"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}}]} as unknown as DocumentNode<GetMastersQuery, GetMastersQueryVariables>;
export const GetClientsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetClients"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"phone"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"telegramId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Long"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"customers"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filters"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"or"},"value":{"kind":"ListValue","values":[{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"phone"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"eq"},"value":{"kind":"Variable","name":{"kind":"Name","value":"phone"}}}]}}]},{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"telegramId"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"eq"},"value":{"kind":"Variable","name":{"kind":"Name","value":"telegramId"}}}]}}]}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"clients"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}}]} as unknown as DocumentNode<GetClientsQuery, GetClientsQueryVariables>;
export const UpdateCustomerDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateCustomer"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"data"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CustomerInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateCustomer"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"documentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"data"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"CustomerFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"CustomerFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Customer"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"active"}},{"kind":"Field","name":{"kind":"Name","value":"documentId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"photoUrl"}},{"kind":"Field","name":{"kind":"Name","value":"role"}},{"kind":"Field","name":{"kind":"Name","value":"telegramId"}}]}}]} as unknown as DocumentNode<UpdateCustomerMutation, UpdateCustomerMutationVariables>;

View File

@ -0,0 +1,9 @@
import { bot } from './telegram';
export async function notifyByTelegramId(telegramId: string | undefined, message: string) {
if (!telegramId) return;
await bot.telegram.sendMessage(telegramId, message, {
parse_mode: 'HTML',
});
}

View File

@ -0,0 +1,4 @@
import { env } from '@/config/env';
import { Telegraf } from 'telegraf';
export const bot = new Telegraf(env.BOT_TOKEN);

View File

@ -1,6 +1,7 @@
/* eslint-disable import/no-unassigned-import */
import dayjs from 'dayjs';
import { isBrowser } from './environment';
import 'dayjs/locale/ru';
import dayjs from 'dayjs';
import { noop } from 'radashi';
export function combineDateTime(date: Date, time: string) {
@ -20,9 +21,11 @@ export function formatDate(date: Date | string) {
return {
db: () => dayjs(date).format('YYYY-MM-DD'),
user: (template?: string) => {
const lang = document.documentElement.lang || 'ru';
user: (template?: string, fallbackLang: string = 'ru') => {
const lang = isBrowser() ? document.documentElement.lang || fallbackLang : fallbackLang;
dayjs.locale(lang);
return dayjs(date).format(template || 'D MMMM YYYY');
},
};

View File

@ -0,0 +1,3 @@
export function isBrowser() {
return typeof window !== 'undefined' && typeof document !== 'undefined';
}

8
pnpm-lock.yaml generated
View File

@ -72,6 +72,9 @@ catalogs:
tailwindcss:
specifier: ^3.4.15
version: 3.4.15
telegraf:
specifier: ^4.16.3
version: 4.16.3
typescript:
specifier: ^5.7
version: 5.7.2
@ -105,7 +108,7 @@ importers:
apps/bot:
dependencies:
telegraf:
specifier: ^4.16.3
specifier: 'catalog:'
version: 4.16.3
zod:
specifier: 'catalog:'
@ -289,6 +292,9 @@ importers:
radashi:
specifier: 'catalog:'
version: 12.5.1
telegraf:
specifier: 'catalog:'
version: 4.16.3
zod:
specifier: 'catalog:'
version: 3.24.1

View File

@ -24,6 +24,7 @@ catalog:
radashi: ^12.5.1
rimraf: ^6.0.1
tailwindcss: ^3.4.15
telegraf: ^4.16.3
typescript: ^5.7
vite-tsconfig-paths: ^5.1.4
vitest: ^2.1.8