Skip to content
This repository has been archived by the owner on Mar 13, 2023. It is now read-only.

Добавить новую систему оплаты #22

Merged
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
.env
__pycache__
user-data

ssl
*.db
**/logs/*.txt

14 changes: 13 additions & 1 deletion stable/chat_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
class ChatUser:
user_id: int
user_name: str
user_chat_id: int
user_storage_path: Path

messages_file_path: Path
Expand All @@ -33,6 +34,8 @@ def __init__(self, user_name: str , user_id: int):
self.user_storage_path.as_posix() + "/settings.json")
self.settings_file_path.parent.mkdir(exist_ok=True, parents=True)

self.user_chat_id = -1

# Default personality.
self.personality = Personalities.Sakura()
# Default tokens.
Expand Down Expand Up @@ -70,6 +73,7 @@ def restore_settings(self):
self.personality = Personalities.find_by_title(file_content_json["personality"])
self.tokens = file_content_json["tokens"]
self.user_name = file_content_json["user_name"]
self.user_chat_id = file_content_json["user_chat_id"]
except:
# Force set of defaults.
self.save()
Expand All @@ -91,6 +95,13 @@ def remove_last_message(self):

def clear_message_history(self):
self.messages = []

@staticmethod
def update_chat_id(user_id: int, chat_id: int):
chat_user = ChatUser("", user_id)
chat_user.restore_settings()
chat_user.user_chat_id = chat_id
chat_user.save()

def save(self):
"""Saves user data on disk."""
Expand All @@ -101,7 +112,8 @@ def save(self):
settings = {
"personality":self.personality.title,
"tokens":self.tokens,
"user_name":self.user_name
"user_name":self.user_name,
"user_chat_id":self.user_chat_id,
}

serialized_settings = json.dumps(settings,ensure_ascii=False,indent=2)
Expand Down
53 changes: 53 additions & 0 deletions stable/db_interface.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import sqlite3

from enum import Enum
from goods import Good

import time

class PaymentStatus(Enum):
CREATED = 1
SUCCEEDED = 2

class DatabaseInterface:
def __init__(self, db_file="payments.db"):
self.connection = sqlite3.connect(db_file)
self.cursor = self.connection.cursor()


def create_payment(self, uuid, user_id, user_name, good: Good):
timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))

self.cursor.execute('''INSERT INTO payments (uuid, user_id, user_name, status, tokens, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?)''', (uuid, user_id, user_name, PaymentStatus.CREATED.name, good.quantity, timestamp, timestamp))
self.connection.commit()


def select_data(self, uuid):
self.cursor.execute(f'''SELECT * FROM payments WHERE uuid="{uuid}"''')
return self.cursor.fetchone()


def set_status(self, uuid, status:PaymentStatus):
timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))

self.cursor.execute('''UPDATE payments SET status=?, updated_at=?
WHERE uuid=?''', (status.name, timestamp, uuid))
self.connection.commit()


def close(self):
self.connection.close()


# db = DatabaseInterface()

# db.create_payment('12345', 1, 'John')
# db.create_payment('64524', 2, 'John')
# db.set_paid('12345')

# db.set_status('12345',PaymentStatus.SUCCEEDED)

# print(db.select_data("2b988180-000f-5000-a000-15923964c419")[5])

# db.close()
81 changes: 29 additions & 52 deletions stable/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,12 @@

import openai

import re

from behaviors import Personalities

from goods import Goods, Good

from chat_user import ChatUser
from chat_gpt import chatGPT
from chat_gpt import get_image

from logger import log_purchase

from text_functions import get_avaliable_behaviours,on_behaviour_change,on_profile_button,text

Expand All @@ -26,11 +21,12 @@
from dotenv import load_dotenv
import os

from payment import create_payment


load_dotenv()
openai.api_key = os.environ.get("OPEN_AI_KEY")
token = os.environ.get("TELEGRAM_KEY")
TELEGRAM_INVOICE_PROVIDER_TOKEN = os.environ.get("TELEGRAM_INVOICE_PROVIDER_TOKEN")
token = os.environ.get("TELEGRAM_KEY_TEST")

bot = telebot.TeleBot(str(token))

Expand All @@ -39,9 +35,9 @@
regex = r"\[image description: (.*?)]"



@bot.message_handler(commands=["start"])
def start_command(message):
ChatUser.update_chat_id(message.from_user.id, message.chat.id)

behaviors_list = Personalities.get_names()

Expand All @@ -52,42 +48,38 @@ def start_command(message):

bot.send_message(message.chat.id, Placeholders.START_MESSAGE , reply_markup=markup)

@bot.pre_checkout_query_handler(func=lambda call: True)
def process_pre_checkout_query(pre_checkout_query: types.PreCheckoutQuery):
# Отправляем запрос на проверку счета
# print(pre_checkout_query.order_info)
bot.answer_pre_checkout_query(int(pre_checkout_query.id), ok=True)



@bot.callback_query_handler(func=lambda call: True)
def handle_callback_query(call: types.CallbackQuery):
ChatUser.update_chat_id(call.from_user.id, call.message.chat.id)

if call.data.startswith("buy_tokens:"):
option = call.data.replace("buy_tokens:", "")
good: Good = Goods.Tokens.__dict__["option" + option]

good: Good = Goods.Tokens.__dict__["option" + option]
good_description = f'🌸Счёт на оплату токенов.\n\nПосле оплаты, вы получите {good.quantity} токенов'
good_price = types.LabeledPrice(str(good.price), good.price * 100)

if not TELEGRAM_INVOICE_PROVIDER_TOKEN:
return

bot.send_invoice(
call.message.chat.id,
title='Счёт',
description=good_description,
invoice_payload=str(good.quantity),
provider_token=TELEGRAM_INVOICE_PROVIDER_TOKEN,
currency=good.currency,
prices=[good_price]
)

chat_user = ChatUser(call.from_user.username, call.from_user.id)
chat_user.restore_settings()

# TODO: CREATE_PAYMENT
payment = create_payment(good, chat_user)
if not payment["confirmation"]:
raise ValueError("No 'confirmation' in 'payment'.")

button_pay = types.InlineKeyboardButton(text=f"Оплатить {good.price} {good.currency}", url=payment["confirmation"]["confirmation_url"])

keyboard = types.InlineKeyboardMarkup()
keyboard.add(button_pay)

bot.send_message(call.message.chat.id, good_description, reply_markup=keyboard)
bot.answer_callback_query(callback_query_id=call.id)

if call.data == "donate":
keyboard = types.InlineKeyboardMarkup()
button1 = types.InlineKeyboardButton(text=str(Goods.Tokens.option1),callback_data="buy_tokens:1")
button2 = types.InlineKeyboardButton(text=str(Goods.Tokens.option2),callback_data="buy_tokens:2")
button3 = types.InlineKeyboardButton(text=str(Goods.Tokens.option3),callback_data="buy_tokens:3")
button1 = types.InlineKeyboardButton(text=str(Goods.Tokens.option1), callback_data="buy_tokens:1")
button2 = types.InlineKeyboardButton(text=str(Goods.Tokens.option2), callback_data="buy_tokens:2")
button3 = types.InlineKeyboardButton(text=str(Goods.Tokens.option3), callback_data="buy_tokens:3")
for button in [button1, button2, button3]:
keyboard.add(button)

Expand Down Expand Up @@ -117,6 +109,8 @@ def handle_callback_query(call: types.CallbackQuery):

@bot.message_handler(content_types=["text"])
def texts(message):
ChatUser.update_chat_id(message.from_user.id, message.chat.id)

chat_user = ChatUser(message.from_user.username,message.from_user.id)
chat_user.restore_message_history()
chat_user.restore_settings()
Expand Down Expand Up @@ -154,6 +148,8 @@ def edit_text(message):

@bot.message_handler(content_types=["voice"])
def voice(message):
ChatUser.update_chat_id(message.from_user.id, message.chat.id)

chat_user = ChatUser(message.from_user.username,message.from_user.id)
chat_user.restore_message_history()

Expand Down Expand Up @@ -192,23 +188,4 @@ def voice(message):
collect_garbage([file_name, file_name.replace(
".ogg", ".wav"), speech_file_name])


@bot.message_handler(content_types=['successful_payment'])
def got_payment(message):
tokens = int(message.successful_payment.invoice_payload)

chat_user = ChatUser(message.from_user.username, message.from_user.id)
chat_user.restore_settings()

chat_user.tokens += tokens
chat_user.save()

log_purchase(chat_user,tokens)

image_link = get_image("Anime girl Sakura, the most cutest. Icon for telegram with a background.")

bot.send_message(message.chat.id, f'🌸 Аввввррр, спасибо мой дорогой друг!\n\nНа твой баланс токенов было зачислено {tokens} токенов!')
bot.send_photo(message.chat.id, photo=image_link)


bot.infinity_polling()
24 changes: 24 additions & 0 deletions stable/migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import sqlite3

# Создаем подключение к базе данных
conn = sqlite3.connect('payments.db')

# Создаем курсор для выполнения операций с базой данных
c = conn.cursor()

# Создаем таблицу с указанными колонками
c.execute('''CREATE TABLE IF NOT EXISTS payments
(id INTEGER PRIMARY KEY,
uuid TEXT,
user_id INTEGER,
user_name TEXT,
status TEXT,
tokens INTEGER,
created_at INTEGER,
updated_at INTEGER)''')

# Сохраняем изменения в базе данных
conn.commit()

# Закрываем соединение с базой данных
conn.close()
92 changes: 92 additions & 0 deletions stable/payment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import uuid
import os
import telebot
import json

from dotenv import load_dotenv
from goods import Good, Goods
from yookassa import Configuration, Payment
from yookassa.domain.response import PaymentResponse

from chat_user import ChatUser
from db_interface import DatabaseInterface

load_dotenv()

Configuration.account_id = os.environ.get("YOOKASSA_ACCOUNT_ID")
Configuration.secret_key = os.environ.get("YOOKASSA_SECRET_KEY")

token = os.environ.get("TELEGRAM_KEY")
bot = telebot.TeleBot(str(token))


def create_payment(good: Good, chat_user: ChatUser):
payment = Payment.create({
"amount": {
"value": good.price,
"currency": good.currency
},
"confirmation": {
"type": "redirect",
"return_url": "https://t.me/sakuraGPTbot"
},
"capture": True,
"description": str(good)
}, uuid.uuid4())

payment_data = json.loads(payment.json())

db = DatabaseInterface()


db.create_payment(payment_data["id"], chat_user.user_id, chat_user.user_name, good)
db.close()

return json.loads(payment.json())

def on_success_payment(user_name: str, user_id: int, tokens: int):
chat_user = ChatUser(user_name, user_id)
chat_user.restore_settings()
chat_user.tokens += tokens
chat_user.save()

message = f"""
🌸 Аввввррр, спасибо мой дорогой друг!

На твой баланс токенов было зачислено {tokens} токенов!
Теперь у тебя {chat_user.tokens} токеньчиков! ❤️
"""

bot.send_message(chat_user.user_chat_id, message)

# chat_user = ChatUser("name",565324826)
# url = create_payment(Goods.Tokens.option3,chat_user)

# print(url)





# payment = {"amount": {"currency": "RUB", "value": "499.00"}, "confirmation": {"confirmation_url": "https://yoomoney.ru/checkout/payments/v2/contract?orderId=2b984aba-000f-5000-9000-10fe47251494", "type": "redirect"}, "created_at": "2023-03-06T18:54:50.745Z", "description": "3750 Токенов - 499 RUB", "id": "2b984aba-000f-5000-9000-10fe47251494", "metadata": {}, "paid": False, "recipient": {"account_id": "200134", "gateway_id": "2057098"}, "refundable": False, "status": "pending", "test": True}


# payment = Payment.create({
# "amount": {
# "value": "69",
# "currency": "RUB"
# },
# "confirmation": {
# "type": "redirect",
# "return_url": "https://t.me/sakuraGPTbot"
# },
# "capture": True,
# "description": "Заказ №1"
# }, uuid.uuid4())

# print(payment.json())

# "confirmation": {
# "type": "",
# "text": "heooo"
# },
4 changes: 0 additions & 4 deletions stable/text_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,3 @@ def text(message, bot, chat_user: ChatUser):
chat_user.add_message("user",message.text)
chat_user.add_message("assistant",message_content)
chat_user.save()



print(get_avaliable_behaviours())
Loading