Форум программистов, компьютерный форум, киберфорум
Python: API, боты
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
0 / 0 / 0
Регистрация: 29.03.2020
Сообщений: 10
Telegram Bot

Код для обмена информацией на работе, в основе бота лежит обмен руководителя и подчинёнными

02.10.2024, 14:02. Показов 492. Ответов 0

Студворк — интернет-сервис помощи студентам
Всем привет. Крайне прошу помощи, а то уже совсем запутался. Разрабатываю код для обмена информацией на работе, в основе бота лежит обмен руководителя и подчинёнными сообщениями и данными. Нужно чтобы это был бот, так как на большинство запросов однотипные ответы, решил сначала разработать код для пользователя, потом для руководителя. И вроде по отдельности всё получилось разработать, но начинаю совмещать это всё в один код и тут же всё сыплется, исчезают кнопки и команды, хотя строил максимально далеко друг от друга, очень прошу помощи. Приложу оба кода и на всякий случай текстовое описание что как должно работать.
Первая часть:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import os
import json
from telegram import Update, ReplyKeyboardMarkup, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import Application, CommandHandler, MessageHandler, CallbackQueryHandler, filters
from datetime import datetime
 
# Путь к файлу для сохранения данных
DATA_DIR = "user_data"
DATA_FILE = os.path.join(DATA_DIR, "data.json")
OWNER_ID = 123456789  # Замените на Telegram ID владельца
 
# Загружаем данные из файла при старте
def load_data():
    if os.path.exists(DATA_FILE):
        with open(DATA_FILE, "r", encoding="utf-8") as file:
            return json.load(file)
    return {}
 
# Сохраняем данные в файл
def save_data():
    if not os.path.exists(DATA_DIR):
        os.makedirs(DATA_DIR)
    with open(DATA_FILE, "w", encoding="utf-8") as file:
        json.dump(user_data, file, ensure_ascii=False, indent=4)
 
# Загружаем данные пользователей из файла
user_data = load_data()
 
# Функция старта
async def start(update: Update, context):
    main_keyboard = [['Проверить статус', 'Доступные ведомости']]
    await update.message.reply_text(
        "Добрый день! Напишите наименование ведомости:",
        reply_markup=ReplyKeyboardMarkup(main_keyboard, resize_keyboard=True)
    )
 
# Функция обработки сообщений и документов
async def handle_message(update: Update, context):
    user_message = update.message.text if update.message.text else "Без текста"
    user_id = str(update.message.from_user.id)
 
    # Сохраняем информацию о сообщении
    user_data[user_id] = user_data.get(user_id, [])
    message_data = {
        "text": user_message,
        "time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        "file": None,
        "status": "Не проверено"
    }
 
    if update.message.document:
        document = update.message.document
        file_name = document.file_name
        file_id = document.file_id
        
        file_save_name = f"{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}_{file_name}"
        file_path = os.path.join(DATA_DIR, file_save_name)
 
        file = await context.bot.get_file(file_id)
        await file.download_to_drive(file_path)
 
        message_data["file"] = file_save_name
 
    user_data[user_id].append(message_data)
    save_data()
 
    reply_keyboard = [['ГКЗ', 'ГМ', 'ДП', 'КМК', 'МП', 'ПХК', 'УПФ']]
    await update.message.reply_text(
        f"Вы отправили: {user_message}",
        reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True, resize_keyboard=True)
    )
 
# Функция отправки сообщения владельцу
async def notify_owner(user_id, user_message, file_name, context):
    file_info = f"Файл: {file_name}" if file_name else "Файл не прикреплен"
    message_text = f"Сообщение от пользователя {user_id}:\n\n{user_message}\n\n{file_info}"
 
    # Кнопки для изменения статуса
    status_buttons = [
        [InlineKeyboardButton("Ожидает доставки", callback_data=f"{user_id}|Ожидает доставки")],
        [InlineKeyboardButton("Ожидает подписи", callback_data=f"{user_id}|Ожидает подписи")],
        [InlineKeyboardButton("На подписи у ЕЕ", callback_data=f"{user_id}|На подписи у ЕЕ")],
        [InlineKeyboardButton("Не подписано", callback_data=f"{user_id}|Не подписано")],
        [InlineKeyboardButton("Ведомость утеряна", callback_data=f"{user_id}|Ведомость утеряна")],
        [InlineKeyboardButton("Ведомость согласована", callback_data=f"{user_id}|Ведомость согласована")],
        [InlineKeyboardButton("Ведомость недействительная", callback_data=f"{user_id}|Ведомость недействительная")]
    ]
 
    await context.bot.send_message(
        chat_id=OWNER_ID,
        text=message_text,
        reply_markup=InlineKeyboardMarkup(status_buttons)
    )
 
