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.
|
Evotor webhook endpoints.
|
||||||
|
|
||||||
POST /user/create — Evotor creates a new subscriber; we create/link a local user and return a token.
|
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/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/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 json
|
||||||
import logging
|
import logging
|
||||||
@@ -267,3 +268,51 @@ async def user_token(request: Request, db: Session = Depends(get_db)):
|
|||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
return JSONResponse({})
|
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