-
Notifications
You must be signed in to change notification settings - Fork 2
/
server.py
162 lines (128 loc) · 5.05 KB
/
server.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
import requests
import json
import io
import os
import shutil
import time
import threading
import random
from flask import Flask, Response, request
from twilio.twiml.messaging_response import MessagingResponse
from twilio.twiml.voice_response import Record, VoiceResponse
import azure
import audio
app = Flask(__name__)
def analyze_sentiment(text):
"""Analyze sentiment of passed string
"""
key = app.config['AZURE_SUBSCRIPTION_KEY']
sentiment = azure.text_to_sentiment(text, key)
score = sentiment['documents'][0]['score']
return score
@app.route('/transcribe_action', methods=['POST'])
def handle_transcribe_action():
print("Handling transcribe action callback")
text = request.form.get("TranscriptionText")
return 0
@app.route('/music/<audiofile>', methods=['GET'])
def handle_audiofile_get(audiofile):
filename = "/tmp/response_{}.wav".format(audiofile)
print("Serving file {}".format(filename))
with open(filename, 'rb') as f:
audio_data = f.read()
return Response(audio_data, mimetype="audio/wav")
@app.route('/recording_status', methods=['POST'])
def handle_recording_status():
print("Handling recording status callback.")
audio_format = ".mp3"
url = request.form.get("RecordingUrl")
basename = url.split('/')[-1] # get unique filename
filename = "/tmp/{}{}".format(basename, audio_format)
r = requests.get(url + audio_format)
with open(filename, 'wb') as f:
shutil.copyfileobj(io.BytesIO(r.content), f)
print("Wrote mp3 out to file {}".format(filename))
filename_happy_music = './music/brandenburg.wav'
outputfile = "/tmp/response_{}.wav".format(basename)
audio.mixing_librosa(filename, filename_happy_music, outputfile)
audio_endpoint = "{}/music/{}".format(app.config['PUBLIC_URL'], basename)
response = VoiceResponse()
response.play(audio_endpoint)
response.say("Thanks. Goodbye.")
response.hangup()
return str(response)
@app.route('/record_action', methods=['POST'])
def handle_record_action():
print("Handling record action callback.")
# Generate temporary filename to store mp3 recording
audio_format = ".mp3"
url = request.form.get("RecordingUrl")
basename = url.split('/')[-1] # get unique filename
mp3_filename = "/tmp/{}{}".format(basename, audio_format)
# download recording from Twilio and write to file
time.sleep(0.5)
r = requests.get(url + audio_format)
with open(mp3_filename, 'wb') as f:
shutil.copyfileobj(io.BytesIO(r.content), f)
print("Wrote mp3 out to file {}".format(mp3_filename))
# convert mp3 file to wav file, then use Azure's speech to text
wav_filename = "/tmp/{}.wav".format(basename)
audio.mp3_to_wav(mp3_filename, wav_filename)
text = azure.wav_to_text(wav_filename, app.config['AZURE_REQUEST_ID'], app.config['AZURE_JWT'])
print("Azure speech to text returned: {}".format(text))
# analyze sentiment
sentiment = analyze_sentiment(text)
print("Sentiment score is: {}".format(sentiment))
# select music based on sentiment
if sentiment <= 0.5:
background_music = './music/imperial-march-quieter.wav'
else:
background_music = './music/brandenburg.wav'
# mix background music into call audio
outputfile = "/tmp/response_{}.wav".format(basename)
audio.mixing_librosa(wav_filename, background_music, outputfile)
# setup response to play file
audio_endpoint = "{}/music/{}".format(app.config['PUBLIC_URL'], basename)
response = VoiceResponse()
response.play(audio_endpoint)
response.say("Thanks. Goodbye.")
response.hangup()
# set timer to delete temporary files after 30sec
delay_seconds = 30
files = [mp3_filename, wav_filename, outputfile]
timer_delete_temp_files = threading.Timer(delay_seconds, delete_temp_files, args=files)
timer_delete_temp_files.start()
return str(response)
def delete_temp_files(*files):
for filename in files:
os.remove(filename)
print("Deleted {}".format(filename))
@app.route('/voice', methods=['GET', 'POST'])
def handle_voice():
"""Handle incoming voice calls."""
response = VoiceResponse()
response.say("Record a message and stay on the line when finished.")
response.record(timeout=2, action='/record_action', recordingStatusCallback='/recording_status')
print(response)
return str(response)
@app.route('/sms', methods=['GET', 'POST'])
def handle_sms():
"""Respond to incoming SMS with a simple text message."""
print(request.values)
body = request.values.get("Body")
score = analyze_sentiment(body)
print(score)
with open('responses', 'r') as f:
responses = json.load(f)
if score < 0.33333:
text = random.choice(responses['Negative'])
elif score < 0.66666:
text = random.choice(responses['Neutral'])
else:
text = random.choice(responses['Positive'])
resp = MessagingResponse()
resp.message(text)
return str(resp)
if __name__ == '__main__':
app.config.from_pyfile('config')
app.run(port=int(app.config['PORT']), debug=True)