基于Twilio的图片收发与存储方案咨询(Python实现)
最经济的Twilio图片接收、存储与合并回传方案
一、存储方案:别折腾自建Dropbox,免费云存储足够
完全没必要搭建Dropbox这类服务,新手直接用免费对象存储就行,成本几乎为0还省心:
- 首推Cloudflare R2:无出站带宽费(多数云存储下载会收带宽费,R2免这个),免费给10GB存储,存手机发送的图片绝对够用,配置也简单。
- 备选AWS S3免费层:15GB存储+每月一定免费流量,个人使用完全覆盖,注意别超出免费额度即可(超出仅小额收费)。
二、从0到1的实操步骤
1. 让Twilio把图片消息传给你的Python服务
当用户给你的Twilio号码发带图短信时,Twilio会把图片的临时Media URL发到你指定的Webhook地址。你可以写个简单的Flask服务接收:
from flask import Flask, request import requests import datetime import boto3 from twilio.rest import Client import os app = Flask(__name__) # 配置R2客户端(存储用) s3 = boto3.client( "s3", endpoint_url="https://<你的Cloudflare账户ID>.r2.cloudflarestorage.com", aws_access_key_id=os.getenv("R2_ACCESS_KEY"), aws_secret_access_key=os.getenv("R2_SECRET_KEY"), ) # 配置Twilio客户端(发消息用) twilio_client = Client(os.getenv("TWILIO_SID"), os.getenv("TWILIO_AUTH_TOKEN")) @app.route("/sms", methods=["POST"]) def receive_sms(): # 获取发来的图片URL和发送者号码 media_urls = request.form.getlist("MediaUrl0") sender_num = request.form.get("From") if media_urls: for idx, url in enumerate(media_urls): # 下载图片 img_data = requests.get(url).content # 生成唯一文件名,避免重复 filename = f"img_{sender_num.replace('+', '')}_{datetime.datetime.now().strftime('%Y%m%d%H%M%S')}_{idx}.jpg" # 上传到R2存储桶 s3.put_object(Bucket="<你的R2存储桶名称>", Key=filename, Body=img_data) # 把发送者和文件名存到本地txt,方便后续合并 with open("received_imgs.txt", "a") as f: f.write(f"{sender_num},{filename}\n") return "<Response></Response>" if __name__ == "__main__": app.run(port=5000)
- 依赖安装:
pip install flask requests boto3 twilio - 本地服务暴露公网:新手直接用ngrok,下载后打开终端跑
ngrok http 5000,复制生成的https URL,到Twilio控制台你的号码的Messaging设置里,把Webhook地址改成这个URL,请求方法选POST。
2. Python合并图片
用Pillow库拼接图片,以纵向合并为例:
from PIL import Image def merge_images(sender_num): # 从txt取出该用户的所有图片文件名 img_filenames = [] with open("received_imgs.txt", "r") as f: for line in f: num, filename = line.strip().split(",") if num == sender_num: img_filenames.append(filename) # 从R2下载图片到本地临时文件 temp_files = [] for filename in img_filenames: resp = s3.get_object(Bucket="<你的R2存储桶名称>", Key=filename) temp_path = f"temp_{filename}" with open(temp_path, "wb") as f: f.write(resp['Body'].read()) temp_files.append(temp_path) # 合并图片 images = [Image.open(fp) for fp in temp_files] total_height = sum(img.height for img in images) max_width = max(img.width for img in images) merged_img = Image.new('RGB', (max_width, total_height)) current_y = 0 for img in images: merged_img.paste(img, (0, current_y)) current_y += img.height merged_path = f"merged_{sender_num.replace('+', '')}.jpg" merged_img.save(merged_path) # 清理临时文件 for fp in temp_files: os.remove(fp) return merged_path
3. 把合并后的图片回传给用户
调用Twilio API发送带图短信:
def send_merged_img(sender_num, merged_path): # 上传合并后的图片到Twilio媒体服务 media = twilio_client.media.create(media_url=f"file://{os.path.abspath(merged_path)}") # 发送短信 twilio_client.messages.create( from_="<你的Twilio号码>", body="这是你发来的图片合并结果!", media_url=[media.url], to=sender_num ) # 清理本地合并后的图片 os.remove(merged_path) # 示例:给指定用户合并并发送 send_merged_img("+123456789", merge_images("+123456789"))
三、新手避坑指南
- 所有密钥(R2、Twilio)别直接写代码里,用环境变量读取,避免泄露。
- ngrok仅用于开发测试,正式上线可以用免费Python托管平台(比如Render免费层)或学生价VPS部署Flask服务。
- Twilio每月有15美元免费额度,个人测试完全够用,超出后费用也很低,不用担心成本。
内容的提问来源于stack exchange,提问作者RCanaway
相关产品推荐
相关产品推荐

