Compare commits

...

23 Commits

Author SHA1 Message Date
Alex55 09f856671d 2134 2026-03-24 22:45:16 +02:00
Alex55 d06e3eb082 2134 2026-03-24 22:39:31 +02:00
Alex55 b4292d2620 2134 2026-03-24 22:36:02 +02:00
Alex55 a53a66f2ec 2134 2026-03-24 22:30:19 +02:00
Alex55 c4d13d2586 2134 2026-03-24 22:21:53 +02:00
Alex55 561db2d611 2134 2026-03-24 22:15:33 +02:00
Alex55 fdd2c1b41d 2134 2026-03-24 21:55:45 +02:00
Alex55 329e433e22 2134 2026-03-24 21:53:46 +02:00
Alex55 c24a7a7256 2134 2026-03-24 21:46:16 +02:00
Alex55 708915f67c 2134 2026-03-24 21:43:24 +02:00
Alex55 8b901533e8 2134 2026-03-24 21:37:29 +02:00
Alex55 9a4f457199 2134 2026-03-24 21:33:17 +02:00
Alex55 3b5cc83165 sdf 2026-03-24 18:58:31 +02:00
Alex55 cd2ec62939 sdf 2026-03-24 18:56:52 +02:00
Alex55 f2370bf4e5 sdf 2026-03-24 18:54:28 +02:00
Alex55 ed5b73f12c sdf 2026-03-24 18:38:48 +02:00
Alex55 2fcfa44b9c sdf 2026-03-24 18:37:36 +02:00
Alex55 9c8476bd72 sdf 2026-03-24 18:35:37 +02:00
Alex55 559b07a0a5 sdf 2026-03-24 18:31:19 +02:00
Alex55 ea8fda702b sdf 2026-03-24 18:22:23 +02:00
Alex55 4d72175bca sdf 2026-03-24 17:07:18 +02:00
Alex55 ef47208ce9 sdf 2026-03-24 16:50:35 +02:00
Alex55 8a7bbf227f sdf 2026-03-24 16:42:10 +02:00
16 changed files with 317 additions and 82 deletions

Binary file not shown.

View File

@ -13,10 +13,10 @@ sys.path.insert(0, project_root)
# print(db_price) # print(db_price)
download_products() # download_products()
download_prices() download_prices()
decrypt_and_unpack("prices") decrypt_and_unpack("prices")
decrypt_and_unpack("products") # decrypt_and_unpack("products")
add_product() # add_product()
update_prices() update_prices()

View File

