mirror of
https://gitverse.ru/kpa39l/md2vk.git
synced 2026-09-29 09:55:04 +00:00
Compare commits
2 Commits
902ee91cf8
...
c7d7b9451c
| Author | SHA1 | Date | |
|---|---|---|---|
| c7d7b9451c | |||
| 6684d1653f |
@@ -13,6 +13,7 @@ COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/pytho
|
|||||||
COPY --from=builder /usr/local/bin /usr/local/bin
|
COPY --from=builder /usr/local/bin /usr/local/bin
|
||||||
|
|
||||||
COPY app/ app/
|
COPY app/ app/
|
||||||
|
COPY static/ static/
|
||||||
COPY .env.example .env
|
COPY .env.example .env
|
||||||
|
|
||||||
# Read-only rootfs — только /data для БД и /logs для аудита
|
# Read-only rootfs — только /data для БД и /logs для аудита
|
||||||
|
|||||||
+36
-1
@@ -6,11 +6,12 @@ import logging
|
|||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
|
|
||||||
from fastapi import FastAPI, Request
|
from fastapi import FastAPI, Request
|
||||||
from fastapi.responses import JSONResponse
|
from fastapi.responses import FileResponse, HTMLResponse, JSONResponse
|
||||||
|
|
||||||
from app.database import init_db
|
from app.database import init_db
|
||||||
from app.api.v1 import router as api_v1_router
|
from app.api.v1 import router as api_v1_router
|
||||||
from app.api.audit import AuditMiddleware
|
from app.api.audit import AuditMiddleware
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s")
|
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s")
|
||||||
logger = logging.getLogger("md2vk")
|
logger = logging.getLogger("md2vk")
|
||||||
@@ -38,6 +39,40 @@ app.add_middleware(AuditMiddleware)
|
|||||||
|
|
||||||
app.include_router(api_v1_router)
|
app.include_router(api_v1_router)
|
||||||
|
|
||||||
|
STATIC_DIR = Path(__file__).resolve().parent.parent / "static"
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/favicon.ico", include_in_schema=False)
|
||||||
|
async def favicon() -> FileResponse:
|
||||||
|
"""Favicon (SVG-бренд)."""
|
||||||
|
return FileResponse(STATIC_DIR / "favicon.svg", media_type="image/svg+xml")
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/", response_class=HTMLResponse, include_in_schema=False)
|
||||||
|
async def index() -> HTMLResponse:
|
||||||
|
"""Стартовая страница сервиса."""
|
||||||
|
return HTMLResponse(
|
||||||
|
"""<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>md2vk</title>
|
||||||
|
<style>
|
||||||
|
body { font-family: system-ui, sans-serif; max-width: 640px; margin: 80px auto; padding: 0 20px;
|
||||||
|
background: #0d1117; color: #e6edf3; }
|
||||||
|
h1 { color: #58a6ff; }
|
||||||
|
code { background: #1f2630; padding: 2px 6px; border-radius: 4px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>md2vk</h1>
|
||||||
|
<p>Сервис публикации Markdown на стену ВКонтакте.</p>
|
||||||
|
<p>API: <code>/api/v1</code> · <a href="/docs" style="color:#58a6ff">Swagger UI</a> · <a href="/redoc" style="color:#58a6ff">ReDoc</a></p>
|
||||||
|
</body>
|
||||||
|
</html>"""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.exception_handler(Exception)
|
@app.exception_handler(Exception)
|
||||||
async def global_exception_handler(request: Request, exc: Exception):
|
async def global_exception_handler(request: Request, exc: Exception):
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
# Как получить VK access_token и опубликовать первый пост (шпаргалка)
|
||||||
|
|
||||||
|
## 1. Создать VK-приложение (один раз, вручную, на сайте VK)
|
||||||
|
|
||||||
|
1. Открой https://id.vk.com/about/business → «VK ID» → «Мои приложения» (или https://dev.vk.com).
|
||||||
|
2. «Создать приложение» → тип **Standalone-приложение**.
|
||||||
|
3. После создания будет `client_id` (число, например `123456789`).
|
||||||
|
Адрес приложения/redirect можно оставить `https://oauth.vk.com/blank.html`.
|
||||||
|
|
||||||
|
## 2. Получить токен (открыть ссылку в браузере, войти в VK)
|
||||||
|
|
||||||
|
```
|
||||||
|
https://oauth.vk.com/authorize?client_id=<client_id>&scope=wall,offline&redirect_uri=https://oauth.vk.com/blank.html&response_type=token
|
||||||
|
```
|
||||||
|
|
||||||
|
После подтверждения браузер перейдёт на
|
||||||
|
`https://oauth.vk.com/blank.html#access_token=<TOKEN>&expires_in=0&user_id=<ID>`
|
||||||
|
(expires_in=0 — бессрочный, благодаря scope=offline).
|
||||||
|
|
||||||
|
- `user_id` — ID твоей страницы (нужен для `vk_user_id`).
|
||||||
|
- Токен — длинная строка, права `wall` (пост на стену), `offline` (долгоживущий).
|
||||||
|
|
||||||
|
## 3. Добавить аккаунт в md2vk (через Swagger)
|
||||||
|
|
||||||
|
Открой https://md2vk.nixg.ru/docs (введя пароль), найди `POST /api/v1/accounts`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"api_key": "<API-ключ из /opt/md2vk/secrets/estorozhenko_api_key.txt>",
|
||||||
|
"vk_user_id": <user_id из шага 2>,
|
||||||
|
"display_name": "<имя, например моя страница>",
|
||||||
|
"access_token": "<TOKEN из шага 2>",
|
||||||
|
"token_type": "user"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Ответ вернёт `"id": 1` — это `vk_account_id`.
|
||||||
|
|
||||||
|
## 4. Опубликовать пост
|
||||||
|
|
||||||
|
`POST /api/v1/publish`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"api_key": "<тот же ключ>",
|
||||||
|
"vk_account_id": 1,
|
||||||
|
"message_md": "Привет, мир! Это тестовый пост через md2vk."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Ответ: `"success": true, "url": "https://vk.com/wall<user_id>_<post_id>"`.
|
||||||
|
|
||||||
|
## Альтернатива: curl из terminal (без Swagger)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
API_KEY=$(cat /opt/md2vk/secrets/estorozhenko_api_key.txt)
|
||||||
|
# добавить аккаунт
|
||||||
|
curl -s -u estorozhenko:<пароль> -X POST https://md2vk.nixg.ru/api/v1/accounts \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d '{"api_key":"'$API_KEY'","vk_user_id":<user_id>,"display_name":"my","access_token":"<TOKEN>","token_type":"user"}'
|
||||||
|
# опубликовать
|
||||||
|
curl -s -u estorozhenko:<пароль> -X POST https://md2vk.nixg.ru/api/v1/publish \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-d '{"api_key":"'$API_KEY'","vk_account_id":1,"message_md":"Привет, мир! Это тестовый пост через md2vk."}'
|
||||||
|
```
|
||||||
|
|
||||||
|
> Пароль md2vk.nixg.ru — у пользователя (в конфиг/репо не пишем).
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><rect width="32" height="32" rx="6" fill="#0d1117"/><text x="16" y="22" font-family="Arial, sans-serif" font-size="16" font-weight="bold" fill="#58a6ff" text-anchor="middle">m</text></svg>
|
||||||
|
After Width: | Height: | Size: 248 B |
Reference in New Issue
Block a user