本篇旨在將前一篇用 HTTP API 傳送 mp3 音訊的程式碼改成用 Bot 物件來實作.
本系列之前的文章參考 :
我將 Telegram Bot API 權杖 (token) 與聊天室識別碼 (chat_id) 都存放在環境變數檔 .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 音訊格式, 可在 App 上直接播放.
11. 利用 Bot 物件傳送音訊 :
新版 (v20+) 的 python-telegram-bot 套件使用非同步架構, 函式只要有呼叫 Bot 物件之方法都要用 async 修飾, 且要用 await 去呼叫 Bot 物件方法. 關於 Bot 物件用法參考本系列第二篇測試 :
(1). 傳送網路音訊 :
使用 Bot 物件傳送單一網路影片的程式碼如下 :
# telegram_send_web_audio_bot.py
import asyncio
from telegram import Bot
async def telegram_web_audio(token, chat_id, audio_url, caption=None, parse_mode='Markdown'):
bot=Bot(token=token)
try:
await bot.send_audio(
chat_id=chat_id,
audio=audio_url,
caption=caption,
parse_mode=parse_mode
)
print("Audio message sent successfully.")
return True
except Exception as e:
print(f'Telegram API 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='🎵 一起聽聽這首歌吧'
asyncio.run(telegram_web_audio(token, chat_id, audio_url, caption))
測試結果如下 :
>>> audio_url='https://yaohuang1966.github.io/media/glorious_days_clip.mp3'
>>> caption='🎵 一起聽聽這首歌吧'
>>> asyncio.run(telegram_web_audio(token, chat_id, audio_url, caption))
Message(audio=Audio(duration=11, file_id='CQACAgQAAxkDAAPGZ_tZsQl1KAm0JUvrQVV8HbuAvBEAAkcIAAJJWt1TD1EgCp7QdWk2BA', file_name='glorious_days_clip.mp3', file_size=176877, file_unique_id='AgADRwgAAkla3VM', mime_type='audio/mpeg'), caption='🎵 一起聽聽這首歌吧', channel_chat_created=False, chat=Chat(first_name='<我的名字>', id=<聊天室ID>, type=<ChatType.PRIVATE>, username='<我的 username>'), date=datetime.datetime(2025, 4, 13, 9, 15, 11, tzinfo=datetime.timezone.utc), delete_chat_photo=False, from_user=User(first_name='twstock', id=7938146214, is_bot=True, username='twstock168_bot'), group_chat_created=False, message_id=211, supergroup_chat_created=False)
Audio message sent successfully.
True
查看 App 有收到這首歌 :
使用 Bot 物件傳送多個音訊時須使用 InputMediaAudio 類別來打包這些音訊, 程式碼如下 :
# telegram_send_web_audios_bot.py
import asyncio
from telegram import Bot, InputMediaAudio
async def telegram_web_audios(token, chat_id, media_list, caption_list, parse_mode='Markdown'):
bot=Bot(token=token)
media_group=[]
for url, caption in zip(media_list, caption_list):
media_group.append(InputMediaAudio(
media=url,
caption=caption,
parse_mode=parse_mode
)
)
try:
await bot.send_media_group(chat_id=chat_id, media=media_group)
print('Audio group sent successfully.')
return True
except Exception as e:
print(f'Telegram API 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=['光輝歲月', '你的答案']
asyncio.run(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=['光輝歲月', '你的答案']
>>> asyncio.run(telegram_web_audios(token, chat_id, audio_urls, captions))
(Message(audio=Audio(duration=11, file_id='CQACAgQAAxkDAAPGZ_tZsQl1KAm0JUvrQVV8HbuAvBEAAkcIAAJJWt1TD1EgCp7QdWk2BA', file_name='glorious_days_clip.mp3', file_size=176877, file_unique_id='AgADRwgAAkla3VM', mime_type='audio/mpeg'), caption='光輝歲月', channel_chat_created=False, chat=Chat(first_name='<我的名字>', id=<聊天室ID>, type=<ChatType.PRIVATE>, username='<我的 username>'), date=datetime.datetime(2025, 4, 13, 13, 1, 1, tzinfo=datetime.timezone.utc), delete_chat_photo=False, from_user=User(first_name='twstock', id=7938146214, is_bot=True, username='twstock168_bot'), group_chat_created=False, media_group_id='13956394088384405', message_id=220, supergroup_chat_created=False), Message(audio=Audio(duration=22, file_id='CQACAgQAAxkDAAPHZ_tbuy8Iwqm0xeFtD-r7m4crAVoAApoHAAK7nN1T6wcAAe_BDvXyNgQ', file_name='your_answer_clip.mp3', file_size=665844, file_unique_id='AgADmgcAAruc3VM', mime_type='audio/mpeg', performer='黃霄雲', title='你的答案'), caption='你的答案', channel_chat_created=False, chat=Chat(first_name='<我的名字>', id=<聊天室ID>, type=<ChatType.PRIVATE>, username='yhhuang1966'), date=datetime.datetime(2025, 4, 13, 13, 1, 1, tzinfo=datetime.timezone.utc), delete_chat_photo=False, from_user=User(first_name='twstock', id=7938146214, is_bot=True, username='twstock168_bot'), group_chat_created=False, media_group_id='13956394088384405', message_id=221, supergroup_chat_created=False))
查看 App 有收到這兩首歌 :
(2). 傳送本機音訊 :
傳送本機音訊也是呼叫 Bot 物件的 send_audio() 方法, 但要先用 open() 開啟 mp3 檔, 將檔案參考傳給 audio 參數即可 :
# telegram_send_local_audio_bot.py
import asyncio
from telegram import Bot
async def telegram_local_audio(token, chat_id, audio_path, caption=None, parse_mode='Markdown'):
bot=Bot(token=token)
try:
with open(audio_path, 'rb') as audio_file:
await bot.send_audio(
chat_id=chat_id,
audio=audio_file,
caption=caption,
parse_mode=parse_mode
)
print("Audio message sent successfully.")
return True
except Exception as e:
print(f'Telegram API Error: {e}')
return False
if __name__ == '__main__':
token='YOUR TOKEN'
chat_id='YOUR CHAT ID'
audio_path='your_answer_clip.mp3'
caption='🎵 一起來聽你的答案'
asyncio.run(telegram_local_audio(token, chat_id, audio_path, caption
測試結果如下 :
>>> audio_path='your_answer_clip.mp3'
>>> caption='🎵 一起來聽你的答案'
>>> asyncio.run(telegram_local_audio(token, chat_id, audio_path, caption))
Message(audio=Audio(duration=22, file_id='CQACAgUAAxkDAAPeZ_u7puXuDAXCL8unhK5IRvr4KMUAArwYAAIU-uBXLrY47umaGaU2BA', file_name='your_answer_clip.mp3', file_size=665844, file_unique_id='AgADvBgAAhT64Fc', mime_type='audio/mpeg', performer='黃霄雲', title='你的答案'), caption='🎵 一起來聽你的答案', channel_chat_created=False, chat=Chat(first_name='<我的名字>', id=<聊天室ID>, type=<ChatType.PRIVATE>, username='<我的 username>'), date=datetime.datetime(2025, 4, 13, 13, 27, 2, tzinfo=datetime.timezone.utc), delete_chat_photo=False, from_user=User(first_name='twstock', id=7938146214, is_bot=True, username='twstock168_bot'), group_chat_created=False, message_id=222, supergroup_chat_created=False)
Audio message sent successfully.
True
查看 App 有收到這首歌 :
傳送本機多個音訊, 與上面傳送多個網路音訊一樣要用 InputMediaVideo 類別來將各音訊檔打包, 差別只是要先開啟音訊檔, 再將檔案參考打包成 InputMediaAudio 物件串列, 然後於 呼叫 Bot 物件的 send_media_group() 方法時把它傳給 media 參數即可. 完整程式碼如下 :
# telegram_send_local_audios_bot.py
import asyncio
from telegram import Bot, InputMediaAudio
async def telegram_local_audios(token, chat_id, audio_paths, captions, parse_mode='Markdown'):
bot=Bot(token=token)
media=[] # 儲存用 InputMediaAudio 打包後的音訊
files=[open(path, 'rb') for path in audio_paths] # 儲存所有開啟的音訊檔案
try:
for i, f in enumerate(files): # 建立 InputMediaAudio 物件串列
caption=captions[i] if i < len(captions) else None
media.append(InputMediaAudio(media=f, caption=caption, parse_mode=parse_mode))
await bot.send_media_group(chat_id=chat_id, media=media)
print('Audio group message sent successfully.')
return True
except Exception as e:
print(f'Telegram API Error: {e}')
return False
finally:
for f in files:
f.close()
if __name__ == '__main__':
token='YOUR TOKEN'
chat_id='YOUR CHAT ID'
audio_paths=['glorious_days_clip.mp3', 'your_answer_clip.mp3']
captions=['🎵 光輝歲月', '🎶 你的答案']
asyncio.run(telegram_local_audios(token, chat_id, audio_paths, captions))
測試結果如下 :
>>> audio_paths=['glorious_days_clip.mp3', 'your_answer_clip.mp3']
>>> captions=['🎵 光輝歲月', '🎶 你的答案']
>>> asyncio.run(telegram_local_audios(token, chat_id, audio_paths, captions))
(Message(audio=Audio(duration=11, file_id='CQACAgUAAxUHZ_vd96HtCw6rZqYGWC8G55JmDtsAAhUZAAIU-uBXfuyPNXaOhAABNgQ', file_name='glorious_days_clip.mp3', file_size=179078, file_unique_id='AgADFRkAAhT64Fc', mime_type='audio/mpeg', performer='Beyond', title='光輝歲月'), caption='🎵 光輝歲月', channel_chat_created=False, chat=Chat(first_name='<我的名字>', id=<聊天室ID>, type=<ChatType.PRIVATE>, username='<我的 username>'), date=datetime.datetime(2025, 4, 13, 15, 53, 27, tzinfo=datetime.timezone.utc), delete_chat_photo=False, from_user=User(first_name='twstock', id=7938146214, is_bot=True, username='twstock168_bot'), group_chat_created=False, media_group_id='13956476862917125', message_id=225, supergroup_chat_created=False), Message(audio=Audio(duration=22, file_id='CQACAgUAAxUHZ_vd91l_mZCQvrteW59nE_FxdxsAAhYZAAIU-uBXMPTgePwhh3c2BA', file_name='your_answer_clip.mp3', file_size=665844, file_unique_id='AgADFhkAAhT64Fc', mime_type='audio/mpeg', performer='黃霄雲', title='你的答案'), caption='🎶 你的答案', channel_chat_created=False, chat=Chat(first_name='<我的名字>', id=<聊天室ID>, type=<ChatType.PRIVATE>, username='<我的 username>'), date=datetime.datetime(2025, 4, 13, 15, 53, 27, tzinfo=datetime.timezone.utc), delete_chat_photo=False, from_user=User(first_name='twstock', id=7938146214, is_bot=True, username='twstock168_bot'), group_chat_created=False, media_group_id='13956476862917125', message_id=226, supergroup_chat_created=False))
Audio group message sent successfully.
True
查看 App 有收到這兩首歌 :
因為我已經用 MP3Tag 軟體更改光輝歲月的 ID3 Tag, 所以這次會顯示曲名與歌手了.
沒有留言 :
張貼留言