@ -1,8 +1,10 @@
from dotenv import load_dotenv from dotenv import load_dotenv
import os import os
load_dotenv() load_dotenv()
import sqlite3
import requests import requests
conn = sqlite3.connect("./files/rokky.db")
partner = os.getenv('partner') partner = os.getenv('partner')
user_name = os.getenv('userName') user_name = os.getenv('userName')
password = os.getenv('password') password = os.getenv('password')
@ -28,7 +30,7 @@ def tokens():
access_token = data["accessToken"] access_token = data["accessToken"]
return access_token return access_token
access_token = tokens() # access_token = tokens()
def get_orders(access_token, page=1, page_size=25): def get_orders(access_token, page=1, page_size=25):
url = f"{BASE_URL}/orders" url = f"{BASE_URL}/orders"
@ -78,8 +80,10 @@ def download_prices():
print("Каталог цен скачан.") print("Каталог цен скачан.")
def create_order(sku, quantity, unit_price, partner_order_id): def create_order(sku, unit_price, partner_order_id):
# try: # try:
conn = sqlite3.connect("./files/rokky.db")
cursor = conn.cursor()
url = f"{BASE_URL}/orders" url = f"{BASE_URL}/orders"
headers = { headers = {
@ -91,11 +95,11 @@ def create_order(sku, quantity, unit_price, partner_order_id):
"items": [ "items": [
{ {
"sku": int(sku), "sku": int(sku),
"quantity": int(quantity), "quantity": 1,
"unitPrice": float(unit_price) "unitPrice": float(unit_price)
} }
], ],
"partnerOrderId": partner_order_id "partnerOrderId": f"my-orders{partner_order_id}"
} }
try: try:
@ -117,7 +121,18 @@ def create_order(sku, quantity, unit_price, partner_order_id):
response.raise_for_status() # Всё равно выбрасываем исключение response.raise_for_status() # Всё равно выбрасываем исключение
return response.json() r = response.json()
order_id = r["orderId"]
print(partner_order_id)
print(order_id)
cursor.execute("""
UPDATE orders
SET orders_rokky = ?
WHERE id_i = ?
""", (order_id, partner_order_id))
conn.commit()
conn.close()
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
print(f"🌐 Сетевая ошибка: {e}") print(f"🌐 Сетевая ошибка: {e}")
@ -146,6 +161,9 @@ def get_orders(page=1, page_size=25):
def get_order_content(order_id): def get_order_content(order_id):
conn = sqlite3.connect("./files/rokky.db")
cursor = conn.cursor()
url = f"{BASE_URL}/orders/{order_id}/content" url = f"{BASE_URL}/orders/{order_id}/content"
headers = { headers = {
@ -156,20 +174,31 @@ def get_order_content(order_id):
response = requests.get(url, headers=headers) response = requests.get(url, headers=headers)
response.raise_for_status() response.raise_for_status()
data = response.json() data = response.json()
con = data['orderContentItems'] con = data['orderContentItems']
for c in con: for c in con:
content = c['content'] content = c['content']
cursor.execute("""
UPDATE orders
SET key = ?
WHERE orders_rokky = ?
""", (content, order_id))
conn.commit()
conn.close()
return content return content
# content = get_order_content(5379499) # content = get_order_content(5388720)
# print(content) # print(content)
# orders = get_orders() # orders = get_orders()
# print(orders) # print(orders)
# order = create_order(22774, 1, 21.3, "my-test-order-12w3") # order = create_order(22785, 22.63, "my-test-order-122w3")
# print(order) # print(order)

View File

@ -173,7 +173,7 @@ def update_prices():
data = [] data = []
for item in prices: for item in prices:
sku = item["sku"] sku = item["sku"]
price = item.get("basePrice") price = item.get("price")
price_gg = item.get("baseSuggestedRetailPrice") price_gg = item.get("baseSuggestedRetailPrice")
price_sales =item.get("discountPercentage") price_sales =item.get("discountPercentage")
is_sale = item.get("isSale") is_sale = item.get("isSale")
@ -201,4 +201,4 @@ def update_prices():
# decrypt_and_unpack("prices") # decrypt_and_unpack("prices")
# decrypt_and_unpack("products") # decrypt_and_unpack("products")
# add_product() # add_product()
update_prices() # update_prices()

2
API/ww
View File

@ -1 +1 @@
5110eb4a7aa7c60d66f9648db40027f241c52673a6a7c9a136e2a02fd1711fb&amount=1.0&currency=RUB&date=2026-03-20T10=43=09+03=00&email=rusinowdima2@yandex.ru&id_d=102180432&id_i=21327450&ip=188.32.208.151&is_my_product=true id_i=34534345435&id_d=102180432&amount=33&curr=USD&date=2026-03-20T10:43:09+03:00&email=rusinowdima2@yandex.ru&sha256=5110eb4a7aa7c60d66f9648db40027f241c52673a6a7c9a136e27a02fd1711fb&ip={IP}&isMyProduct=true

View File

@ -4,9 +4,12 @@ import os
import sqlite3 import sqlite3
import json import json
# from services.rokky import ones # from services.rokky import ones
from API.rok import create_order from API.rok import create_order, get_order_content
from API.TG import send_telegram from API.TG import send_telegram
from services.orders import get_sku from services.orders import get_sku
from services.gg import get_product, create_messagea
from services.send_mai import send_html_flow
import logging import logging
@ -26,21 +29,30 @@ def get_image(filename):
@main.route("/orders/api_payments", methods=["POST", "GET"]) @main.route("/orders/api_payments", methods=["POST", "GET"])
def index1(): def index1():
DB_PATH = "./files/rokky.db"
# Получаем все GET-параметры # Получаем все GET-параметры
params = request.args.to_dict() params = request.args.to_dict()
logging.warn(f"newOrder: {params}") logging.warn(f"newOrder: {params}")
# Просто выводим на экран (в ответ клиенту) # Просто выводим на экран (в ответ клиенту)
# парсим данные # парсим данные
sku = params.get("id_d") id_d = params.get("id_d")
product_id = params.get("id_i") id_i = params.get("id_i")
email = params.get("email") email = params.get("email")
price = params.get("amount") amount = params.get("amount")
currency = params.get("currency")
date = params.get("date")
# всё остальное сохраняем как JSON # всё остальное сохраняем как JSON
content = json.dumps(params, ensure_ascii=False) content = json.dumps(params, ensure_ascii=False)
db_sku, db_price = get_sku(sku) send_telegram(content)
create_order(db_sku, price, db_price, f"my-test-order-{product_id}")
# send_telegram(content) message = f"🔹Спасибо за покупку в WST Keys (West Store Trusted Keys)\n\n ⏳ Ваш заказ обрабатывается и будет доставлен автоматически"
create_messagea(id_i, message)
#
sku_rokky, price_rokky = get_sku(id_d)
send_telegram(content)
name_p, im = get_product(id_d)
conn = sqlite3.connect(DB_PATH) conn = sqlite3.connect(DB_PATH)
cursor = conn.cursor() cursor = conn.cursor()
@ -48,9 +60,9 @@ def index1():
try: try:
cursor.execute(""" cursor.execute("""
INSERT INTO orders (sku, product_id, email, price, content) INSERT INTO orders (id_i, id_d, email,name_p, im, amount, content, currency, date, sku_rokky, price_rokky)
VALUES (?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)
""", (sku, product_id, email, price, content)) """, (id_i, id_d, email, name_p, im, amount, content, currency, date, sku_rokky, price_rokky))
conn.commit() conn.commit()
except Exception as e: except Exception as e:
@ -58,18 +70,16 @@ def index1():
return jsonify({"error": str(e)}), 500 return jsonify({"error": str(e)}), 500
conn.close() conn.close()
send_telegram(create_order(sku_rokky, price_rokky, id_i))
return jsonify({"success": True}), 200 return jsonify({"success": True}), 200
# return "Hello GET" # return "Hello GET"
@main.route("/sales", methods=["POST", "GET"])
def index2():
return "Hello GET!!!++!!ss"
@main.route("/newOrder", methods=["POST"]) @main.route("/newOrder", methods=["POST"])
def new_order(): def new_order():
if not request.is_json: if not request.is_json:
return jsonify({"error": "Invalid content type"}), 400 return jsonify({"error": "Invalid content type"}), 400
@ -84,9 +94,13 @@ def new_order():
# TODO: обработка заказа # TODO: обработка заказа
print(f"New order received: {order_id}") print(f"New order received: {order_id}")
send_telegram(data) send_telegram(order_id)
# logging.warn(get_order_content(order_id))
logging.warn(f"newOrder: {order_id}") logging.warn(f"newOrder: {order_id}")
get_order_content(order_id)
send_html_flow(order_id)
return jsonify({"status": "ok"}), 200 return jsonify({"status": "ok"}), 200

View File

@ -12,17 +12,33 @@ services:
- ./nginx/certbot/conf:/etc/letsencrypt - ./nginx/certbot/conf:/etc/letsencrypt
extra_hosts: extra_hosts:
- "host.docker.internal:host-gateway" - "host.docker.internal:host-gateway"
depends_on:
- web
restart: always
wg-client:
image: ghcr.io/linuxserver/wireguard
container_name: wg-client
cap_add:
- NET_ADMIN
- SYS_MODULE
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Amsterdam
volumes:
- ./wg:/config # сюда кладём ./wg/wg_confs/wg0.conf
restart: always restart: always
web: web:
build: . build: .
container_name: flask-dev container_name: flask-dev
ports:
- "5205:5205" # Пробрасываем порт наружу
volumes: volumes:
# Главная строка: монтируем текущую папку с кодом (.)
# в папку /app внутри контейнера
- .:/app - .:/app
environment: environment:
- FLASK_DEBUG=1 # Дополнительная страховка для включения дебага - FLASK_DEBUG=1
- PYTHONUNBUFFERED=1 # Чтобы логи выводились сразу, а не кэшировались - PYTHONUNBUFFERED=1
network_mode: "service:wg-client" # весь трафик Flask через VPN
depends_on:
- wg-client
restart: always

View File

@ -6,10 +6,19 @@ cursor = conn.cursor()
cursor.execute(""" cursor.execute("""
CREATE TABLE IF NOT EXISTS orders ( CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
sku INTEGER UNIQUE, id_i INTEGER UNIQUE,
product_id INTEGER, id_d INTEGER,
name_p TEXT,
im TEXT,
email TEXT, email TEXT,
price TEXT, chat_id TEXT,
currency TEXT,
amount TEXT,
date TEXT,
sku_rokky TEXT,
price_rokky TEXT,
orders_rokky TEXT,
key TEXT,
content TEXT content TEXT
) )
""") """)

View File

@ -212,9 +212,9 @@ def get_chats(page=1, pagesize=20, filter_new=None, email=None, id_ds=None):
return r.json() return r.json()
def get_product(): def get_product(product_id):
token = load_token() token = load_token()
product_id = 102182541 # product_id = 102180432
url = f"https://seller.ggsel.com/api_sellers/api/products/{product_id}/data" url = f"https://seller.ggsel.com/api_sellers/api/products/{product_id}/data"
@ -229,10 +229,14 @@ def get_product():
r = requests.get(url, headers=headers, params=params) r = requests.get(url, headers=headers, params=params)
print(r.status_code) print(r.status_code)
return r.json() prud = r.json()
name = prud["product"]["name"]
im = prud["product"]["preview_imgs"][0]["url"]
return name, im
# return r.json()
# print(get_product()) # print(get_product(102184895))
def create_message(id_i: int): def create_message(id_i: int):
@ -268,10 +272,91 @@ def create_message(id_i: int):
} }
# пример вызова # пример вызова
create_message(18094706) # create_message(18094706)
def create_messagea(id_i: int, message):
print("SEND MESSAGE CALLED", id_i)
token = load_token()
# message = "Спасибо за покупку в WST Keys"
url = "https://seller.ggsel.com/api_sellers/api/debates/v2"
params = {
"token": token,
"id_i": id_i
}
payload = {
"message": message
}
r = requests.post(url, params=params, json=payload)
print("STATUS:", r.status_code)
return r.text
# message = f"🔹Спасибо за покупку в WST Keys (West Store Trusted Keys)\n\n"
# create_messagea(22289522, message)
# пример # пример
# print(get_chats())
def get_chats_by_email(email):
token = load_token()
message = (
f""
)
url = "https://seller.ggsel.com/api_sellers/api/debates/v2/chats"
params = {
"token": token,
'email': email,
'pagesize': 100,
'page': 1
}
payload = {
"message": message
}
r = requests.get(url, params=params)
print(r.text)
if r.status_code == 200:
return {"success": True}
return {
"success": False,
"status": r.status_code,
"response": r.text
}
# get_chats_by_email('fenomenplayerok@gmail.com')
def get_order_info(invoice_id: int, locale: str = "ru"):
token = load_token()
url = f"https://seller.ggsel.com/api_sellers/api/purchase/info/{invoice_id}"
headers = {
"Accept": "application/json",
"locale": locale
}
params = {
"token": token
}
r = requests.get(url, headers=headers, params=params)
return r.json() # или r.text если нужен сырой ответ
# # пример использования
# invoice_id = 22228752
# info = get_order_info(invoice_id)
# print(info)
# print(get_chats(email='fenomenplayerok@gmail.com'))
# def tokens(): # def tokens():
# timestamp = str(int(time.time())) # timestamp = str(int(time.time()))
@ -314,3 +399,23 @@ create_message(18094706)
# print(response.status_code) # print(response.status_code)
# print(response.json()) # print(response.json())
# def create_debate(order_id):
# token = load_token()
# url = "https://seller.ggsel.com/api_sellers/api/debates/v2"
# params = {
# "token": token,
# "id_i": order_id
# }
# json = {
# "message": "Спасибо за покупку в WST Keys"
# }
# r = requests.post(url, params=params, json=json)
# return r.json()
# print(create_debate("22257737"))

