Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Direct notifications from apps to omi with mentor example #1560

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 59 additions & 2 deletions backend/routers/notifications.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import os

from fastapi import APIRouter, Depends, Header, HTTPException
from fastapi import APIRouter, Depends, Header, HTTPException, Request

from database.redis_db import get_enabled_plugins
from utils.apps import get_available_app_by_id
from utils.plugins import send_plugin_notification
import database.notifications as notification_db
from models.other import SaveFcmTokenRequest
from utils.notifications import send_notification
from utils.other import endpoints as auth
from models.app import App


# logger = logging.getLogger('uvicorn.error')
Expand All @@ -18,7 +22,6 @@ def save_token(data: SaveFcmTokenRequest, uid: str = Depends(auth.get_current_us
notification_db.save_token(uid, data.dict())
return {'status': 'Ok'}


# ******************************************************
# ******************* TEAM ENDPOINTS *******************
# ******************************************************
Expand All @@ -33,3 +36,57 @@ def send_notification_to_user(data: dict, secret_key: str = Header(...)):
token = notification_db.get_token_only(uid)
send_notification(token, data['title'], data['body'], data.get('data', {}))
return {'status': 'Ok'}


@router.post('/v1/integrations/notification')
def send_app_notification_to_user(
request: Request,
data: dict,
):
# Check app-based auth
if 'aid' not in data:
raise HTTPException(status_code=400, detail='aid (app id) in request body is required')

# Get app details and convert to App model
app_data = get_available_app_by_id(data['aid'], data['uid'])
if not app_data:
raise HTTPException(status_code=404, detail='App not found')
app = App(**app_data)

# Check if user has app installed
user_enabled = set(get_enabled_plugins(data['uid']))
if data['aid'] not in user_enabled:
raise HTTPException(status_code=403, detail='User does not have this app installed')

# Verify request origin matches app webhook URL
if not app.works_externally():
raise HTTPException(status_code=400, detail='App is not an external integration')

app_webhook_url = app.external_integration.webhook_url if app.external_integration else None
if not app_webhook_url:
raise HTTPException(status_code=400, detail='App does not have a webhook URL configured')

# Extract base URLs for comparison
from urllib.parse import urlparse
app_base_url = urlparse(app_webhook_url).netloc

# Try to get the request origin from headers
request_origin = request.headers.get('origin') or request.headers.get('referer')
if not request_origin:
raise HTTPException(status_code=400, detail='Origin or Referer header is required when using app auth')

request_base_url = urlparse(request_origin).netloc
if app_base_url != request_base_url:
raise HTTPException(status_code=403, detail='Request origin does not match app webhook URL')

if not data.get('uid'):
raise HTTPException(status_code=400, detail='uid is required')
uid = data['uid']
token = notification_db.get_token_only(uid)

send_plugin_notification(token, app.name, app.id, data['message'])
return {'status': 'Ok'}




2 changes: 1 addition & 1 deletion backend/utils/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ def _single(app: App):
url += '?uid=' + uid

try:
response = requests.post(url, json={"session_id": uid, "segments": segments}, timeout=30)
response = requests.post(url, json={"session_id": uid, "segments": segments, "aid": app.id}, timeout=30)
if response.status_code != 200:
print('trigger_realtime_integrations', app.id, 'status: ', response.status_code, 'results:',
response.text[:100])
Expand Down
2 changes: 2 additions & 0 deletions plugins/.env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
API_BASE_URL=https://backend-dt5lrfkkoa-uc.a.run.app/
PLUGIN_BASE_URL= # add your plugin base url here
Loading