Skip to content

Instantly share code, notes, and snippets.

@cvcore
Last active February 17, 2025 07:49
Show Gist options
  • Save cvcore/64762f37a749b29a66deece0826cea22 to your computer and use it in GitHub Desktop.
Save cvcore/64762f37a749b29a66deece0826cea22 to your computer and use it in GitHub Desktop.
Send Voicemail from Asterisk with Telegram Bot

Forward Voicemail from Asterisk with Telegram Bot

Installation

First, put the script to a common location e.g. /usr/local/bin/vm-post.py

Then, point your Asterisk mail command to this script to invoke it when a voice mail is received.

For example, in FreePBX:

image

The script will decode the text message (as configured from Asterisk) and the voice message (stored with wav encoding).

Since Telegram only accepts the .ogg format as voice message, the script also performs wav -> ogg conversion with ffmpeg.

Finally, change the telegram bot token and chat id in the tg_post_voicemail() function.

To test, dial an extension with voicemail enabled and leave a voice message. You should be able to receive it from your telegram chat window.

If it doesn't work for you, you can inspect the log from /tmp/vm_bot.log.

Note

The script tries to keep things simple and avoids introducing the telegram bot python package.

#!/usr/bin/env python3
import datetime
import email
import sys
from typing import Tuple, Any
import requests
import ffmpeg # from: ffmpeg-python package
def debug_log(log: str):
with open("/tmp/vm_bot.log", "a") as f:
f.write(f"{datetime.datetime.now()}\n")
f.write(f"{log}\n")
def decode_voicemail(vm_encoded_str: str) -> Tuple[str, Any]:
mailtext = ''
for line in vm_encoded_str:
mailtext = mailtext + line
try:
msg = email.message_from_string(mailtext)
text_msg = "NO TEXT MESSAGE FOUND"
voice_msgs = []
for payload in msg.get_payload():
if payload.get_content_type() == 'text/plain':
text_msg = payload.get_payload()
elif payload.get_content_type() == 'audio/x-wav':
voice_msgs.append(payload.get_payload(decode=True))
else:
debug_log(f"Unknown payload type: {payload.get_content_type()}")
except:
debug_log(f"Error decoding voicemail: {sys.exc_info()[0]}")
return text_msg, voice_msgs
def tg_post_voicemail(text_msg: str, voice_msgs: Any):
bot_token = "YOUR_BOT_TOKEN_GET_THIS_FROM_BOTFATHER"
chat_id = "YOUR_CHAT_ID"
# Post the text message
text_url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
text_params = {"chat_id": chat_id, "text": text_msg, "parse_mode": "markdown"}
resp = requests.post(text_url, data=text_params)
debug_log(f"Text message response: {resp}")
# Post each voice message
voice_url = f"https://api.telegram.org/bot{bot_token}/sendVoice"
for voice_msg in voice_msgs:
voice_params = {"chat_id": chat_id}
voice_msg_ogg = convert_wav_2_ogg(voice_msg)
files = {"voice": voice_msg_ogg}
resp = requests.post(voice_url, data=voice_params, files=files)
debug_log(f"Voice message response: {resp}")
def convert_wav_2_ogg(wavdata: bytearray) -> bytearray:
ffmpeg_process = (
ffmpeg
.input('pipe:', format='wav')
.output('pipe:', format='ogg', acodec='libopus')
.run_async(pipe_stdin=True, pipe_stdout=True)
)
out_ogg, _ = ffmpeg_process.communicate(input=wavdata)
return out_ogg
if __name__ == "__main__":
msg, voice_msgs = decode_voicemail(sys.stdin)
tg_post_voicemail(msg, voice_msgs)
debug_log(f"msg: {msg}\nvoice_msgs: {len(voice_msgs)}")
@Balrokmg
Copy link

Need help with "point your Asterisk mail command to this script to invoke it when a voice mail is received", cant understand how to((

@cvcore
Copy link
Author

cvcore commented Feb 13, 2025

Need help with "point your Asterisk mail command to this script to invoke it when a voice mail is received", cant understand how to((

Hi @Balrokmg , I uploaded a screenshot, hope it helps!

@Balrokmg
Copy link

Balrokmg commented Feb 14, 2025

Thx, but it doesnt work for me. May be because i am using an old version of FreeBPX?

@cvcore
Copy link
Author

cvcore commented Feb 14, 2025

Thx, but it doesnt work for me. May be because i am using an old version of FreeBPX?

@Balrokmg I haven't tested it on different versions. Maybe you can try to debug by dumping some logs to see if script is invoked and with which arguments.

@Balrokmg
Copy link

Balrokmg commented Feb 16, 2025

Last strings in my vm_bot.log:

2025-02-14 07:15:00.419574
Text message response: <Response [400]>
2025-02-14 07:43:05.694019
Text message response: <Response [400]>
2025-02-14 08:18:41.142118
Text message response: <Response [400]>
2025-02-14 08:28:47.346512
Text message response: <Response [400]>
2025-02-14 08:48:41.403831
Text message response: <Response [400]>

Which email system do you use? For me it is local postfix. Because after adding a mail command in config, emails didnt come.

@cvcore
Copy link
Author

cvcore commented Feb 16, 2025

@Balrokmg Your log shows the script is invoked, but unable to send the message - possibly due to incorrect bot token and/or chat id. Try to validate them with a vanilla python script.

IMO the email system is irreverent here, because the script is forwarding SMS via telegram, not via email.

@Balrokmg
Copy link

Bot token and chat id are correct. Another script on php works fine.

@Balrokmg
Copy link

I have no idea what next... i have checked everything twice...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment