在电报机器人中从内联模式发送本地照片
Send a local photo from inline mode in a telegram bot
我使用 Python telegram bot API 作为我的机器人。
我想在本地生成照片并将它们作为内联结果发送,但 InlineQueryResultPhoto
只接受照片 URL。
假设我的项目结构如下所示:
main.py
photo.jpg
如何发送 photo.jpg
作为内联结果?
这里是main.py
的代码:
from uuid import uuid4
from telegram.ext import InlineQueryHandler, Updater
from telegram import InlineQueryResultPhoto
def handle_inline_request(update, context):
update.inline_query.answer([
InlineQueryResultPhoto(
id=uuid4(),
photo_url='', # WHAT DO I PUT HERE?
thumb_url='', # AND HERE?
)
])
updater = Updater('TELEGRAM_TOKEN', use_context=True)
updater.dispatcher.add_handler(InlineQueryHandler(handle_inline_request))
updater.start_polling()
updater.idle()
没有直接的答案,因为 Telegram Bot API 没有提供。
但是有两种解决方法:您可以使用将照片上传到电报服务器然后使用 InlineQueryResultCachedPhoto
或者您可以上传到任何图像服务器然后使用 InlineQueryResultPhoto
.
InlineQueryResultCachedPhoto
第一个选项要求您在创建结果列表之前先将照片上传到电报服务器。你有哪些选择?机器人可以向您发送照片、获取该信息并使用您需要的信息。另一种选择是创建一个私人频道,您的机器人可以在其中 post 它会重复使用的照片。此方法的唯一细节是了解 channel_id (How to obtain the chat_id of a private Telegram channel?).
现在让我们看一些代码:
from config import tgtoken, privchannID
from uuid import uuid4
from telegram import Bot, InlineQueryResultCachedPhoto
bot = Bot(tgtoken)
def inlinecachedphoto(update, context):
query = update.inline_query.query
if query == "/CachedPhoto":
infophoto = bot.sendPhoto(chat_id=privchannID,photo=open('logo.png','rb'),caption="some caption")
thumbphoto = infophoto["photo"][0]["file_id"]
originalphoto = infophoto["photo"][-1]["file_id"]
results = [
InlineQueryResultCachedPhoto(
id=uuid4(),
title="CachedPhoto",
photo_file_id=originalphoto)
]
update.inline_query.answer(results)
当你将照片发送到chat/group/channel时,你可以获得file_id、缩略图的file_id、标题和其他我要跳过的细节。什么问题?如果您不过滤正确的查询,您最终可能会多次将照片发送到您的私人频道。这也意味着自动完成将不起作用。
内联查询结果照片
另一种方法是将照片上传到互联网,然后使用 url。除了您自己的托管之类的选项,您可以使用一些提供 APIs 的免费图像托管(例如:imgur、imgbb)。对于此代码,在 imgbb 中生成自己的密钥比在 imgur 中更简单。一旦生成:
import requests
import json
import base64
from uuid import uuid4
from config import tgtoken, key_imgbb
from telegram import InlineQueryResultPhoto
def uploadphoto():
with open("figure.jpg", "rb") as file:
url = "https://api.imgbb.com/1/upload"
payload = {
"key": key_imgbb,
"image": base64.b64encode(file.read()),
}
response = requests.post(url, payload)
if response.status_code == 200:
return {"photo_url":response.json()["data"]["url"], "thumb_url":response.json()["data"]["thumb"]["url"]}
return None
def inlinephoto(update, context):
query = update.inline_query.query
if query == "/URLPhoto":
upphoto = uploadphoto()
if upphoto:
results = [
InlineQueryResultPhoto(
id=uuid4(),
title="URLPhoto",
photo_url=upphoto["photo_url"],
thumb_url=upphoto["thumb_url"])
]
update.inline_query.answer(results)
此代码与之前的方法类似(并且存在相同的问题):如果不过滤查询,则上传多次,并且在编写内联时不会有自动完成。
免责声明
编写这两个代码时都认为您要上传的图像是在您收到查询时生成的,否则您可以在收到查询之前完成这些工作,将该信息保存在数据库中。
奖金
您可以 运行 您自己的机器人使用 pyTelegramBotAPI
获取您私人频道的 channel_id
import telebot
bot = telebot.TeleBot(bottoken)
@bot.channel_post_handler(commands=["getchannelid"])
def chatid(message):
bot.reply_to(message,'channel_id = {!s}'.format(message.chat.id))
bot.polling()
要获取您需要在频道中写入的id /getchannelid@botname
我使用 Python telegram bot API 作为我的机器人。
我想在本地生成照片并将它们作为内联结果发送,但 InlineQueryResultPhoto
只接受照片 URL。
假设我的项目结构如下所示:
main.py
photo.jpg
如何发送 photo.jpg
作为内联结果?
这里是main.py
的代码:
from uuid import uuid4
from telegram.ext import InlineQueryHandler, Updater
from telegram import InlineQueryResultPhoto
def handle_inline_request(update, context):
update.inline_query.answer([
InlineQueryResultPhoto(
id=uuid4(),
photo_url='', # WHAT DO I PUT HERE?
thumb_url='', # AND HERE?
)
])
updater = Updater('TELEGRAM_TOKEN', use_context=True)
updater.dispatcher.add_handler(InlineQueryHandler(handle_inline_request))
updater.start_polling()
updater.idle()
没有直接的答案,因为 Telegram Bot API 没有提供。
但是有两种解决方法:您可以使用将照片上传到电报服务器然后使用 InlineQueryResultCachedPhoto
或者您可以上传到任何图像服务器然后使用 InlineQueryResultPhoto
.
InlineQueryResultCachedPhoto
第一个选项要求您在创建结果列表之前先将照片上传到电报服务器。你有哪些选择?机器人可以向您发送照片、获取该信息并使用您需要的信息。另一种选择是创建一个私人频道,您的机器人可以在其中 post 它会重复使用的照片。此方法的唯一细节是了解 channel_id (How to obtain the chat_id of a private Telegram channel?).
现在让我们看一些代码:
from config import tgtoken, privchannID
from uuid import uuid4
from telegram import Bot, InlineQueryResultCachedPhoto
bot = Bot(tgtoken)
def inlinecachedphoto(update, context):
query = update.inline_query.query
if query == "/CachedPhoto":
infophoto = bot.sendPhoto(chat_id=privchannID,photo=open('logo.png','rb'),caption="some caption")
thumbphoto = infophoto["photo"][0]["file_id"]
originalphoto = infophoto["photo"][-1]["file_id"]
results = [
InlineQueryResultCachedPhoto(
id=uuid4(),
title="CachedPhoto",
photo_file_id=originalphoto)
]
update.inline_query.answer(results)
当你将照片发送到chat/group/channel时,你可以获得file_id、缩略图的file_id、标题和其他我要跳过的细节。什么问题?如果您不过滤正确的查询,您最终可能会多次将照片发送到您的私人频道。这也意味着自动完成将不起作用。
内联查询结果照片
另一种方法是将照片上传到互联网,然后使用 url。除了您自己的托管之类的选项,您可以使用一些提供 APIs 的免费图像托管(例如:imgur、imgbb)。对于此代码,在 imgbb 中生成自己的密钥比在 imgur 中更简单。一旦生成:
import requests
import json
import base64
from uuid import uuid4
from config import tgtoken, key_imgbb
from telegram import InlineQueryResultPhoto
def uploadphoto():
with open("figure.jpg", "rb") as file:
url = "https://api.imgbb.com/1/upload"
payload = {
"key": key_imgbb,
"image": base64.b64encode(file.read()),
}
response = requests.post(url, payload)
if response.status_code == 200:
return {"photo_url":response.json()["data"]["url"], "thumb_url":response.json()["data"]["thumb"]["url"]}
return None
def inlinephoto(update, context):
query = update.inline_query.query
if query == "/URLPhoto":
upphoto = uploadphoto()
if upphoto:
results = [
InlineQueryResultPhoto(
id=uuid4(),
title="URLPhoto",
photo_url=upphoto["photo_url"],
thumb_url=upphoto["thumb_url"])
]
update.inline_query.answer(results)
此代码与之前的方法类似(并且存在相同的问题):如果不过滤查询,则上传多次,并且在编写内联时不会有自动完成。
免责声明
编写这两个代码时都认为您要上传的图像是在您收到查询时生成的,否则您可以在收到查询之前完成这些工作,将该信息保存在数据库中。
奖金
您可以 运行 您自己的机器人使用 pyTelegramBotAPI
获取您私人频道的 channel_idimport telebot
bot = telebot.TeleBot(bottoken)
@bot.channel_post_handler(commands=["getchannelid"])
def chatid(message):
bot.reply_to(message,'channel_id = {!s}'.format(message.chat.id))
bot.polling()
要获取您需要在频道中写入的id /getchannelid@botname