Meeting Minutes Made Easy: Summarize Key Points and Send Emails using Lyzr-Automata
Tags: chatgpt, machinelearning, python, lllm
Published: 2024-03-18 03:37:24

After every single meeting, capturing action items, summarizing key decisions, and keeping everyone in the loop with follow-up emails can be a time-consuming hassle. In this blog post, we’ll delve into the innovative workflow using Lyzr-Automata designed to summarize meetings and send email reports seamlessly.

## Before We Begin
Before we start, we need to get an Access Token to call Microsoft Graph API. Graph API is what we’ll be using to retrieve content and emails.

Steps to get Access Token and basic python setup template — [LINK](https://registeredapps.hosting.portal.azure.net/registeredapps/Content/1.0.2622.777/Quickstarts/en/PythonQuickstartPage.html?clientOptimizations=undefined&l=en.en-gb&trustedAuthority=https%3A%2F%2Fportal.azure.com&shellVersion=undefined)

Documentation of Graph API — [LINK](https://learn.microsoft.com/en-us/graph/api/overview?view=graph-rest-1.0)

We will be mainly using 2 APIs from Microsoft Graph

1. [Get callTranscript](https://learn.microsoft.com/en-us/graph/api/calltranscript-get?view=graph-rest-1.0&tabs=http) — To get the transcript of a particular meeting
2. [List attendanceRecords](https://learn.microsoft.com/en-us/graph/api/attendancerecord-list?view=graph-rest-1.0&tabs=http) — To list all the attendees in a meeting

Now let’s look at how to automate the process using Lyzr-Automata, given that we have retrieved results from these 2 APIs.

## Setup
Create a folder, set up a virtual environment and activate it

```
virtualenv my_env
source my_env/bin/activate
```

Install the following packages

```
lyzr-automata==0.1.2
python-dotenv==1.0.1
```
Setup .env file

```
OPENAI_API_KEY = "YOUR OPENAI API KEY"
EMAIL = "YOUR EMAIL ID"
PASSWORD = "YOUR APP PASSWORD"
```
_Note: To get your App Password, follow these steps [here](https://support.google.com/accounts/answer/185833?hl=en)_

## Get Started
**1.APIs to fetch data** (_token_ is the Microsoft Access Token)

```python
# Transcript API
def get_transcript_content(meeting_ID, transcript_ID, token):
    endpoint = "https://graph.microsoft.com/v1.0/me/onlineMeetings/{meeting}/transcripts/{transcript}/content?$format=text/vtt".format(meeting = meeting_ID, transcript = transcript_ID)
    api_result = requests.get(
        endpoint,
        headers={'Authorization': 'Bearer ' + token['access_token']},
        timeout=30,
    ).text
    return api_result

# Attendees API
def get_attendees_list(meeting_ID, report_ID, token):
    endpoint = "https://graph.microsoft.com/v1.0/me/onlineMeetings/{meeting}/attendanceReports/{report}/attendanceRecords".format(meeting = meeting_ID, report = report_ID)
    api_result = requests.get(
        endpoint,
        headers={'Authorization': 'Bearer ' + token['access_token']},
        timeout=30,
    ).json()

    attendance_values = api_result["value"]
    email_list = []
    for attendee in attendance_values:
        if attendee["emailAddress"]:
            email_list.append(attendee["emailAddress"])
    return email_list
```
**2.Load .env variables**

```python
from dotenv import load_dotenv
import os
from lyzr_automata.ai_models.openai import OpenAIModel
from lyzr_automata import Agent
from lyzr_automata import Task
from lyzr_automata.tasks.task_literals import InputType, OutputType
from lyzr_automata.tools.prebuilt_tools import send_email_by_smtp_tool

load_dotenv()

OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
EMAIL = os.getenv("EMAIL") # Email ID to send emails from
PASSWORD = os.getenv("PASSWORD") # App password of the email
```
**3.Initialize Text Model**

```python
# GPT 4 Text Model
open_ai_model_text = OpenAIModel(
    api_key= OPENAI_API_KEY,
    parameters={
        "model": "gpt-4-turbo-preview",
        "temperature": 0.2,
        "max_tokens": 1500,
    },
)

```
**4.Create our Summarizer**

```python
# Intructions for our Agent
summarizer_agent = Agent(
        prompt_persona="You are an intelligent agent that can summarize WebVTT content into a meaninful summary",
        role="WebVTT summarizer",
    )

input_transcript = get_transcript_content(meeting_ID, transcript_ID, token)

def email_draft_function(input_transcript):
    # Draft a summary Task
    summarize_content_task = Task(
        name="Transcript summarizer",
        agent=summarizer_agent,
        output_type=OutputType.TEXT,
        input_type=InputType.TEXT,
        model=open_ai_model_text,
        instructions="Summarize the WebVTT input into a meaningful Minutes of Meeting that captures immportant details and speakers. Return only the speaker name and their corresponding suammary [!IMPORTANT] Use HTML table to revise the email and beautify it", # Prompt Engineering
        log_output=True,
        enhance_prompt=False,
        default_input=input_transcript # Input for the task
    ).execute()

    return summarize_content_task # Return Output
```
**5.Send Email Task**

```python
input_email_list = get_attendees_list(meeting_ID, report_ID, token)

# Email config
def email_sender_function(summarize_content_task, input_email_list):
    email_sender = send_email_by_smtp_tool(
        username=EMAIL,
        password=PASSWORD,
        host="smtp.gmail.com",
        port=587,
        sender_email=EMAIL
    )

    # Send email Task
    send_email_task = Task(
        name = "Send Email Task",
        tool = email_sender,
        instructions="Send Email",
        model=open_ai_model_text,
        input_tasks = [summarize_content_task],
        default_input = input_email_list,
        previous_output = summarize_content_task
    ).execute()
```
**6. Setup your flask server and run!**

## FLOW Diagram

![Flow diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g03mdhu459hzzfgpmqth.jpg)

Want to create more of such amazing AI Workflows? Visit our website at [GitHub](https://github.com/LyzrCore/lyzr-automata) to learn more about Lyzr-Automata!

**Lyzr Website:** [https://www.lyzr.ai/](https://www.lyzr.ai/)
**Lyzr Community Channel:** [Discord](https://discord.com/invite/nm7zSyEFA2)