# Функция обработки выбора статуса владельцем
async def handle_status_change(update: Update, context):
    query = update.callback_query
    user_id, new_status = query.data.split('|')
 
    # Обновляем статус сообщения пользователя
    if user_id in user_data:
        user_data[user_id][-1]["status"] = new_status
        save_data()
 
        # Уведомляем пользователя об изменении статуса
        await context.bot.send_message(
            chat_id=int(user_id),
            text=f"Ваше сообщение обновлено: {new_status}"
        )
 
    await query.answer()
 
# Функция обработки выбора кнопок
async def button_choice(update: Update, context):
    user_choice = update.message.text
    user_id = str(update.message.from_user.id)
 
    if user_choice in ['ГКЗ', 'ГМ', 'ДП', 'КМК', 'МП', 'ПХК', 'УПФ']:
        user_data[user_id][-1]["choice"] = user_choice
        save_data()
 
        # Отправка уведомления владельцу
        message_data = user_data[user_id][-1]
        await notify_owner(user_id, message_data["text"], message_data["file"], context)
 
        await update.message.reply_text("Информация отправлена.")
        main_keyboard = [['Проверить статус', 'Доступные ведомости']]
        await update.message.reply_text(
            "Возвращаемся к главному меню:",
            reply_markup=ReplyKeyboardMarkup(main_keyboard, resize_keyboard=True)
        )
    else:
        await update.message.reply_text("Пожалуйста, выберите из предложенных вариантов.")
 
# Функция проверки статуса сообщений
async def check_status(update: Update, context):
    user_id = str(update.message.from_user.id)
    if user_id in user_data and user_data[user_id]:
        status_message = "Ваши отправленные сообщения:\n\n"
        for message in user_data[user_id]:
            file_info = f" и файл: {message['file']}" if message['file'] else ""
            status_message += f"{message['time']}, {message['text']} {message.get('choice', '')}{file_info}, статус: {message['status']}\n"
        await update.message.reply_text(status_message)
    else:
        await update.message.reply_text("У вас пока нет сообщений.")
 
# Основная функция для запуска бота
def main():
    application = Application.builder().token('YOUR_BOT_TOKEN').build()
 
    application.add_handler(CommandHandler("start", start))
    application.add_handler(MessageHandler(filters.Regex('^(Проверить статус|Доступные ведомости)$'), check_status))
    application.add_handler(MessageHandler(filters.Regex('^(ГКЗ|ГМ|ДП|КМК|МП|ПХК|УПФ)$'), button_choice))
    application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))
    application.add_handler(MessageHandler(filters.Document.ALL, handle_message))
    application.add_handler(CallbackQueryHandler(handle_status_change))
 
    application.run_polling()
 
if __name__ == "__main__":
    main()
Вторая часть:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
import os
import logging
from datetime import datetime
from telegram import Update, ReplyKeyboardMarkup, ReplyKeyboardRemove
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ConversationHandler, CallbackContext
 
# Логирование
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO
)
logger = logging.getLogger(__name__)
 
# Состояния разговора
MAIN_MENU, DEVELOPER_LOGIN, DEVELOPER_MENU, VIEW_MESSAGES, ASSIGN_NUMBER, ASSIGN_STATUS, ADD_SCAN = range(7)
 
# Папка для хранения данных
USER_DATA_PATH = "user_data"
 
# Создание папок по дате
def create_daily_folder():
    today_str = datetime.today().strftime('%Y-%m-%d')
    path = os.path.join(USER_DATA_PATH, today_str)
    if not os.path.exists(path):
        os.makedirs(path)
    return path
 
# Стартовое сообщение
async def start(update: Update, context: CallbackContext) -> int:
    reply_keyboard = [["Проверить статус", "Вход для разработчика"]]
    await update.message.reply_text(
        "Добрый день! Отправьте ведомость",
        reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True),
    )
    return MAIN_MENU
 
# Проверка статуса - пока не работает
async def check_status(update: Update, context: CallbackContext) -> int:
    await update.message.reply_text("Функция в разработке.")
    return MAIN_MENU
 
