Подключение Гугл диска и Таблицы к Телеграмм боту (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)