forked from deepgram-starters/flask-live-transcription
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathapp.py
265 lines (213 loc) · 10.3 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
import os
from flask import Flask, render_template, request, redirect, url_for
from flask_socketio import SocketIO
from dotenv import load_dotenv
import logging
from threading import Event
from deepgram import (
DeepgramClient,
DeepgramClientOptions,
LiveOptions,
Microphone, LiveTranscriptionEvents,
)
import requests
from send_email import *
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
load_dotenv()
app = Flask(__name__)
socketio = SocketIO(app)
# Set up client configuration
config = DeepgramClientOptions(
verbose=logging.DEBUG,
options={"keepalive": "true"}
)
# logging.basicConfig(filename='app.log')
# Initialize Deepgram client and connection
deepgram = DeepgramClient("", config)
dg_connection = deepgram.listen.live.v("1")
# Track transcription state
transcribing = False
transcription_event = Event()
def configure_deepgram():
options = LiveOptions(
smart_format=True,
language="en-US",
encoding="linear16",
channels=1,
sample_rate=16000,
diarize=True,
)
dg_connection.start(options)
def start_microphone():
microphone = Microphone(dg_connection.send)
microphone.start()
return microphone
# # Later, you can save the transcriptions to a file or concatenate them into a string
def save_transcriptions_to_file(file_path, transcriptions):
with open(file_path, 'w') as file:
for transcript in transcriptions:
file.write(transcript + '\n')
#
# def save_transcriptions_to_file(file_path, data):
# with open(file_path, 'w') as file:
# for entry in data:
# file.write(f"[Speaker:{entry['speaker']}] {entry['transcript']}\n")
def start_transcription_loop():
try:
global transcribing
while transcribing:
configure_deepgram()
# Open a microphone stream
microphone = start_microphone()
transcriptions = []
# def on_message(self, result, **kwargs):
# for word in result.channel.alternatives[0].words:
# speaker = word['speaker']
# transcript = word['word']
# transcriptions.append({"speaker": speaker, "transcript": transcript})
# socketio.emit('transcription_update', {'transcription': transcript})
def on_message(self, result, **kwargs):
transcript = result.channel.alternatives[0].transcript
# print(result.channel)
# print(result.channel.alternatives)
# print(result.channel.alternatives[0])
# print(result.channel.alternatives[0].transcript)
# print(result.channel.alternatives[0].words)
if len(transcript) > 0:
transcriptions.append(transcript)
socketio.emit('transcription_update', {'transcription': transcript})
dg_connection.on(LiveTranscriptionEvents.Transcript, on_message)
# Wait for the transcription to finish
transcription_event.wait()
transcription_event.clear()
# Finish the microphone and Deepgram connection
microphone.finish()
dg_connection.finish()
logging.info("Transcription loop finished.")
another = "\n".join(transcriptions)
# print(f"This is the transcript I generated for you: {transcript}")
save_transcriptions_to_file('transcriptions.txt', transcriptions)
ask_chat(another)
# print(transcriptions)
except Exception as e:
logging.error(f"Error: {e}")
def ask_chat(transcript):
url = "https://api.openai.com/v1/chat/completions"
print(f"my openai API key is {OPENAI_API_KEY}")
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {OPENAI_API_KEY}"
}
data = {
"model": "gpt-3.5-turbo",
"messages": [{"role": "user",
"content": f"""I'm a realtor. Your client just called me. You are my secretary. Under the
heading 'FOLLOW-UP ITEMS' list out what follow-up actions I should take after the call ends,
on behalf of my client, informed by the call transcript below. Examples of follow-up items
include: Property Research: If the client expressed interest in a specific property during the
call, I would conduct additional research on the property to gather more detailed information.
This may include reviewing property listings, assessing the property's condition,
checking comparable sales data, and gathering any relevant documents or disclosures. Follow-Up
Communication: Shortly after the call, I would send a follow-up email or text message to the
client to summarize our discussion, confirm any action items or appointments agreed upon,
and express my availability to assist further. Schedule Property Viewings: If the client
expressed interest in viewing one or more properties, I would work with them to schedule
appointments for property viewings at their convenience. I would coordinate with the property
owners or listing agents to arrange the visits. Prepare Property Information Packets: For
scheduled property viewings, I would prepare informational packets containing details about the
properties, including photos, floor plans, property descriptions, and any relevant neighborhood
information. Review Market Trends: I would review current market trends, recent property sales
data, and local market conditions to provide the client with insights into property values,
pricing strategies, and market dynamics. Follow-Up with Sellers: If the client expressed
interest in selling their current property, I would follow up with them to discuss the selling
process, market evaluation of their property, and steps to prepare their home for sale. Update
Client Records: I would update my client database or CRM system with the details of the
conversation, including any specific property preferences, contact information, and scheduled
appointments. Continue Client Relationship: I would maintain regular communication with the
client to provide updates on new listings, market changes, and relevant information to support
their real estate goals. Building a strong relationship with the client is essential for
long-term success in real estate. Afterwards, write an email from me to my client containing a
call summary and following up on items discussed during the call to remind them of how useful
realtors are, under the heading 'EMAIL'. Do not include any other information besides
'FOLLOW-UP ITEMS', the follow-up items, 'EMAIL', and the email. This is the call transcript:
{transcript}"""}],
"temperature": 0.7
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
with open('follow-ups.txt', "w") as file:
file.write(response.json()["choices"][0]["message"]["content"])
def reconnect():
try:
logging.info("Reconnecting to Deepgram...")
new_dg_connection = deepgram.listen.live.v("1")
# Configure and start the new Deepgram connection
configure_deepgram(new_dg_connection)
logging.info("Reconnected to Deepgram successfully.")
return new_dg_connection
except Exception as e:
logging.error(f"Reconnection failed: {e}")
return None
def on_disconnect():
logging.info("Client disconnected")
global dg_connection
if dg_connection:
dg_connection.finish()
dg_connection = None
logging.info("Cleared listeners and set dg_connection to None")
else:
logging.info("No active dg_connection to disconnect from")
@app.route('/')
def index():
return render_template('index.html')
@app.route('/unlocked_intel', methods=['GET','POST'])
def new_analysis():
if request.method == 'POST':
# Get the value of the text input field from the form
email_recipient = request.form['textInput']
# Do something with the text input, such as print it
drip_client(email_recipient)
print("email_sent")
return redirect(url_for('index'))
else:
followups = []
email_text = []
# Flag to indicate whether to start capturing lines
capture_followups = False
with open('follow-ups.txt', 'r') as file:
for line in file:
if "FOLLOW-UP ITEMS" in line:
# Start capturing lines
capture_followups = True
continue
elif "EMAIL" in line:
# Stop capturing lines
capture_followups = False
continue
if capture_followups:
followups.append(line.rstrip('\n')) # Remove newline character
else:
email_text.append(line.rstrip('\n')) # Remove newline character
transcript = []
with open('transcriptions.txt', 'r') as file:
for line in file:
transcript.append(line.rstrip('\n')) # Remove newline character
return render_template('unlocked.html', action_items=followups, email=email_text, transcription=transcript)
@socketio.on('disconnect')
def handle_disconnect():
socketio.start_background_task(target=on_disconnect)
@socketio.on('toggle_transcription')
def toggle_transcription(data):
global transcribing
action = data.get('action')
if action == 'start' and not transcribing:
# Start transcription
transcribing = True
socketio.start_background_task(target=start_transcription_loop)
elif action == 'stop' and transcribing:
# Stop transcription
transcribing = False
transcription_event.set()
if __name__ == '__main__':
logging.info("Starting SocketIO server.")
socketio.run(app, debug=True)