# Вход в личный кабинет разработчика
async def developer_login(update: Update, context: CallbackContext) -> int:
    await update.message.reply_text("Введите пароль для входа в личный кабинет или нажмите 'Отмена'.")
    return DEVELOPER_LOGIN
 
async def handle_password(update: Update, context: CallbackContext) -> int:
    password = "password123"  # Пароль для личного кабинета разработчика
    if update.message.text == password:
        await update.message.reply_text("Пароль верен. Добро пожаловать в личный кабинет.", reply_markup=ReplyKeyboardRemove())
        reply_keyboard = [["Сообщения", "Присвоить номер", "Присвоить статус", "Выход"]]
        await update.message.reply_text(
            "Выберите действие.",
            reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True),
        )
        return DEVELOPER_MENU
    else:
        await update.message.reply_text("Неправильный пароль. Нажмите 'Отмена', чтобы вернуться.")
        return DEVELOPER_LOGIN
 
# Сообщения в личном кабинете (вывод всех сообщений пользователей)
async def view_messages(update: Update, context: CallbackContext) -> int:
    await update.message.reply_text("Функция просмотра сообщений в разработке.")
    return DEVELOPER_MENU
 
# Присвоение номера сообщения
async def assign_number(update: Update, context: CallbackContext) -> int:
    await update.message.reply_text("Введите номер сообщения или нажмите 'Отмена'.")
    return ASSIGN_NUMBER
 
async def handle_assign_number(update: Update, context: CallbackContext) -> int:
    # Валидация номера
    number = update.message.text
    if number.isdigit():  # Пример проверки корректности номера
        await update.message.reply_text(f"Номер {number} присвоен.")
        # Возвращение в главное меню разработчика
        reply_keyboard = [["Сообщения", "Присвоить номер", "Присвоить статус", "Выход"]]
        await update.message.reply_text(
            "Выберите действие.",
            reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True),
        )
        return DEVELOPER_MENU
    else:
        await update.message.reply_text("Неверный номер, попробуйте снова или нажмите 'Отмена'.")
        return ASSIGN_NUMBER
 
# Присвоение статуса
async def assign_status(update: Update, context: CallbackContext) -> int:
    await update.message.reply_text("Введите номер сообщения для присвоения статуса или нажмите 'Отмена'.")
    return ASSIGN_STATUS
 
async def handle_assign_status(update: Update, context: CallbackContext) -> int:
    number = update.message.text
    if number.isdigit():  # Пример проверки корректности номера
        statuses = [["Ожидает доставки", "Ожидает подписи", "На подписи у ЕЕ"],
                    ["Не подписано", "Ведомость утеряна", "Ведомость согласована", "Ведомость недействительная"], ["Отмена"]]
        await update.message.reply_text(f"Выберите статус для сообщения {number}.", reply_markup=ReplyKeyboardMarkup(statuses, one_time_keyboard=True))
        return ASSIGN_STATUS
    else:
        await update.message.reply_text("Неверный номер, попробуйте снова или нажмите 'Отмена'.")
        return ASSIGN_STATUS
 
# Присвоение статуса (в зависимости от выбора)
async def handle_status_choice(update: Update, context: CallbackContext) -> int:
    status = update.message.text
    if status in ["Ожидает доставки", "Ожидает подписи", "На подписи у ЕЕ", "Не подписано", "Ведомость утеряна", "Ведомость согласована", "Ведомость недействительная"]:
        await update.message.reply_text(f"Статус '{status}' присвоен.")
        if status == "Ведомость согласована":
            await update.message.reply_text("Прикрепите скан документа.")
            return ADD_SCAN
        else:
            reply_keyboard = [["Сообщения", "Присвоить номер", "Присвоить статус", "Выход"]]
            await update.message.reply_text("Выберите действие.", reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True))
            return DEVELOPER_MENU
    else:
        await update.message.reply_text("Выберите корректный статус.")
        return ASSIGN_STATUS
 
# Прикрепление скана
async def add_scan(update: Update, context: CallbackContext) -> int:
    document = update.message.document
    if document:
        await update.message.reply_text(f"Ведомость согласована, скан отправлен.")
        reply_keyboard = [["Сообщения", "Присвоить номер", "Присвоить статус", "Выход"]]
        await update.message.reply_text("Выберите действие.", reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True))
        return DEVELOPER_MENU
    else:
        await update.message.reply_text("Прикрепите корректный скан документа.")
        return ADD_SCAN
 
