Подключение Гугл диска и Таблицы к Телеграмм боту (aiogram)

Выдаёт ошибку: Traceback (most recent call last): File "F:\Niposh_Studio_Bot\main.py", line 16, in credentials = ServiceAccountCredentials.from_json_keyfile_name('credentials.json', scopes) File "F:\Niposh_Studio_Bot\venv\lib\site-packages\oauth2client\service_account.py", line 219, in from_json_keyfile_name with open(filename, 'r') as file_obj: FileNotFoundError: [Errno 2] No such file or directory: 'credentials.json'

Нужно чтобы после вопроса ответа "так" на втопрос "Чи потрібно розмістити фото на прев'ю?", пользоветель мог загрузить медиа файлы в бота а тот загрузить их на гугл диск, ссылку на файлы и инфа с тоба должна добавляться в гугл таблицу

import aiogram
from aiogram import Bot, Dispatcher, types
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.contrib.fsm_storage.memory import MemoryStorage
import gspread
import json
from oauth2client.service_account import ServiceAccountCredentials
from googleapiclient.discovery import build
from googleapiclient.http import MediaIoBaseUpload
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow


scopes = ['https://www.googleapis.com/auth/drive','https://www.googleapis.com/auth/spreadsheets']
credentials = ServiceAccountCredentials.from_json_keyfile_name('credentials.json', scopes)
gc = gspread.authorize(credentials)

bot = Bot(token="Токен Бота")
dp = Dispatcher(bot, storage=MemoryStorage())


spreadsheet = gc.open_by_key("ID таблицы")
worksheet = spreadsheet.get_worksheet(0)

from googleapiclient.discovery import build
drive_service = build('drive', 'v3', credentials=credentials)


class OrderStates(StatesGroup):
    num_works = State()
    theme = State()
    need_photo = State()
    liked_works = State()
    text_for_preview = State()
    urgency = State()
    price = State()

# Команда старта
@dp.message_handler(commands=['start'])
async def start_command(message: types.Message):
    await message.reply("Главное меню", reply_markup=main_menu_keyboard())

# Клавиатура главного меню
def main_menu_keyboard():
    keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
    buttons = ["Замовлення послуг", "Мої замовлення", "Мої бонуси", "Підтримка"]
    keyboard.add(*buttons)
    return keyboard


# Обработка выбора Замовлення послуг
@dp.message_handler(text="Замовлення послуг")
async def services_choice(message: types.Message):
    await message.reply("Що дизайнемо?", reply_markup=services_keyboard())


# Клавиатура выбора сервиса
def services_keyboard():
    keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
    buttons = ["YouTube", "Twitch", "Інше"]
    keyboard.add(*buttons)
    return keyboard


# Обработка выбора YouTube
@dp.message_handler(text="YouTube")
async def youtube_choice(message: types.Message):
    await message.reply("Що бажаємо?", reply_markup=youtube_options_keyboard())


# Клавиатура выбора опций для YouTube
def youtube_options_keyboard():
    keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
    buttons = ["Превью для відео", "Банер+Аватар", "Оверлей"]
    keyboard.add(*buttons)
    return keyboard


# Обработка выбора Превью для видео
@dp.message_handler(text="Превью для відео")
async def preview_choice(message: types.Message):
    await message.reply("Який тип замовлення?", reply_markup=preview_order_type_keyboard())


# Клавиатура выбора типа заказа Превью
def preview_order_type_keyboard():
    keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
    buttons = ["Нове замовлення", "Повторне замовлення"]
    keyboard.add(*buttons)
    return keyboard

@dp.message_handler(text="Нове замовлення")
async def new_order(message: types.Message):
    await message.reply("Скільки робіт потрібно?")


@dp.message_handler(lambda message: message.text.isdigit(), state="*")
async def handle_work_amount(message: types.Message):
    work_amount = int(message.text)
    await message.reply("Яка тематика Вас цікавить?")


@dp.message_handler(state="*")
async def handle_theme(message: types.Message):
    theme = message.text
    await message.reply("Чи потрібно розмістити фото на прев'ю?", reply_markup=types.ReplyKeyboardMarkup(
        resize_keyboard=True, one_time_keyboard=True, keyboard=[
            [types.KeyboardButton("Так")],
            [types.KeyboardButton("Ні")]
        ]
    ))

    @dp.message_handler(text="Так", state="*")
    async def process_files(message: types.Message):
        await message.reply("Завантажте потрібні матеріали")
        await OrderStates.next()  # переходим к загрузке файлов

    @dp.message_handler(content_types=['photo'], state=OrderStates.next_state)
    async def upload_files(message: types.Message, state: FSMContext):
        await upload_and_save_links(message, state)
        await message.reply("Файли збережено!")


@dp.message_handler(state="*")
async def save_data(message: types.Message, state: FSMContext):
    data = await state.get_data()

    if 'files' in data:
        worksheet.append_row([data['files']])

async def upload_and_save_links(message, state):
    file_links = []

    for photo in message.photo:
        file_info = await bot.get_file(photo.file_id)
        file = await bot.download_file(file_info.file_path)

        uploaded_file = upload_to_drive(file)
        file_link = uploaded_file.get('webViewLink')
        file_links.append(file_link)

    async with state.proxy() as data:
        data['files'] = file_links


def upload_to_drive(file):
    file_metadata = {
        'name': file.file_name,
        'parents': ['ID папки гугл диска']
    }
    media = MediaIoBaseUpload(file, mimetype='image/jpg')  # для картинок

    file = drive_service.files().create(body=file_metadata, media_body=media).execute()
    return file





@dp.message_handler(text="Так", state="*")
async def need_photo(message: types.Message):
    await message.reply("Прикріпіть, будь ласка, потрібне фото:")
    # Додаткова логіка для обробки фото і переходу до наступного кроку


@dp.message_handler(text="Ні", state="*")
async def no_photo(message: types.Message):
    await message.reply("Чи є приклади робіт, що Вам сподобалися, можливо, на каналах-конкурентах?")
    # Логіка для обробки відповіді користувача "Ні" і перехід до наступного кроку


if __name__ == '__main__':
    import asyncio
    from aiogram import executor

    executor.start_polling(dp, skip_updates=True)

Ответы (0 шт):