2025年4月8日 星期二

Python 學習筆記 : 用 Telegram Bot 取代 LINE Notify (三)

因為我的股票爬蟲程式需要傳送圖片到群組, 所以今天先來測試如何用 Telegram Bot API 傳送圖片, 然後再來修改爬蟲程式. 本系列之前的文章參考 : 


我的 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')   

參考 :


本篇旨在測試如何使用 HTTP POST 方法將圖片檔案傳送到聊天室裡. 


6. 利用 HTTP 的 POST 方法傳送圖片 :    

發出 HTTP 請求最好用的是 requests 模組, 先匯入 requests :

>>> import requests 

傳送圖片


(1). 傳送單一圖片 : 

Telegram Bot API 傳送圖片的 HTTP 網址格式如下 :  

https://api.telegram.org/bot{token}/sendPhoto    

定義一個嵌入 Telegram Bot 權杖的圖片網址變數 url :

>>> url=f'https://api.telegram.org/bot{token}/sendPhoto'    
>>> url    
'https://api.telegram.org/bot<我的權杖>/sendPhoto' 

其中嵌入變數 token 即為之前測試中取得的 Telegram Bot 的權杖. 

首先來測試傳送網路上的圖片, 例如下面這張 Wiki 上的 Lenna 照片 :





定義圖片網址變數 :

>>> photo = 'https://upload.wikimedia.org/wikipedia/zh/thumb/3/34/Lenna.jpg/300px-Lenna.jpg'    
注意, 圖片必須是能直接存取的公開圖檔, 不能有防盜連或驗證機制.

然後定義 HTTP 請求要攜帶的變數字典 data, 可用的鍵與說明如下表 :


 data 字典的鍵  說明
chat_id 接收訊息的聊天室 (個人或群組) ID 
photo 要傳送的圖片, Telegram 上已存在的 file_id 或透過 multipart/form-data 模式傳送的本機圖片檔案
caption 圖片附帶的標題文字說明 (最長 1024 個字元)
parse_mode caption 格式 : "Markdown" 或 "HTML", 預設 None (純文字)
disable_notification 關閉圖片送達通知音, True (靜音發送訊息) 或 False(預設)
reply_to_message_id 指定這張圖片回覆的某則訊息之 ID
allow_sending_without_reply True=即使指定的 reply_to_message_id 無效也會照常傳送
protect_content True=禁止此訊息被轉傳與儲存 (僅群組與頻道有效)


其中 chat_id 與 photo 是必要的鍵, 例如 : 

>>> data={'chat_id': chat_id, 'photo': photo}    

其中 chat_id 鍵為聊天室識別碼, photo 鍵為圖片網址, 這樣就可以呼叫 requests 的 post() 函式並傳入 url 與 data 參數提出 POST 請求 : 

>>> r=requests.post(url, data=data)    

傳回值為一個儲存 JSON 格式回應字串的 Response 物件, 呼叫其 json() 方法會將 JSON 字串轉成字典型態傳回 : 

>>> r.json()  
{'ok': True, 'result': {'message_id': 28, 'from': {'id': 7938146214, 'is_bot': True, 'first_name': 'twstock', 'username': 'twstock168_bot'}, 'chat': {'id': <聊天室識別碼>, 'first_name': '<我的名字>', 'username': '<我的 username>', 'type': 'private'}, 'date': 1744102311, 'photo': [{'file_id': 'AgACAgQAAxkDAAMcZ_Tjp_hAlv-3qWVBwQ-jkZQHwv0AApKtMRtu9CVR606iM07xqbsBAAMCAANzAAM2BA', 'file_unique_id': 'AQADkq0xG270JVF4', 'file_size': 1964, 'width': 90, 'height': 90}, {'file_id': 'AgACAgQAAxkDAAMcZ_Tjp_hAlv-3qWVBwQ-jkZQHwv0AApKtMRtu9CVR606iM07xqbsBAAMCAANtAAM2BA', 'file_unique_id': 'AQADkq0xG270JVFy', 'file_size': 21503, 'width': 300, 'height': 300}]}}

可見此字典紀錄了此次傳送之圖檔的識別碼, 尺寸, 檔案大小等資訊. 

這時去查看 Telegram App 就會看到所傳送的圖檔了 :