# Выход из личного кабинета
async def developer_exit(update: Update, context: CallbackContext) -> int:
    await update.message.reply_text("Вы вышли из личного кабинета.", reply_markup=ReplyKeyboardRemove())
    return MAIN_MENU
 
# Обработка кнопки "Отмена"
async def cancel(update: Update, context: CallbackContext) -> int:
    await update.message.reply_text("Отмена выполнена.", reply_markup=ReplyKeyboardRemove())
    return MAIN_MENU
 
# Основной обработчик
def main() -> None:
    application = Application.builder().token("YOUR_TELEGRAM_BOT_TOKEN").build()
 
    conv_handler = ConversationHandler(
        entry_points=[CommandHandler("start", start)],
        states={
            MAIN_MENU: [
                MessageHandler(filters.Regex("^(Проверить статус)$"), check_status),
                MessageHandler(filters.Regex("^(Вход для разработчика)$"), developer_login),
            ],
            DEVELOPER_LOGIN: [
                MessageHandler(filters.TEXT & ~filters.COMMAND, handle_password),
                MessageHandler(filters.Regex("^Отмена$"), cancel),
            ],
            DEVELOPER_MENU: [
                MessageHandler(filters.Regex("^Сообщения$"), view_messages),
                MessageHandler(filters.Regex("^Присвоить номер$"), assign_number),
                MessageHandler(filters.Regex("^Присвоить статус$"), assign_status),
                MessageHandler(filters.Regex("^Выход$"), developer_exit),
            ],
            ASSIGN_NUMBER: [
                MessageHandler(filters.TEXT & ~filters.COMMAND, handle_assign_number),
                MessageHandler(filters.Regex("^Отмена$"), cancel),
            ],
            ASSIGN_STATUS: [
                MessageHandler(filters.TEXT & ~filters.COMMAND, handle_assign_status),
                MessageHandler(filters.Regex("^Отмена$"), cancel),
            ],
            ADD_SCAN: [
                MessageHandler(filters.Document.ALL, add_scan),
                MessageHandler(filters.Regex("^Отмена$"), cancel),
            ],
        },
        fallbacks=[MessageHandler(filters.Regex("^Отмена$"), cancel)],
    )
 
    application.add_handler(conv_handler)
    application.run_polling()
 
if __name__ == "__main__":
    main()