View File

@ -3,7 +3,7 @@ import smtplib
from email.message import EmailMessage from email.message import EmailMessage
from dotenv import load_dotenv from dotenv import load_dotenv
from utils import build_items_html, build_keys_html, render_template from services.utils import build_items_html, build_keys_html, render_template
load_dotenv() load_dotenv()

View File

@ -1,5 +1,8 @@
import sys import sys
from mailer import send_plain_email, send_html_email from services.mailer import send_plain_email, send_html_email
import sqlite3
from datetime import datetime
from services.gg import create_messagea
def read_multiline(prompt: str) -> str: def read_multiline(prompt: str) -> str:
@ -24,43 +27,59 @@ def send_text_flow():
send_plain_email(to_addr, subject, body) send_plain_email(to_addr, subject, body)
def send_html_flow(): def send_html_flow(ids):
to_addr = input("Receiver email: ").strip() # to_addr = input("Receiver email: ").strip()
conn = sqlite3.connect("./files/rokky.db")
cursor = conn.cursor()
sku = ids
cursor.execute("""
SELECT *
FROM orders
WHERE orders_rokky = ?
""", (sku,))
rows = cursor.fetchall()
for row in rows:
print(row)
s = row[9]
s = s.replace(" ", "+", 1) # только первое вхождение после времени
dt = datetime.fromisoformat(s)
dates = dt.strftime("%Y-%m-%d %H:%M:%S")
data = { data = {
"company_name": "wstkeys", # "company_name": "wstkeys",
"order_id": "123", "order_id": row[1],
"customer_name": "4321", # "customer_name": "4321",
"currency": "USD", "currency": row[7],
"items": [ "items": [
{"name": "Game 1333", "quantity": 1, "price": 1330}, {"name": row[3], "quantity": 1, "price": row[8]},
], ],
"date": "23.03.2026 14:02", "date": dates,
"product_name": "Railroads Online - Pioneer DLC", "product_name": row[3],
"product_image": "https://s3.ggsel.com/gsellers-imgs-prod/e05c8d1f28e18f56334bf8e7e9f7b547.jpeg", "product_image": row[4],
"total_price": 20, "total_price": row[8],
"key": 'XXXX-XXXX-YYY23', "key": row[13],
"support_email": "wstkeys@gmail.com", "support_email": "wstkeys@gmail.com",
"year": 2026 "year": 2026
} }
to_addr = row[5]
send_html_email(to_addr, data) send_html_email(to_addr, data)
message = (
f"🔑 Ваш ключ: {row[13]}\n\n"
"📩 Копия ключа отправлена на вашу электронную почту.\n"
"💬 Если у вас возникнут вопросы — напишите нам.\n"
"⭐️ Нам очень важно ваше мнение, пожалуйста, оставьте отзыв."
)
create_messagea(row[1], message )
conn.close()
def main(): # send_html_flow(5388351)
print("1 - Send plain email")
print("2 - Send HTML email")
choice = input("Choose: ").strip()
if choice == "1":
send_text_flow()
elif choice == "2":
send_html_flow()
else:
print("Invalid choice")
if __name__ == "__main__":
main()

