feat: add /user/install webhook + exclude admins from third-party API tasks
- Add POST /user/install endpoint handling Evotor app install/uninstall events: uninstall suspends the user and marks connection offline; reinstall reactivates a suspended account - Exclude admin and system role users from refresh_catalog, refresh_vk_catalog, and mirror_to_vk periodic tasks by joining users table and filtering role = 'user' Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
"""
|
||||
Evotor webhook endpoints.
|
||||
|
||||
POST /user/create — Evotor creates a new subscriber; we create/link a local user and return a token.
|
||||
POST /user/verify — Evotor verifies credentials for a user trying to log in via the Evotor interface.
|
||||
POST /user/token — Evotor sends us its own API token for the user.
|
||||
POST /user/create — Evotor creates a new subscriber; we create/link a local user and return a token.
|
||||
POST /user/verify — Evotor verifies credentials for a user trying to log in via the Evotor interface.
|
||||
POST /user/token — Evotor sends us its own API token for the user.
|
||||
POST /user/install — Evotor notifies about app install or uninstall for a user.
|
||||
"""
|
||||
import json
|
||||
import logging
|
||||
@@ -267,3 +268,51 @@ async def user_token(request: Request, db: Session = Depends(get_db)):
|
||||
db.commit()
|
||||
|
||||
return JSONResponse({})
|
||||
|
||||
|
||||
@router.post("/user/install")
|
||||
async def user_install(request: Request, db: Session = Depends(get_db)):
|
||||
"""Handle app install / uninstall events from Evotor."""
|
||||
if not _verify_secret(request):
|
||||
return JSONResponse({"error": "Unauthorized"}, status_code=401)
|
||||
|
||||
try:
|
||||
body = await request.json()
|
||||
except Exception:
|
||||
return JSONResponse({"error": "Invalid JSON"}, status_code=400)
|
||||
|
||||
evotor_user_id: str = body.get("userId", "")
|
||||
event_type: str = body.get("type", "").lower() # "install" or "uninstall"
|
||||
|
||||
if not evotor_user_id:
|
||||
return JSONResponse({"error": "userId required"}, status_code=400)
|
||||
|
||||
logger.info("user/install event type=%s userId=%s", event_type, evotor_user_id)
|
||||
|
||||
user = db.query(User).filter(User.evotor_user_id == evotor_user_id).first()
|
||||
if not user:
|
||||
# Unknown user — nothing to act on, but acknowledge the event
|
||||
return JSONResponse({})
|
||||
|
||||
now = datetime.now(timezone.utc).replace(tzinfo=None)
|
||||
|
||||
if event_type == "uninstall":
|
||||
user.status = UserStatusEnum.suspended
|
||||
user.updated_at = now
|
||||
conn = db.query(EvotorConnection).filter(
|
||||
EvotorConnection.evotor_user_id == evotor_user_id
|
||||
).first()
|
||||
if conn:
|
||||
conn.is_online = False
|
||||
conn.updated_at = now
|
||||
db.commit()
|
||||
logger.info("user suspended on uninstall: userId=%s", evotor_user_id)
|
||||
|
||||
elif event_type == "install":
|
||||
if user.status == UserStatusEnum.suspended:
|
||||
user.status = UserStatusEnum.active
|
||||
user.updated_at = now
|
||||
db.commit()
|
||||
logger.info("user reactivated on reinstall: userId=%s", evotor_user_id)
|
||||
|
||||
return JSONResponse({})
|
||||
|
||||
Reference in New Issue
Block a user