Кликните здесь для просмотра всего текста
На главном экране нас встречает надпись: «Добрый день! Отправьте ведомость», внизу находятся две кнопки: «Проверить статус» и «Вход для разработчика», кнопка проверить статус отвечает за проверку статуса сообщений пользователя и по её нажатию, пользователь видит все сообщения, которые он отправил боту с датой временем и индивидуальным номером сообщения например:2024-10-01 18:38:00, Номер сообщения: 2, Без текста ДП и файл: XlPwy87NgQ, статус: Не проверен.
Как ты можешь заметить, также сообщению присвоена категория, например: ГМ и ДП, а также статус от разработчика. Категорию присваивает пользователь, а статус разработчик, по умолчанию стоит. Не проверено. Как это работает: Пользователь запускает бота, у него на выбор написать сообщение, или выбрать кнопку Проверить статус или Вход для разработчика. Про кнопку проверить статус мы с тобой разобрались. Если же пользователь нажимает кнопку Вход для разработчика, ему доступно ввести пароль, чтобы зайти в личный кабинет разработчика, либо нажать кнопку отмена, чтобы вернуться в главное меню, если же он вводит неправильный пароль, то ему предлагается нажать кнопку отмена и вернутся в главное меню. Так как пользователь не знает пароль от личного кабинет, он остаётся в главном меню. Теперь рассмотрим какой ещё есть функционал для пользователя. В главном меню пользователь может отправить любое сообщение или файл, после этого у пользователя появляется три кнопки: добавить текст, присвоить категорию и отмена. Кнопка добавить текст даёт возможность добавить текстовое описание к уже отправленному тексту или файлу, после нажатия этой кнопки, появляется кнопка отмена, при нажатии этой кнопки пользователь возвращается к выбору кнопок Добавить текст, Присвоить категорию, Отмена, если же пользователь отправил какой-то текст, текст сохраняется и возвращаются кнопки Добавить текст, Присвоить категорию, Отмена. При нажатии кнопки Отмена в кнопках Добавить текст, Присвоить категорию, Отмена у пользователя отменяется уже отправленное сообщение или файл и он возвращается в главное меню и может заново отправлять сообщение и файлы. Кнопка Присвоить категорию при нажатию на эту кнопку бот объединяет сообщение отправленное пользователем или файл с текстом(при наличии), который он отправил при нажатии кнопки Добавить текст, пользователю выходит следующее: «Ваш текст: здесь перечисляется отправленное сообщение или файл и добавленный текст (при наличии)» и появляются кнопки: «ГКЗ», «ГМ», «ДП», «КМК», «МП», «ПХК», «УПФ». После того, как пользователь выбрал категорию Бот суммирует всю собранную информацию и получается что-то похожее: «(Сообщение или файл пользователя)+(Добавленный текст при наличии)+(Выбранная категория)» Бот соединяет это всё и присваивает индивидуальный номер начиная с 1 (каждому сообщения вообще от всех пользователей присваивается индивидуальный номер, этот номер будет очень важен для разработчика). После чего, Бот отправляет всю собранную информацию пользователю вместе с индивидуальным номер, то есть пишет: Ваша информация отправлена (и перечисляет всю информацию), после чего пользователь возвращается в главное меню и может выполнить все действия сначала. Пожалуйста, заметь, абсолютно все сообщения и файлы и вся информация о пользователе сохраняется в папке где хранится бот, папка с информацией называется: «user_data». Вся информация сохранятся по каждому дню, для этого создаётся папка внутри папки «user_data» и называется как дата, в ней сохраняются вся информация и файлы, файлы сохраняются с отправленным именем, но только к ним добавляется время. Теперь переходим к самому сложному Вход для разработчика – это личный кабинет владельца бота, и все его функции не должны перекрываться окном для пользователя, если владелец зашёл в личный кабинет, ни одна функция из окна пользователя здесь не может работать. Здесь работают только строго функции, предусмотренные для личного кабинета, при вводе функций, не предусмотренных появляется сообщение «Я не знаю такой функции». Теперь давай рассмотрим основные функции для владельца, которые представлены кнопками после входа: «Сообщения», «Присвоить статус», «Присвоить номер», «Выход». Кнопка «Выход» отвечает за выход из личного кабинета владельца, после нажатия на неё, владелец покидает личный кабинет и ему снова доступны все функции пользователя, однако заметь, все функции из кабинета владельца в кабинете пользователя воспринимаются как сообщение, то есть они также проходят всю процедуру с добавлением текста при наличии и присвоением категории и так далее, они обладают отдельной функцией, только в личном кабинете владельца. После выхода, функции владельца начинают работать только после входа в личный кабинет. Приступим к остальным кнопкам владельца. Кнопка «Сообщения» - абсолютно все сообщения и файлы отправленные пользователями, также появляются и в личном кабинете владельца, соответственно, при нажатии на кнопку «Сообщения» у пользователя появляется следующие кнопки: кнопки по абсолютно каждому пользователю, который пользуется ботом, соответственно, если добавился пользователь, то и здесь появилась новая кнопка с пользователем и обязательно кнопка «Отмена». Кнопка «Отмена» абсолютно во всех случаях в личном кабинете владельца отвечает за функцию возврата на предыдущее окно, например: пользователь нажал на кнопку: «Сообщения», после этого нажал кнопку «Отмена», все функции окна «Сообщения» отключились и он вернулся к окну с выбором кнопок: «Сообщения», «Присвоить статус», «Присвоить номер», «Выход». Теперь давай разберёмся с кнопками по каждому пользователю в окне «Сообщения», когда человек нажимает на кнопку какого-либо пользователя, у него как и у пользователя появляется статус абсолютно всех сообщений с датой, временем, названием, названием файла категорией, статусом, индивидуальным номером и так далее, и обязательно кнопка отмена, функционал которой мы с тобой обговаривали ранее в этом окне владельцу больше ничего не доступно, он может только просмотреть сообщения от пользователей и вернуться обратно. Следующая кнопка: «Присвоить номер», нажав на неё у пользователя появляется сообщение: отправьте индивидуальный номер сообщения. А также кнопка отмена. Функционал кнопки Отмена мы с тобой знаем. А вот основной функционал заключается в следующем: владелец должен отправить индивидуальны номер сообщения, который был присвоен, заметь, если владелец отправляет номер сообщения, которого нет в базе, бот отвечает ему: Отправьте корректный номер. Если пользователь отправил корректный номер, то появляется сообщение: Какой номер присвоить? И также кнопка отмена, пользователь может писать любой текст (ну конечно кроме «отмена», потому что тогда он вернётся назад), тот текст, который владелец отправил, бот тут же прикрепляет к сообщению, то есть у сообщения теперь ещё появляется дополнение: «Номер: (номер присвоенный разработчиком)», это дополнение также прикрепляется к сообщению. После того, как номер был присвоен, появляется сообщение у Владельца: «Номер был присвоен» и владелец возвращается в главное меню личного кабинете. Пользователь же после присвоения номера получает сообщение: «Вашему сообщению: (номер сообщения) присвоен номер: (номер который присвоил владелец)». Теперь кнопка «Присвоить статус», при нажатии на неё появляется текст: «Введите номер сообщения» и появляется кнопка «Отмена», функционал которой мы с тобой знаем. Владелец должен отправить индивидуальны номер сообщения, который был присвоен, заметь, если владелец отправляет номер сообщения, которого нет в базе, бот отвечает ему: Отправьте корректный номер. Если пользователь отправил корректный номер, то появляется Абсолютно вся информация по этому сообщению и кнопки: 1. Ожидает доставки 2. Ожидает подписи 3. На подписи у ЕЕ 4. Не подписано 5. Ведомость утеряна 6. Ведомость согласована 7. Ведомость недействительная., также есть кнопка «Отмена». Заметь, при нажатии на все эти кнопки, происходит примерна та же процедура, что и при присвоении номера, только никакое сообщение владельцу вводить не надо, присваивается тот статус, что выбрал владелец из кнопок, другие сообщения воспринимаются как ошибка и пользователю появляется сообщение: «Выберите статус». После выбора, изначальный статус: «Не проверено», изменяется на статус, который выбрал владелец и происходит та же процедура, что и с номером, сообщение меняется и отправляется пользователю. Исключение кнопка «Ведомость согласована», после нажатия на эту кнопку, у владельца появляется сообщение: «Прикрепите скан» и кнопка отмена, дальше пользователь может действовать только в случае, если он отправит прикреплённый файл сообщением, если же он отправит просто сообщение, то ничего не произойдёт и опять появится сообщение «Прикрепите скан», он может только нажать кнопку «Отмена» и вернутся на предыдущий шаг, если же он отправил прикреплённый файл, то появляется сообщение «Ведомость согласована, скан отправлен», владелец возвращается на главный экран личного кабинете владельца, а пользователю также приходит сообщение с изменением статуса, а также присылается прикреплённый документ, который отправил владелец. На этом с кнопками личного кабинета владельца закончили.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
02.10.2024, 14:02
Ответы с готовыми решениями:

