Meeting Minute Automation with AI. The system automatically transcribes meeting recordings, identifies participants, highlights decisions and tasks, and generates structured minutes. Integrates with Zoom, Google Meet, MS Teams, Slack, and corporate task management systems. ### Pipeline Architecture
Запись встречи (аудио/видео)
↓ VAD + диаризация (pyannote.audio)
↓ Транскрибация (Whisper large-v3)
↓ NLP-обработка (GPT-4o / Claude)
↓ Извлечение: решения / задачи / ответственные / дедлайны
↓ Генерация протокола (Markdown / Notion / Jira)
```### Transcription with diarization```python
import whisper
from pyannote.audio import Pipeline
import torch
class MeetingTranscriber:
def __init__(self):
self.whisper = whisper.load_model("large-v3", device="cuda")
self.diarizer = Pipeline.from_pretrained(
"pyannote/speaker-diarization-3.1",
use_auth_token="HF_TOKEN"
)
def transcribe_with_speakers(self, audio_path: str) -> list[dict]:
# Диаризация
diarization = self.diarizer(audio_path)
segments_by_speaker = [
{"speaker": turn.speaker, "start": turn.start, "end": turn.end}
for turn, _, _ in diarization.itertracks(yield_label=True)
]
# Транскрипция
result = self.whisper.transcribe(audio_path, language="ru", word_timestamps=True)
# Мёржим
transcript = []
for seg in result["segments"]:
speaker = self._find_speaker(seg["start"], segments_by_speaker)
transcript.append({
"speaker": speaker,
"start": seg["start"],
"end": seg["end"],
"text": seg["text"].strip()
})
return transcript
def _find_speaker(self, timestamp: float, diar_segments: list) -> str:
for s in diar_segments:
if s["start"] <= timestamp <= s["end"]:
return s["speaker"]
return "UNKNOWN"
```### NLP processing and structure extraction```python
from openai import AsyncOpenAI
import json
client = AsyncOpenAI()
async def extract_meeting_structure(transcript: list[dict]) -> dict:
# Форматируем транскрипт
formatted = "\n".join([
f"[{seg['speaker']} | {int(seg['start']//60):02d}:{int(seg['start']%60):02d}] {seg['text']}"
for seg in transcript
])
response = await client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "system",
"content": """Ты — ассистент для протоколирования встреч.
Проанализируй транскрипт и верни JSON:
{
"summary": "краткое резюме 2-3 предложения",
"participants": ["SPEAKER_00 = Иван Петров", ...],
"agenda_items": [{"topic": "...", "discussion": "..."}],
"decisions": [{"decision": "...", "context": "..."}],
"action_items": [{"task": "...", "owner": "...", "deadline": "..."}],
"next_meeting": "дата/условие следующей встречи если обсуждалась"
}"""
}, {
"role": "user",
"content": f"Транскрипт встречи:\n\n{formatted[:8000]}"
}],
response_format={"type": "json_object"}
)
return json.loads(response.choices[0].message.content)
```### Protocol generation```python
def format_meeting_minutes(structure: dict, transcript: list[dict]) -> str:
date = datetime.now().strftime("%d.%m.%Y")
duration_min = int(transcript[-1]["end"] / 60) if transcript else 0
md = f"""## Протокол встречи от {date}
**Продолжительность:** {duration_min} минут
**Участники:** {", ".join(structure.get("participants", []))}
### Краткое резюме
{structure.get("summary", "")}
### Принятые решения
"""
for d in structure.get("decisions", []):
md += f"- **{d['decision']}**\n _{d.get('context', '')}_\n\n"
md += "### Задачи\n\n"
md += "| Задача | Ответственный | Срок |\n|--------|--------------|------|\n"
for item in structure.get("action_items", []):
md += f"| {item['task']} | {item.get('owner', '—')} | {item.get('deadline', '—')} |\n"
return md
```### Integrations **Zoom:** via Zoom Recordings API - automatically receive mp4/m4a files after the meeting ends. **Google Meet:** via Google Workspace Events API + Cloud Storage for recordings. **MS Teams:** via Microsoft Graph API `/communications/callRecords`.```python
@app.post("/webhook/zoom/recording")
async def zoom_recording_webhook(payload: dict):
if payload["event"] == "recording.completed":
recording_url = payload["payload"]["object"]["recording_files"][0]["download_url"]
meeting_id = payload["payload"]["object"]["uuid"]
asyncio.create_task(process_meeting_recording(meeting_id, recording_url))
return {"status": "ok"}
```### Export```python
class MinutesExporter:
async def to_notion(self, minutes: str, database_id: str): ...
async def to_confluence(self, minutes: str, space_key: str): ...
async def to_jira_tasks(self, action_items: list, project_key: str): ...
async def to_slack(self, summary: str, channel_id: str): ...
async def to_email(self, minutes: str, recipients: list[str]): ...
```Timeline: Basic pipeline (transcription + NLP + Markdown) — 1–2 weeks. A full-fledged system with Zoom/Teams/Notion/Jira integrations — 4–6 weeks.