- language:python - sdk:compatibility - product:voice This guide will show how you can easily take a voicemail message from incoming callers, transcribe the recording, and email the transcription. We will use the [SignalWire Python SDK](/compatibility-api/sdks) to record a voicemail and transcribe it along with the [MailGun](https://www.mailgun.com/) API to send an email. What do I need to run this code? -- As we said before, there are a few packages and resources you will want to have ready to go before running this script. You can find out more information about them here! Once youve got these on hand, youre ready to go! - [The SignalWire Python SDK](/compatibility-api/sdks) - [MailGun](https://www.mailgun.com/) API to send an email. There are two ways you could run this script easily. The first way is through using our pre-built docker image for the script or by building your own. You could also run it through Flask! Here are some more resources around those: - [Docker](https://www.docker.com/get-started) - [Flask](https://flask.palletsprojects.com/en/2.0.x/) As with all guides and snippets, you will need your API credentials **(SignalWire Space URL, API Token, and Project ID)**. These can be found under the **API** tab of your SignalWire Space. For more information around that, check [here](/guides/navigating-your-space). Code Breakdown -- ### Setting Up Your Environment File 1. Copy from example.env and fill in your values 2. Save the new file as .env Your file should look something like this, where SIGNALWIRE_SPACE is the full name of your SignalWire Space. e.g.: example.signalwire.com, SIGNALWIRE_PROJECT is your SignalWire Project ID, and SIGNALWIRE_TOKEN is your SignalWire API token. SIGNALWIRE_SPACE= SIGNALWIRE_PROJECT= SIGNALWIRE_TOKEN= MAILGUN_DOMAIN= MAILGUN_API_TOKEN= EMAIL_FROM=info@yourdomain.com EMAIL_TO=youremail@yourdomain.com EMAIL_SUBJECT=Transcribed Voicemail ### The Code Itself Our first route is the entry point for all incoming calls. In this route, we will use [Say](/compatibility-api/cxml/voice/say) to play a quick prompt and [Record](/compatibility-api/cxml/voice/record) to take a message. We will redirect to the /hangup route when the recording is finished as specified by the action URL. We will also make use of recording status callbacks and transcription status callbacks so that SignalWire will send an http request to our specified routes when the recordings and transcriptions are complete. python # Entry point for incoming calls, prompts to leave a voice mail for processing. @app.route(/voice_entry, methods=[GET, POST]) def voice_entry(): # instantiate voice response response = VoiceResponse() # play voicemail prompt and record voicemail that will finish on # key response.say(Please leave a message at the beep. Press the pound key when finished.) response.record(finishOnKey=#, maxLength=1, action=/hangup, transcribe=true, transcribeCallback=/transcribe_webhook, recordingStatusCallback=/recording_webhook) # return response return str(response) Our next route /hangup is the action URL that will execute when the recording is complete. We will play a short message to say goodbye and then use [Hangup](/compatibility-api/cxml/voice/hangup) to end the call. python # Terminates the call @app.route(/hangup, methods=[GET,POST]) def hangup(): # instantiate voice response response = VoiceResponse() # say goodbye and hangup response.say(Thank you! Good Bye!) response.hangup() # return response return str(response) Now we will define a function send_email(body) that will utilize the MailGun API to send an email using the variables from our .env file. python # Sends the email provided using mailgun def send_email(body): return requests.post( https://api.mailgun.net/v3/ + os.environ[MAILGUN_DOMAIN] + /messages, auth=(api, os.environ[MAILGUN_API_TOKEN]), data={from: os.environ[EMAIL_FROM], to: [os.environ[EMAIL_TO]], subject: os.environ[EMAIL_SUBJECT], text: body }) This route /recording_webhook will be called when the recording is completed. We will use it for information purposes only - for the sake of printing to console all the necessary information about recordings. Read more about recording status callbacks in our [status callbacks super guide](/guides/signalwire-status-callbacks#recording-status-callbacks). python # The webhook that is called on recording updates @app.route(/recording_webhook, methods=[GET,POST]) def recording_webhook(): # For information only, and to show what is returned. pprint.pprint(request.values) return 200 Our last route/transcribe_webhook will be used to handle the transcription status callback when the transcription is complete. We will use the TranscriptionText parameter as the body in our send_email(body) function. python # The webhook that is called when a transcription is received, this will process the transcription actions. @app.route(/transcribe_webhook, methods=[GET,POST]) def transcribe_webhook(): # get all request values pprint.pprint(request.values) # Recording Information recording_duration = request.values.get(RecordingDuration) recording_url = request.values.get(RecordingUrl) # Send Email send_email(request.values.get(TranscriptionText)) return 200 Conclusion - After all is said and done, youll start receiving voicemail transcriptions of any incoming voicemail that has gone to whatever phone number(s) youve decided to run it on. And as we said, there are two ways you could run this. ### Build and Run on Docker 1. Use our pre-built image from Docker Hub docker pull signalwire/snippets-voicemail-transcription:latest (or build your own image) 1. Build your image docker build -t snippets-voicemail-transcription . 2. Run your image docker run --publish 5000:5000 --env-file .env snippets-voicemail-transcription 3. The application will run on port 5000 ### Build and Run Natively To run the application, execute export FLASK_APP=app.py then run flask run. You may need to use an SSH tunnel for testing this code if running on your local machine. – we recommend [ngrok](https://ngrok.com/). You can learn more about how to use ngrok [here](/guides/how-to-test-webhooks-with-ngrok). Sign Up Here If you would like to test this example out, [create a SignalWire account and Space](https://m.signalwire.com/signups/new?s=1). Please feel free to reach out to us on our [Community Slack](https://signalwire.community/) or create a Support ticket if you need guidance!