NAS для обмена информацией
Здравствуйте, есть необходимость собрать NAS ну или просто компьютер с объемом информации 25 TB, будет использоваться для постоянного...

Связь двух консольных приложений для обмена информацией
Вообщем имеются 2 консольных приложения (на с#). Как можно их связать друг с другом? Имеется ввиду научить их обмениваться данными между...

Программа (клиент-сервер) для обмена информацией через сокет
Здравствуйте, уважаемые программисты! Я заочник, столкнулся с проблемой по комп. сетям : нужно написать программку (клиент-сервер на Visual...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
02.10.2024, 14:02
Помогаю со студенческими работами здесь

Выбор языка программирования для обмена информацией с другим копмьютером по интернету
Здравствуйте. Подскажите пожалуйста на каком языке программирования легче реализовать следующую вещь (меня интересует C++, java, c# -...

Обмен УТ 11 ---> БП 3 Поддерживаемые версии для обмена
Добрый день уважаемые форумчане !!! Прошу помощи у гуру ... Подскажите пожалуйста - допустим есть типовой обмен УТ 11 ---> БП 3 ... ...

обмен информацией
Обмен информацией между вызываемой и вызывающей функциями осуществляется с помощью механизма…

Arduino как host usb, написание своего драйвера для обмена информацией с stm32 по usb
Доброго дня Всем, интересует вопрос как написать свой драйвер на ардуино мега чтобы можно было общаться с стм32 по протоколу usb. Пробовал...

Selenium. Проблема в работе бота для рассылки сообщений WhatsApp
Скрипт запускается, ошибок не выдает. Переходит в чат к контакту, но не пишет и не отправляет. Думал, что ошибка в Xpath, но перепробовав...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru