You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django页面展示Telegram API获取的消息?含缓存优化咨询

在Django中展示Telegram提取的消息(含YouTube链接)

我拥有Telegram API用于获取消息,通过以下Telethon代码可提取需在网页展示的消息(含YouTube链接):

from telethon import TelegramClient, events, sync
from telethon.tl.types import MessageMediaWebPage, WebPageEmpty

client = TelegramClient(session_name, api_id, api_hash)
client.start()

for message in client.iter_messages(chat, reverse=True):
    if type(message.media) == type(None):
        continue
    if not type(message.media) == MessageMediaWebPage:
        continue
    if type(message.media.webpage) == WebPageEmpty:
        continue
    if hasattr(message.media.webpage, 'display_url'):
        print('+++  display_url ', message.media.webpage.display_url)

问题1:该从何处入手,如何直接在网页展示Telegram返回的数据?

按以下步骤落地:

  • 封装数据获取逻辑:把Telethon的代码封装成独立函数,比如get_telegram_youtube_links(chat_id),返回提取到的display_url列表,方便在Django中调用。同时把api_id、api_hash、session_name这些配置移到Django的settings.py中,避免硬编码。
  • 编写Django视图:在视图中调用封装好的函数获取链接列表,将数据传入模板上下文。
  • 编写模板渲染数据:创建Django模板,用循环遍历链接列表,将每个URL渲染成可点击的链接;若为YouTube链接,还可以直接嵌入iframe播放器提升体验。

示例代码片段:

# views.py
from django.shortcuts import render
from telethon import TelegramClient
from telethon.tl.types import MessageMediaWebPage, WebPageEmpty
from django.conf import settings
from django.core.cache import cache

def get_telegram_links():
    client = TelegramClient(settings.TELEGRAM_SESSION_NAME, settings.TELEGRAM_API_ID, settings.TELEGRAM_API_HASH)
    client.start()
    links = []
    try:
        for message in client.iter_messages(settings.TELEGRAM_CHAT_ID, reverse=True):
            if not message.media or not isinstance(message.media, MessageMediaWebPage):
                continue
            if isinstance(message.media.webpage, WebPageEmpty):
                continue
            if hasattr(message.media.webpage, 'display_url'):
                links.append(message.media.webpage.display_url)
    finally:
        client.disconnect()
    return links

def telegram_links_view(request):
    links = get_telegram_links()
    return render(request, 'telegram_links.html', {'links': links})

模板示例(telegram_links.html):

{% for link in links %}
    {% if 'youtube.com' in link or 'youtu.be' in link %}
        <iframe width="560" height="315" src="{{ link|replace:'watch?v=,embed/' }}" frameborder="0" allowfullscreen></iframe>
    {% else %}
        <a href="{{ link }}" target="_blank">{{ link }}</a>
    {% endif %}
    <br>
{% endfor %}

问题2:是否可在Django视图中调用上述循环?

可以直接在视图中调用,但需要注意几个细节:

  • 避免请求阻塞:如果聊天消息量很大,iter_messages会耗时较久,同步视图会导致用户等待时间过长。建议优先使用Django异步视图(Django 3.1+支持),或者将数据拉取操作放到后台任务(如Celery)中,视图直接读取预拉取的数据。
  • 客户端复用与资源释放:不要每次请求都重新创建TelegramClient,可复用会话文件减少登录开销;同时要确保在操作完成后调用client.disconnect()释放资源,避免连接泄漏。
  • 异常处理:添加try-except块捕获API调用失败、网络异常等情况,返回友好的错误提示,避免页面崩溃。

问题3:每次页面加载查询Telegram耗时久,如何缓存API数据优化后续读取?

可以通过以下几种方式优化:

  • 使用Django自带缓存框架:将获取到的链接列表缓存到内存、Redis或数据库中,设置合理的过期时间(如15-30分钟)。每次请求先读取缓存,缓存失效时再调用Telegram API更新缓存。
    示例代码:
    from django.core.cache import cache
    
    def get_telegram_links():
        cache_key = 'telegram_youtube_links'
        links = cache.get(cache_key)
        if not links:
            # 原有Telethon数据拉取逻辑
            client = TelegramClient(settings.TELEGRAM_SESSION_NAME, settings.TELEGRAM_API_ID, settings.TELEGRAM_API_HASH)
            client.start()
            links = []
            try:
                for message in client.iter_messages(settings.TELEGRAM_CHAT_ID, reverse=True, limit=50):
                    if not message.media or not isinstance(message.media, MessageMediaWebPage):
                        continue
                    if isinstance(message.media.webpage, WebPageEmpty):
                        continue
                    if hasattr(message.media.webpage, 'display_url'):
                        links.append(message.media.webpage.display_url)
            finally:
                client.disconnect()
            cache.set(cache_key, links, 60*15)  # 缓存15分钟
        return links
    
  • 后台定时拉取数据:用Celery+Beat定时任务定期拉取Telegram数据,将结果存入数据库,视图直接从数据库读取数据,彻底避免页面加载时调用API的延迟。
  • 限制拉取数量:在iter_messages中添加limit参数,只拉取最新的N条消息(如iter_messages(chat, reverse=True, limit=50)),减少API请求的数据量和耗时。

内容的提问来源于stack exchange,提问作者nish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 07:25:32