也可以用 caption 鍵設定圖片標題, 例如 :

>>> data={'chat_id': chat_id, 'photo': photo, 'caption': 'Lenna'}   
>>> r=requests.post(url, data=data)   

結果如下 :




可見圖片標題的位置是放在底下. 

圖片標題也可以用 Markdown 語法, 這時要將 parse_mode 鍵設為 "Markdown" :

>>> data={
    'chat_id': chat_id,
    'photo': photo_url,
    'caption': '_Lena Söderberg_',
    'parse_mode': 'Markdown'
    }  
>>> r=requests.post(url, data=data)   

此處 caption 值前後的底線是 Markdown 中的斜體語法, 結果如下 :




可見標題確實變成斜體了. 也可以用 HTML 格式, 例如 :

>>> data={
    'chat_id': chat_id,
    'photo': photo_url,
    'caption': '<i>Lena Söderberg</i>',
    'parse_mode': 'HTML'
    }   
>>> r=requests.post(url, data=data)     

此處標題前後的 <i> 與 </i> 是 HTML 斜體語法, 結果與上面 Markdown 的相同. 

茲將上面程式碼寫成如下函式 telegram_web_image() :

import requests

def telegram_web_image(token, chat_id, photo, caption=None, parse_mode='Markdown'):
    url=f'https://api.telegram.org/bot{token}/sendPhoto'
    data={
        'chat_id': chat_id,
        'photo': photo,
        '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('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

>>> photo='https://upload.wikimedia.org/wikipedia/zh/thumb/3/34/Lenna.jpg/300px-Lenna.jpg'   
>>> telegram_web_image(token, chat_id, photo) 
Message sent successfully.
True

結果與上面一樣. 

除了傳送網路上的圖片外, 也可以傳送本機上的圖片, 傳送檔案要改用 HTTP 的 multipart/form-data 格式, 只要用 rb 模式呼叫 open() 開啟圖檔後將檔案參考放在鍵為 photo 的字典中, 然後在呼叫 requests.post() 時將此檔案參考字典傳給 files 參數即可, requests.post() 函式看到 files 參數就會使用 HTTP 的 multipart/form-data 格式來傳送所附的檔案.

我在目前工作目錄下有一個貓咪圖片 cat2.jpg :

data 參數只要指定聊天室 ID 與圖片標題 : 

>>> data={
    'chat_id': chat_id,
    'caption': '可愛的貓咪'
    }   

然後用 open() 開啟圖檔, 並將其參考指定給 files 字典的 photo 鍵 :

>>> photo=open('cat2.jpg', 'rb')    # 開啟圖檔傳回檔案參考
>>> files={'photo': photo}     # 檔案參考字典

然後呼叫 requests.post() 時將圖檔字典傳給 files 參數 : 

>>> r=requests.post(url, data=data, files=files)     # 傳入 files 參數
>>> photo.close()   

結果如下 : 



茲將上面程式碼寫成如下函式 telegram_local_image() :

import requests

def telegram_local_image(token, chat_id, photo, caption=None, parse_mode='Markdown'):
    url=f'https://api.telegram.org/bot{token}/sendPhoto'
    data={
        'chat_id': chat_id,
        'caption': caption,
        'parse_mode': parse_mode
        }
    try:
        with open(photo, 'rb') as f:
            files={'photo': 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 requests.exceptions.RequestException as e:
        print(f'Request error: {e}')
        return False

>>> photo='cat2.jpg' 
>>> telegram_local_image(token, chat_id, photo)   
Message sent successfully.
True

結果與上面一樣. 


(2). 傳送多的圖片 : 

也可以傳送多個圖檔, 這時 API 網址要改為 MediaGroup, 網址格式如下 :

https://api.telegram.org/bot{token}/sendMediaGroup   

定義一個嵌入 Telegram Bot 權杖的圖片網址變數 url :

>>> url=f'https://api.telegram.org/bot{token}/sendMediaGroup'

我找了之前放在 GitHub 的測試圖片, 網址如下 :


然後為此兩張圖片定義一個字典串列, 每一個字典代表一張圖片, 必要的鍵是 type 與 media, 其中 type 鍵值為 'photo' (如果是影片則為 'video'), media 鍵的值就是網址 (必須是能直接存取的公開圖檔, 不能有防盜連或驗證機制) 或已上傳到 Telegram 的 file_id, 圖片標題相關的 caption 與 parse_mode 鍵則可有可無, 例如 : 

>>> media=[
    {"type": "photo",
     "media": "https://yaohuang1966.github.io/images/cat.jpg",
     "caption": "**可愛的小咪**",
     "parse_mode": "Markdown"},
    {"type": "photo",
     "media": "https://yaohuang1966.github.io/images/orchid.jpg",
     "caption": "**蘭花**",
     "parse_mode": "Markdown"}    
     ]   

然後定義字典變數 data, 必要的兩個鍵是 chat_id 與 media (值為 JSON 字串), 將上面的 media 串列用 str() 轉成字串後把單引號改成雙引號後做為 media 鍵之值, 與

>>> data={
    'chat_id': chat_id,
    'media': str(media).replace("'", '"')
    }   

注意, 即使 media 字典串列中的鍵都是用雙引號, 經過 str() 轉成字串後都會變成單引號, 但 JSON 格式要求鍵一定要用雙引號, 不可用單引號, 所以上面用 replace() 是必要的. 最後將 data 傳給 requests.post() 即可 :

>>> r=requests.post(url, data=data)   
>>> r.json()   
{'ok': True, 'result': [{'message_id': 66, 'from': {'id': 7938146214, 'is_bot': True, 'first_name': 'twstock', 'username': 'twstock168_bot'}, 'chat': {'id': <聊天室ID>, 'first_name': '<我的名字>', 'username': '<我的 username>', 'type': 'private'}, 'date': 1744199834, 'media_group_id': '13953598677847773', 'photo': [{'file_id': 'AgACAgQAAxUHZ_ZdsT7IDVJhtUCxnXNFh_cudJgAAhW4MRtSC7VT0zHgt9QirCMBAAMCAANzAAM2BA', 'file_unique_id': 'AQADFbgxG1ILtVN4', 'file_size': 1120, 'width': 90, 'height': 57}, {'file_id': 'AgACAgQAAxUHZ_ZdsT7IDVJhtUCxnXNFh_cudJgAAhW4MRtSC7VT0zHgt9QirCMBAAMCAANtAAM2BA', 'file_unique_id': 'AQADFbgxG1ILtVNy', 'file_size': 10157, 'width': 320, 'height': 204}], 'caption': '可愛的小咪'}, {'message_id': 67, 'from': {'id': 7938146214, 'is_bot': True, 'first_name': 'twstock', 'username': 'twstock168_bot'}, 'chat': {'id': <聊天室ID>, 'first_name': '<我的名字>', 'username': '<我的 username>', 'type': 'private'}, 'date': 1744199834, 'media_group_id': '13953598677847773', 'photo': [{'file_id': 'AgACAgQAAxUHZ_Zgmtac22EDmiPs9y7K1GvmInkAAsS3MRs0HLRTjJ5CHHFKag8BAAMCAANzAAM2BA', 'file_unique_id': 'AQADxLcxGzQctFN4', 'file_size': 1396, 'width': 90, 'height': 44}, {'file_id': 'AgACAgQAAxUHZ_Zgmtac22EDmiPs9y7K1GvmInkAAsS3MRs0HLRTjJ5CHHFKag8BAAMCAANtAAM2BA', 'file_unique_id': 'AQADxLcxGzQctFNy', 'file_size': 19517, 'width': 320, 'height': 156}, {'file_id': 'AgACAgQAAxUHZ_Zgmtac22EDmiPs9y7K1GvmInkAAsS3MRs0HLRTjJ5CHHFKag8BAAMCAAN4AAM2BA', 'file_unique_id': 'AQADxLcxGzQctFN9', 'file_size': 48815, 'width': 600, 'height': 292}], 'caption': '蘭花'}]}

檢視 Telegram App 果然收到兩張圖片訊息 : 




我將上面的程序寫成如下的 telegram_web_images() 函式 :

def telegram_web_images(token, chat_id, media_list, caption_list):
    url=f'https://api.telegram.org/bot{token}/sendMediaGroup'
    media=[{
            'type': 'photo',
            'media': media,
            'caption': caption,
            'parse_mode': 'Markdown'
            }
        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, timeout=10) 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 requests.exceptions.RequestException as e:
        print(f'Request error: {e}')
        return False

此函式使用串列生成式從 media_list 與 caption_list 串列產生 media 字典串列, 當 media_list 與 caption_list 只有一個元素時就是傳送單一圖片 :

>>> media_list=['https://yaohuang1966.github.io/images/cat.jpg']   
>>> caption_list=['可愛的小咪']   
>>> telegram_web_images(token, chat_id, media_list, caption_list)      
Message sent successfully.
True

當 media_list 與 caption_list 有多個元素時就是傳送多個圖片 :

>>> media_list=['https://yaohuang1966.github.io/images/cat.jpg',
            'https://yaohuang1966.github.io/images/orchid.jpg']   
>>> caption_list=['可愛的小咪', '蘭花']   
>>> telegram_web_images(token, chat_id, media_list, caption_list)    
Message sent successfully.
True

結果與上面一樣. 

如果要傳送本機的多個圖檔, 那麼呼叫 requests.post() 時就要指定 files 參數, 這樣就會使用 multipart/form-data 格式來傳送圖檔, 語法如下 :

r=requests.post(url, data=data, files=multipart) 

準備 data 與 files 參數的程序較傳送單一圖檔時複雜, 首先須建立一個圖檔字典 files 儲存檔案參考, 然後利用它製作 media 字典串列並將其轉成 JSON 字串後指定給 data 字典的 media 鍵, 最後從 files 字典製作 multipart 字典傳給 requests.post() 的 files 參數. 

我在目前工作目錄下準備了三張貓咪圖片 cat1.jpg, cat2.jpg, 與 cat3.jpg, 用 open() 開啟後分別指定給自訂鍵名組成一個圖檔字典 :

>>> files={
    'media1': open('cat1.jpg', 'rb'),
    'media2': open('cat2.jpg', 'rb'),
    'media3': open('cat3.jpg', 'rb'),
    }  

定義 media 字典串列, 每個字典須指定 type 與 media 鍵 (caption 鍵可有可無), type 鍵之值為 'photo', media 鍵之值為 'attach://' 後面串接上面圖檔字典中個圖片之自訂鍵名 :

>>> media=[
    {'type': 'photo', 'media': 'attach://media1', 'caption': '貓咪 1'},
    {'type': 'photo', 'media': 'attach://media2', 'caption': '貓咪 2'},
    {'type': 'photo', 'media': 'attach://media3', 'caption': '貓咪 3'},
    ]   

然後將此 media 字典串列用 str() 序列化後轉成 JSON 字串指定給 media 鍵 : 

>>> data={
    'chat_id': chat_id,
    'media': str(media).replace("'", '"') 
    }

注意, 此處 replace() 是必要的, 因為 media 鍵的值必須是 JSON 格式字串, 但是用 str() 將字典轉成字串時, 鍵值都會用單引號括起來, 這不符合 JSON 格式要求 (JSON 的鍵必須用雙引號括起來), 檢視 data 字典 :

>>> data  
{'chat_id': '7742981072', 'media': '[{"type": "photo", "media": "attach://media1", "caption": "貓咪 1"}, {"type": "photo", "media": "attach://media2", "caption": "貓咪 2"}, {"type": "photo", "media": "attach://media3", "caption": "貓咪 3"}]'}

可見 media 的值都是雙引號括起來了. 

最後利用字典生成式從 files 字典建立 multipart 字典 : 

>>> multipart={k: (f.name, f, 'image/jpeg') for k, f in files.items()}  
>>> multipart  
{'media1': ('cat1.jpg', <_io.BufferedReader name='cat1.jpg'>, 'image/jpeg'), 'media2': ('cat2.jpg', <_io.BufferedReader name='cat2.jpg'>, 'image/jpeg'), 'media3': ('cat3.jpg', <_io.BufferedReader name='cat3.jpg'>, 'image/jpeg')}

這樣便可呼叫 requests.post() 並把 data 字典與 multipart 字典分別傳給 data 與 files 參數了 :

>>> r=requests.post(url, data=data, files=multipart)   
>>> r.json()   
{'ok': True, 'result': [{'message_id': 90, 'from': {'id': 7938146214, 'is_bot': True, 'first_name': 'twstock', 'username': 'twstock168_bot'}, 'chat': {'id': <聊天室ID>, 'first_name': '<我的名字>', 'username': '<我的 username>', 'type': 'private'}, 'date': 1744276157, 'media_group_id': '13954209257219933', 'photo': [{'file_id': 'AgACAgUAAxUHZ_eKuzGsDrmHcOe8XMClagTnAAHHAAKAwjEbBW64V_EWQQJaJNhaAQADAgADcwADNgQ', 'file_unique_id': 'AQADgMIxGwVuuFd4', 'file_size': 1394, 'width': 90, 'height': 60}, {'file_id': 'AgACAgUAAxUHZ_eKuzGsDrmHcOe8XMClagTnAAHHAAKAwjEbBW64V_EWQQJaJNhaAQADAgADbQADNgQ', 'file_unique_id': 'AQADgMIxGwVuuFdy', 'file_size': 18479, 'width': 320, 'height': 213}, {'file_id': 'AgACAgUAAxUHZ_eKuzGsDrmHcOe8XMClagTnAAHHAAKAwjEbBW64V_EWQQJaJNhaAQADAgADeAADNgQ', 'file_unique_id': 'AQADgMIxGwVuuFd9', 'file_size': 94085, 'width': 800, 'height': 533}, {'file_id': 'AgACAgUAAxUHZ_eKuzGsDrmHcOe8XMClagTnAAHHAAKAwjEbBW64V_EWQQJaJNhaAQADAgADeQADNgQ', 'file_unique_id': 'AQADgMIxGwVuuFd-', 'file_size': 241570, 'width': 1280, 'height': 853}, {'file_id': 'AgACAgUAAxUHZ_eKuzGsDrmHcOe8XMClagTnAAHHAAKAwjEbBW64V_EWQQJaJNhaAQADAgADdwADNgQ', 'file_unique_id': 'AQADgMIxGwVuuFd8', 'file_size': 540510, 'width': 2250, 'height': 1500}], 'caption': '貓咪 1'}, {'message_id': 91, 'from': {'id': 7938146214, 'is_bot': True, 'first_name': 'twstock', 'username': 'twstock168_bot'}, 'chat': {'id': <聊天室ID>, 'first_name': '<我的名字>', 'username': '<我的 username>', 'type': 'private'}, 'date': 1744276157, 'media_group_id': '13954209257219933', 'photo': [{'file_id': 'AgACAgUAAxUHZ_eKvAi3dvXSZMjm4zc5H0ucywUAAoLCMRsFbrhXGCZ9_AoDXBMBAAMCAANzAAM2BA', 'file_unique_id': 'AQADgsIxGwVuuFd4', 'file_size': 1366, 'width': 90, 'height': 60}, {'file_id': 'AgACAgUAAxUHZ_eKvAi3dvXSZMjm4zc5H0ucywUAAoLCMRsFbrhXGCZ9_AoDXBMBAAMCAANtAAM2BA', 'file_unique_id': 'AQADgsIxGwVuuFdy', 'file_size': 20757, 'width': 320, 'height': 213}, {'file_id': 'AgACAgUAAxUHZ_eKvAi3dvXSZMjm4zc5H0ucywUAAoLCMRsFbrhXGCZ9_AoDXBMBAAMCAAN4AAM2BA', 'file_unique_id': 'AQADgsIxGwVuuFd9', 'file_size': 82754, 'width': 800, 'height': 533}, {'file_id': 'AgACAgUAAxUHZ_eKvAi3dvXSZMjm4zc5H0ucywUAAoLCMRsFbrhXGCZ9_AoDXBMBAAMCAAN5AAM2BA', 'file_unique_id': 'AQADgsIxGwVuuFd-', 'file_size': 185302, 'width': 1280, 'height': 853}, {'file_id': 'AgACAgUAAxUHZ_eKvAi3dvXSZMjm4zc5H0ucywUAAoLCMRsFbrhXGCZ9_AoDXBMBAAMCAAN3AAM2BA', 'file_unique_id': 'AQADgsIxGwVuuFd8', 'file_size': 719975, 'width': 2560, 'height': 1707}], 'caption': '貓咪 2'}, {'message_id': 92, 'from': {'id': 7938146214, 'is_bot': True, 'first_name': 'twstock', 'username': 'twstock168_bot'}, 'chat': {'id': <聊天室ID>, 'first_name': '<我的名字>', 'username': '<我的 username>', 'type': 'private'}, 'date': 1744276157, 'media_group_id': '13954209257219933', 'photo': [{'file_id': 'AgACAgUAAxUHZ_eKu6BwUtic_8Lj7XblPfxa9lMAAoHCMRsFbrhXkvOMxCCzQocBAAMCAANzAAM2BA', 'file_unique_id': 'AQADgcIxGwVuuFd4', 'file_size': 1042, 'width': 80, 'height': 90}, {'file_id': 'AgACAgUAAxUHZ_eKu6BwUtic_8Lj7XblPfxa9lMAAoHCMRsFbrhXkvOMxCCzQocBAAMCAANtAAM2BA', 'file_unique_id': 'AQADgcIxGwVuuFdy', 'file_size': 12276, 'width': 285, 'height': 320}, {'file_id': 'AgACAgUAAxUHZ_eKu6BwUtic_8Lj7XblPfxa9lMAAoHCMRsFbrhXkvOMxCCzQocBAAMCAAN4AAM2BA', 'file_unique_id': 'AQADgcIxGwVuuFd9', 'file_size': 68931, 'width': 712, 'height': 800}, {'file_id': 'AgACAgUAAxUHZ_eKu6BwUtic_8Lj7XblPfxa9lMAAoHCMRsFbrhXkvOMxCCzQocBAAMCAAN3AAM2BA', 'file_unique_id': 'AQADgcIxGwVuuFd8', 'file_size': 173001, 'width': 1336, 'height': 1500}, {'file_id': 'AgACAgUAAxUHZ_eKu6BwUtic_8Lj7XblPfxa9lMAAoHCMRsFbrhXkvOMxCCzQocBAAMCAAN5AAM2BA', 'file_unique_id': 'AQADgcIxGwVuuFd-', 'file_size': 182085, 'width': 1140, 'height': 1280}], 'caption': '貓咪 3'}]}

結果如下 :




以上傳送多個本機圖檔的程序可以寫成如下的函式 :

import requests

def telegram_local_images(token, chat_id, media_list, caption_list):
    url=f'https://api.telegram.org/bot{token}/sendMediaGroup'
    files={}  # 儲存檔案參考的字典
    media=[]  # 儲存 media 字典串列
    for i, img_path in enumerate(media_list): # 將檔案
        key=f'media{i+1}'  # 製作 files 字典的鍵 'media#'
        f=open(img_path, 'rb')  # 開啟檔案
        files[key]=f  # 將檔案參考存入 files 字典
        item={  # media 字典的項目
            'type': 'photo',
            'media': f'attach://{key}'
            }        
        if i < len(caption_list): # 若有對應的 caption,則加入
            item['caption']=caption_list[i]  # 加入 caption 鍵
        media.append(item)  # 將媒體字典加入 media 串列
    data={  # 製作 data 參數值
        'chat_id': chat_id,
        'media': str(media).replace("'", '"')  # JSON 字串格式
        }
    multipart={  # 製作 multipart 參數值
        k: (f.name, f, 'image/jpeg') for k, f in files.items()
        }
    try:
        with requests.post(url, data=data, files=multipart) 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 requests.exceptions.RequestException as e:
        print(f'Request error: {e}')
        return False
    finally:  # 關閉檔案避免資源泄漏
        for f in files.values():
            f.close()

此函式可用來傳送單一檔案 : 

>>> media_list=['cat1.jpg']   
>>> caption_list=['貓咪 1']      
>>> telegram_local_images(token, chat_id, media_list, caption_list)      
Message sent successfully.
True

結果如下 :



傳送多個檔案 :

>>> media_list=['cat2.jpg', 'cat3.jpg']   
>>> caption_list=['貓咪 2', '貓咪 3']   
>>> telegram_local_images(token, chat_id, media_list, caption_list)   
Message sent successfully.
True

結果如下 :



沒有留言 :