Python Бот Telegram на Heroku не может получить доступ к электронной таблице Google - PullRequest
0 голосов
/ 05 апреля 2020

Я отправляю программу python на Heroku. Все отлично работает локально, но, похоже, он не работает на Heroku

В файле bot.py содержатся две переменные, которые сохраняются как конфигурации в Heroku: TOKEN и SPREADSHEET, это токен бота telegram и идентификатор таблицы Google, к которой я пытаюсь получить доступ.

Когда код работает на Heroku, я получаю следующее: код работает на сервере Heroku, но когда я пытаюсь отправить команду на бот Telegram, он не работает

at=info method=POST path="/" host=fff-transparency-wg.herokuapp.com request_id=d883bfc2-24a3-4cb5-b638-36b310726780 fwd="91.108.6.81" dyno=web.1 connect=1ms service=5ms status=200 bytes=172 protocol=https

Программа содержит файлы:

  1. bot.py
  2. client_secret. json
  3. Procfile
  4. needs.txt
  5. runtime.txt

BOT.PY

from telegram.ext import Updater, CommandHandler, CallbackQueryHandler
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
import logging
import os
import json
import gspread
from oauth2client.service_account import ServiceAccountCredentials
from datetime import datetime
from itertools import permutations
import re

logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)
logger = logging.getLogger("telegram.bot")

def start(update, context):
    context.bot.send_message(
        chat_id=update.effective_chat.id, text="I'm a bot, please talk to me!")

# def help(update, context):


def call(update, context):
    """ 
    Save Message ID, Title, Date, Time, Duration, Description, Link, Group ID, Group name, Saved by Name, Username

    Expected inputs (in order): Date, Time, Duration, Title, Description, Link

    Send variables to Google Sheet

    Send variables to Trello Board

    Send variables to Google Calendar

    OPTIONAL:
    Notification System
    """
    message_id = update.message.message_id
    user = update.message.from_user
    username = user['username']
    full_name = "{} {}".format(user['first_name'], user['last_name'])
    groupchat = update.message.chat

    message_text = update.message.text
    text = format_string(message_text, "/call")
    if (text == -1):
        groupchat.send_message(
            text="Please make sure all arguments are inserted in the correct order and separated by semicolomns:\n\n- Date (dd/mm/yy) \n- Time (GMT) \n- Duration (hour:min) \n- Title \n- Description(optional) \n- Agenda Link(optional)")

    call_date = text[0]
    call_time = text[1]
    call_duration = text[2]
    call_title = text[3]
    #if text[4]: call_description = text[4]
    #if text[5]: call_agenda = text[5]

    calls.append_row(
        [message_id, call_title, call_date, call_time, call_duration])


# def group(update, context):
def str2date(string):
    "Parse a string into a datetime object."

    for fmt in dateformats():
        try:
            return datetime.strptime(string, fmt)
        except ValueError:
            pass

    raise ValueError("'%s' is not a recognized date/time" % string)


def format_string(message, command):
    message = re.sub(command, '', message)
    message.strip()
    message = message.split(';')

    if not(len(message) >= 4):
        return -1

    if command == "/call":
        message[0: 1] = [' '.join(message[0: 1])]
        s = message[0].strip()
        try:
            message[0] = str2date(s)
        except ValueError:
            print("invalid date/time")

    return message


def dateformats():
    "Yield all combinations of valid date formats."

    years = ("%Y",)
    months = ("%b", "%B")
    days = ("%d",)
    times = ("%I%p", "%I:%M%p", "%H:%M", "")

    for year in years:
        for month in months:
            for day in days:
                for args in ((day, month), (month, day)):
                    date = " ".join(args)
                    for time in times:
                        for combo in permutations([year, date, time]):
                            yield " ".join(combo).strip()


def error(update, context):
    logger.warning('Update "%s" caused error "%s"', update, context.error)


def main():
    TOKEN = os.environ['TOKEN']
    updater = Updater(token=TOKEN, use_context=True)
    dp = updater.dispatcher

    PORT = int(os.environ.get('PORT', '8443'))
    updater.start_webhook(listen="0.0.0.0", port=PORT, url_path=TOKEN)
    updater.bot.set_webhook("https://fff-transparency-wg.herokuapp.com/" + TOKEN)
    updater.idle()

    # use creds to create a client to interact with the Google Drive API
    scope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive', 'https://www.googleapis.com/auth/drive.file', 'https://www.googleapis.com/auth/drive']
    creds = ServiceAccountCredentials.from_json_keyfile_name(
        'client_secret.json', scope)
    client = gspread.authorize(creds)

    # Find a workbook by name and open the first sheet
    SPREADSHEET = os.environ['SPREADSHEET']
    spreadsheet = client.open_by_key(
        SPREADSHEET)
    groupchats = spreadsheet.get_worksheet(0)
    calls = spreadsheet.get_worksheet(1)

    # Commands
    dp.add_handler(CommandHandler("start", start))
    #dp.add_handler(CommandHandler("help", help))
    dp.add_handler(CommandHandler("call", call))
    #dp.add_handler(CommandHandler("group", group))

    dp.add_error_handler(error)

if __name__ == '__main__':
    main()

PROCFILE

web: python3 bot.py
worker: python3 bot.py

ТРЕБОВАНИЯ. TXT

certifi==2019.11.28
cffi==1.14.0
chardet==3.0.4
cryptography==2.9
decorator==4.4.2
future==0.18.2
gspread==3.3.1
httplib2==0.17.1
idna==2.9
oauth2client==4.1.3
pyasn1==0.4.8
pyasn1-modules==0.2.8
pycparser==2.20
python-telegram-bot==12.5.1
requests==2.23.0
rsa==4.0
six==1.14.0
tornado==6.0.4
urllib3==1.25.8

RUNTIME.TXT

python-3.8.2
...