-
Notifications
You must be signed in to change notification settings - Fork 1.3k
feat: Add speaker name mapping to transcript segments in developer API and webhook #3962
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,7 @@ | |
| import database.conversations as conversations_db | ||
| import database.dev_api_key as dev_api_key_db | ||
| import database.action_items as action_items_db | ||
| import database.users as users_db | ||
|
|
||
| from models.memories import MemoryCategory, Memory, MemoryDB | ||
| from models.conversation import ( | ||
|
|
@@ -679,6 +680,29 @@ class CreateConversationFromTranscriptRequest(BaseModel): | |
| geolocation: Optional[Geolocation] = Field(default=None, description="Geolocation where conversation occurred") | ||
|
|
||
|
|
||
| def _add_speaker_names_to_segments(uid, conversations: list): | ||
| """Add speaker_name to transcript segments based on person_id mappings.""" | ||
| all_person_ids = set() | ||
| for conv in conversations: | ||
| for seg in conv.get('transcript_segments', []): | ||
| if seg.get('person_id'): | ||
| all_person_ids.add(seg['person_id']) | ||
|
|
||
| people_map = {} | ||
| if all_person_ids: | ||
| people_data = users_db.get_people_by_ids(uid, list(all_person_ids)) | ||
| people_map = {p['id']: p['name'] for p in people_data} | ||
|
|
||
| for conv in conversations: | ||
| for seg in conv.get('transcript_segments', []): | ||
| if seg.get('is_user'): | ||
| seg['speaker_name'] = 'User' | ||
| elif seg.get('person_id') and seg['person_id'] in people_map: | ||
| seg['speaker_name'] = people_map[seg['person_id']] | ||
| else: | ||
| seg['speaker_name'] = f"Speaker {seg.get('speaker_id', 0)}" | ||
|
|
||
|
|
||
| @router.get("/v1/dev/user/conversations", response_model=List[Conversation], tags=["developer"]) | ||
| def get_conversations( | ||
| start_date: Optional[datetime] = None, | ||
|
|
@@ -717,6 +741,8 @@ def get_conversations( | |
| if not include_transcript: | ||
| for conv in unlocked_conversations: | ||
| conv.pop('transcript_segments', None) | ||
| else: | ||
| _add_speaker_names_to_segments(uid, unlocked_conversations) | ||
|
||
|
|
||
| return unlocked_conversations | ||
|
|
||
|
|
@@ -822,6 +848,8 @@ def get_conversation_endpoint( | |
| # Remove transcript_segments if not requested | ||
| if not include_transcript: | ||
| conversation.pop('transcript_segments', None) | ||
| else: | ||
| _add_speaker_names_to_segments(uid, [conversation]) | ||
|
|
||
| return conversation | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -16,6 +16,7 @@ | |||||||||||||||||||||
| from models.conversation import Conversation | ||||||||||||||||||||||
| from models.users import WebhookType | ||||||||||||||||||||||
| import database.notifications as notification_db | ||||||||||||||||||||||
| import database.users as users_db | ||||||||||||||||||||||
| from utils.notifications import send_notification | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -31,6 +32,27 @@ def _json_serialize_datetime(obj: Any) -> Any: | |||||||||||||||||||||
| return obj | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| def _add_speaker_names_to_payload(uid, payload: dict): | ||||||||||||||||||||||
| """Add speaker_name to transcript segments in webhook payload.""" | ||||||||||||||||||||||
| segments = payload.get('transcript_segments', []) | ||||||||||||||||||||||
| if not segments: | ||||||||||||||||||||||
| return | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| person_ids = [seg.get('person_id') for seg in segments if seg.get('person_id')] | ||||||||||||||||||||||
| people_map = {} | ||||||||||||||||||||||
| if person_ids: | ||||||||||||||||||||||
| people_data = users_db.get_people_by_ids(uid, list(set(person_ids))) | ||||||||||||||||||||||
| people_map = {p['id']: p['name'] for p in people_data} | ||||||||||||||||||||||
|
Comment on lines
+41
to
+45
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The logic for collecting More importantly, this function
Suggested change
References
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| for seg in segments: | ||||||||||||||||||||||
| if seg.get('is_user'): | ||||||||||||||||||||||
| seg['speaker_name'] = 'User' | ||||||||||||||||||||||
| elif seg.get('person_id') and seg['person_id'] in people_map: | ||||||||||||||||||||||
| seg['speaker_name'] = people_map[seg['person_id']] | ||||||||||||||||||||||
| else: | ||||||||||||||||||||||
| seg['speaker_name'] = f"Speaker {seg.get('speaker_id', 0)}" | ||||||||||||||||||||||
|
Comment on lines
+35
to
+53
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| def conversation_created_webhook(uid, memory: Conversation): | ||||||||||||||||||||||
| toggled = user_webhook_status_db(uid, WebhookType.memory_created) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -41,6 +63,7 @@ def conversation_created_webhook(uid, memory: Conversation): | |||||||||||||||||||||
| webhook_url += f'?uid={uid}' | ||||||||||||||||||||||
| try: | ||||||||||||||||||||||
| payload = memory.as_dict_cleaned_dates() | ||||||||||||||||||||||
| _add_speaker_names_to_payload(uid, payload) | ||||||||||||||||||||||
|
||||||||||||||||||||||
| payload = _json_serialize_datetime(payload) | ||||||||||||||||||||||
| response = requests.post( | ||||||||||||||||||||||
| webhook_url, | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is nearly identical to
_add_speaker_names_to_payload()inbackend/utils/webhooks.py(lines 35-53). The logic for mapping speaker names is duplicated in both places.Consider extracting this common logic into a shared utility function (e.g., in
backend/utils/orbackend/database/) that both files can import and use. This would: