本篇紀錄如何用 Telegram Bot API 透過 HTTP 傳送音訊.
本系列之前的文章參考 :
我將 Telegram Bot API 權杖與聊天室識別碼都存放在環境變數檔 .env 裡面, 利用 dotenv 套件載入後再用 os 模組讀取出來放在 token 與 chat_id 變數裡 :
>>> from dotenv import load_dotenv
>>> load_dotenv()
True
>>> import os
>>> token=os.environ.get('TELEGRAM_TOKEN')
>>> chat_id=os.environ.get('TELEGRAM_ID')
# load_secrets_py
from dotenv import load_dotenv
import os
load_dotenv()
token=os.environ.get('TELEGRAM_TOKEN')
chat_id=os.environ.get('TELEGRAM_ID')
參考 :
Telegram 支援 mp3 與 m4a 音訊檔案傳送, 可在 Telegram App 上直接播放. 我在 GitHub 上準備了下面兩個 mp3 檔案做為測試用的標本 :
前者取自 Beyond 的 "光輝歲月" 前 11 秒片段; 後者則是取自黃霄雲 "你的答案" 前 22 秒片段. 可以下載後做為測試傳送本機 mp3 檔案之用. 以下測試將直接使用函式, 不再一步一步地在命令列測試.
10. 利用 HTTP API 傳送音訊 :
Telegram Bot API 傳送音訊的 API 是 sendAudio, 作法與傳送影片類似, 但多了 title (音樂標題) 與 performer (演唱者) 這兩個參數, 但其實並沒有效果 (因為 Telegram 預設會使用音訊檔的 metadata), 故以下測試不使用這兩個參數.
(1). 傳送網路音訊 :
傳送單一個 mp3 音訊的完整程式碼如下 :
# telegram_send_web_audio.py
import requests
def telegram_web_audio(token, chat_id, audio_url, caption=None, parse_mode='Markdown'):
url=f'https://api.telegram.org/bot{token}/sendAudio'
data={
'chat_id': chat_id,
'audio': audio_url,
'caption': caption,
'parse_mode': parse_mode,
}
try:
with requests.post(url, data=data) as r:
r.raise_for_status()
result=r.json()
if result.get('ok'):
print('Audio message sent successfully.')
return True
else:
print(f'Telegram API Error: {result}')
return False
except requests.exceptions.RequestException as e:
print(f'Request error: {e}')
return False
if __name__ == '__main__':
token='YOUR TOKEN'
chat_id='YOUR CHAT ID'
audio_url='https://yaohuang1966.github.io/media/glorious_days_clip.mp3'
caption='🎵 一起聽聽這首歌吧'
telegram_web_audio(token, chat_id, audio_url, caption, title, performer)
首先用 "光輝歲月" 的前奏 mp3 測試 :
>>> audio_url='https://yaohuang1966.github.io/media/glorious_days_clip.mp3'
>>> caption='🎵 一起聽聽這首歌吧'
>>> telegram_web_audio(token, chat_id, audio_url, caption, title, performer)
Audio message sent successfully.
True
查看 App 有收到這首歌, 但表演者顯示的卻是 'Unknown artist', 歌曲標題顯示的是 mp3 檔案名稱, 這是因為光輝歲月這首歌 mp3 檔的 metadata (ID3 標籤) 裡面的 Title 與 Artist 欄位空白所致 :
改用另一個 mp3 黃霄雲的 "你的答案" 測試 :
>>> audio_url='https://yaohuang1966.github.io/media/your_answer_clip.mp3'
>>> telegram_web_audio(token, chat_id, audio_url, caption, title, performer)
Audio message sent successfully.
True
結果曲名與歌手顯示正常, 因為這首歌的 ID3 標籤的 Title 與 Artist 欄位有設定 :
可以用 MP3tag 這個軟體去修改 ID3 標籤 :
如果要傳送多個音訊, API 就要改用 sendMediaGroup, 每個音訊要先與標題打包成字典串列, 轉成 JSON 字串後傳給 data 字典的 media 參數, 完整程式碼如下 :
# telegram_send_web_audios.py
import requests
def telegram_web_audios(token, chat_id, media_list, caption_list, parse_mode='Markdown'):
url=f'https://api.telegram.org/bot{token}/sendMediaGroup'
media=[{
'type': 'audio',
'media': media,
'caption': caption,
'parse_mode': parse_mode
} for media, caption in zip(media_list, caption_list)]
data={
'chat_id': chat_id,
'media': str(media).replace("'", '"')
}
try:
with requests.post(url, data=data) as r:
r.raise_for_status() # 若 status_code != 2xx 會拋出例外
result=r.json()
if result.get('ok'):
print('Message sent successfully.')
return True
else:
print(f'Telegram API Error: {result}')
return False
except Exception as e:
print(f'Request error: {e}')
return False
if __name__ == '__main__':
token='YOUR TOKEN'
chat_id='YOUR CHAT ID'
audio_urls=[
'https://yaohuang1966.github.io/media/glorious_days_clip.mp3',
'https://yaohuang1966.github.io/media/your_answer_clip.mp3'
]
captions=['光輝歲月', '你的答案']
telegram_web_audios(token, chat_id, audio_urls, captions)
測試結果如下 :
>>> audio_urls=[
'https://yaohuang1966.github.io/media/glorious_days_clip.mp3',
'https://yaohuang1966.github.io/media/your_answer_clip.mp3'
]
>>> captions=['光輝歲月', '你的答案']
>>> telegram_web_audios(token, chat_id, audio_urls, captions)
Message sent successfully.
True
查看 App 有收到這兩首歌 :
(2). 傳送本機音訊 :
傳送本機音訊所用的 API 與網路音訊的一樣, 傳送一個 mp3 檔使用 sendAudio; 傳送多個 mp3 檔使用 sendMidiaGroup, 傳送本機音訊就是多了開檔與關檔動作而已.
傳送一個音訊檔的程式碼如下 :
# telegram_send_local_audio.py
import requests
def telegram_local_audio(token, chat_id, audio_path, caption=None, parse_mode='Markdown'):
url=f'https://api.telegram.org/bot{token}/sendAudio'
data={
'chat_id': chat_id,
'caption': caption,
'parse_mode': parse_mode,
}
try:
with open(audio_path, 'rb') as f:
files={'audio': f}
with requests.post(url, data=data, files=files) as r:
r.raise_for_status()
result=r.json()
if result.get('ok'):
print('Message sent successfully.')
return True
else:
print(f'Telegram API Error: {result}')
return False
except Exception as e:
print(f'Request error: {e}')
return False
if __name__ == '__main__':
token='YOUR TOKEN'
chat_id='YOUR CHAT ID'
audio_path='your_answer_clip.mp3'
caption='🎵 一起來聽你的答案'
telegram_local_audio(token, chat_id, audio_path, caption)
測試結果如下 :
>>> audio_path='your_answer_clip.mp3'
>>> caption='🎵 一起來聽你的答案'
>>> telegram_local_audio(token, chat_id, audio_path, caption)
Message sent successfully.
True
查看 App 果然有收到這首歌 :
傳送多個本機檔案使用的 API 是 sendMediaGroup, 完整程式碼如下 :
# telegram_send_local_audios.py
import requests
def telegram_local_audios(token, chat_id, audio_paths, captions):
url=f'https://api.telegram.org/bot{token}/sendMediaGroup'
files={} # 儲存檔案物件
media=[] # 準備 media payload
for i, audio_path in enumerate(audio_paths):
key=f'media{i+1}'
f=open(audio_path, 'rb')
files[key]=f
item={
'type': 'audio',
'media': f'attach://{key}'
}
if i < len(captions):
item['caption']=captions[i]
media.append(item)
data={
'chat_id': chat_id,
'media': str(media).replace("'", '"') # 轉成 JSON 字串格式
}
multipart={
k: (f.name, f, 'audio/mpeg') for k, f in files.items()
}
try:
with requests.post(url, data=data, files=multipart) as r:
r.raise_for_status()
result=r.json()
if result.get('ok'):
print('Message sent successfully.')
return True
else:
print(f'Telegram API Error: {result}')
return False
except Exception as e:
print(f'Request error: {e}')
return False
finally:
for f in files.values():
f.close()
if __name__ == '__main__':
token='YOUR TOKEN'
chat_id='YOUR CHAT ID'
audio_paths=['glorious_days_clip.mp3', 'your_answer_clip.mp3']
captions=['🎵 光輝歲月', '🎶 你的答案']
telegram_local_audios(token, chat_id, audio_paths, captions)
請注意每個 mp3 音訊檔打包時 type 鍵要設為 audio, 而 multipart 的編碼格式要設為 audio/mpeg, 測試結果如下 :
>>> audio_paths=['glorious_days_clip.mp3', 'your_answer_clip.mp3']
>>> captions=['🎵 光輝歲月', '🎶 你的答案']
>>> telegram_local_audios(token, chat_id, audio_paths, captions)
Message sent successfully.
True
查看 App 有收到這兩首歌 :
沒有留言 :
張貼留言