25
services/test.py Normal file
View File

@ -0,0 +1,25 @@
import sqlite3
from datetime import datetime
conn = sqlite3.connect("./files/rokky.db")
cursor = conn.cursor()
sku = '5388258'
cursor.execute("""
SELECT *
FROM orders
WHERE orders_rokky = ?
""", (sku,))
rows = cursor.fetchall()
for row in rows:
print(row[3])
s = row[8]
s = s.replace(" ", "+", 1) # только первое вхождение после времени
dt = datetime.fromisoformat(s)
result = dt.strftime("%Y-%m-%d %H:%M:%S")
print(result)
conn.close()

View File

@ -1,18 +1,20 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<body style="font-family: Arial, sans-serif; background:#0f0f0f; padding:20px; color:#fff;"> <body style="font-family: Arial, sans-serif; background:#080808; padding:20px; color:#fff;">
<table width="600" align="center" style="background:#111; padding:20px; border:1px solid #00cfff;"> <table width="600" align="center" style="background:#000000; padding:20px; border:1px solid #00cfff;">
<tr> <tr>
<td align="center"> <td align="center">
<!-- LOGO --> <!-- LOGO -->
<div style="text-align:center; margin-bottom:10px;"> <div style="text-align:center; margin-bottom:10px;">
<img src="https://wstkeys.top/images/10.png" alt="logo" <img src="https://wstkeys.top/images/10.png" alt="logo"
style="max-width:200px; height:auto;"> style="max-width:400px; height:auto;">
</div> </div>
<!--<h1 style="color:#00cfff; margin-bottom:5px;">{{company_name}}</h1>--> <!--<h1 style="color:#00cfff; margin-bottom:5px;">{{company_name}}</h1>-->
<p style="margin:0; color:#aaa; font-size:16px;">Спасибо за покупку в WST Keys (West Store Trusted Keys)</p> <p style="margin:0; color:#ffffff; font-size:16px; font-weight:bold;">
Спасибо за покупку в WST Keys (West Store Trusted Keys)
</p>
<hr style="border:1px solid #00cfff; margin:20px 0;"> <hr style="border:1px solid #00cfff; margin:20px 0;">

16
wg/wg_confs/wg0.conf Normal file
View File

@ -0,0 +1,16 @@
[Interface]
PrivateKey = yNlGhRShhVe9Jf+9PYA5cL1OcQq2K2rT8KsPGPfG50o=
Address = 10.66.66.15/32,fd42:42:42::15/128
DNS = 1.1.1.1,1.0.0.1
# Uncomment the next line to set a custom MTU
# This might impact performance, so use it only if you know what you are doing
# See https://github.com/nitred/nr-wg-mtu-finder to find your optimal MTU
# MTU = 1420
[Peer]
PublicKey = bcJDrYlhWls25zz9+bJcWiONw8Qfx1tai504+vKLcgQ=
PresharedKey = 40DSkC0TTySjBFyUj19++ngCdYxAHZaLnsrz8Ck9R2Q=
Endpoint = 85.208.110.167:50395
AllowedIPs = 0.0.0.0/0,::/0