登录
  • 人们都希望被别人需要 却往往事与愿违
  • 作为一名预言家, 马克思失败的原因, 完全在于历史主义的贫乏@《历史决定论的贫困》波普尔 (哲学家 思想家)

使用Telegram 斗图

编程 Benny小土豆 2395次浏览 3019字 1个评论
文章目录[显示]

人类的本质就是斗图机。

想要在Telegram上斗图,那么必然就要用到MTProto了。对于pyrogram来说,那是非常简单的!

@app.on_message(filters.incoming)
def sticker_handler(client: "Client", message: "types.Message"):
    chat_id = message.chat.id
    sticker = "CAACAgUAAxkBAAEHooZhc87afMQjB-c10tBfkdcH1VSAWwACjwEAAjMDHAiv-7CBCwXTrR4E"
    client.send_chat_action(chat_id, "typing")
    message.reply_sticker(sticker, quote=True)

sticker可以为表情包的文件路径、HTTP URL、或者是文件ID。

如有需要可以对filters进行各种定制,比如说我要某个用户给我发某个特定表情包时才斗图,那么filter大概可以这样写

@app.on_message(filters.sticker & filters.incoming & filters.user(user_id))

然后判断一下

if message.sticker.file_unique_id == "abcd":
    client.send_chat_action(chat_id, "typing")
    message.reply_sticker(sticker, quote=True)

小提示:如何获取user_id? 试试这个bot呢? https://t.me/blog_update_bot


那么这个sticker的ID怎么获取呢?笨办法是,找个小号帮忙发个表情就好了。

我的Telegram里明明添加了那么多表情包,如果能一键使用就好了。既然MTProto是公开的,那么也一定有办法。

Raw Functions

pyrogram封装了许多易于使用的方法,比如上面的发sticker,最常用的回复消息等等。但是实际上这些都利用了Raw Function。很多功能并没有封装成高层的 Python方法,非常不幸的是,获取sticker set便是其中之一。

想要使用raw functions也很简单啦

from pyrogram.raw import functions
app.send(
    functions.account.UpdateProfile(
    first_name="Dan", last_name="Tès",
    about="Bio written from Pyrogram")
)

获取全部已添加的sticker

获取全部sticker的函数是 functions.messages.GetAllStickers

于是你兴致勃勃写好了代码,并且猜测猜测send方法会有返回值

使用Telegram 斗图

这是怎么回事?这个参数hash是什么?要怎么写?

使用Telegram 斗图

其实这个hash是为了节约双方的资源的,有点像etag。具体可以看这里 https://core.telegram.org/api/offsets#hash-generation

我们这随便传入一个数字就可以了,这个接口获取到的数据大概是这种结构:

使用Telegram 斗图

看到上面的hash 50617....了吗,按道理应该传入这个的哦,就会有类似304 Not Modified的效果

获取sticker set

上面的all_stickers就包含了这个用户所收藏的所有sticker,每一个sticker set都是list的一个元素。

然后我们看下获取sticker set的API

functions.messages.GetStickerSet

接受一个神奇的参数 stickerset: "raw.base.InputStickerSet"

很多人可能会问,这是啥参数类型啊,怎么构造?

要从raw_types里去搞啦,type hint已经给了提示是 raw.base.InputStickerSet

from pyrogram.raw import types as raw_types
raw_types.InputStickerSetID

InputStickerSetID接受两个参数,一个是id,一个是access_hash

那这个就不用我多说了吧,每一个set都有这两个参数

使用Telegram 斗图

这样我们就能拿到一个sticker的全部信息了!数据结构大致如下

set字段,表示sticker set的基本信息,和上面的一样

packs和documents,表示单个sticker的信息

packs的结构比较简单,看起来像是个索引一样

使用Telegram 斗图

documents的结构比较复杂,包含了缩略图等信息

使用Telegram 斗图

那看起来这个document就是我们想要的了!那么继续用functions.messages.send_xxx

想想就痛苦,有没有办法利用pyrogram的send_stickersn呢?

那一大长串file_id是什么啊?

转换为file_id

要使用古娜拉黑暗之神——呼呼拉——黑仙魔光才能把sticker变到file_id!

具体怎么做我教给你们就好了!不用探索其中原理……反正就是看pyrogram的send_sticker是怎么实现的,然后逆着来嘛😝

from pyrogram.file_id import FileId, FileType

file_id = FileId(file_type=FileType.STICKER,
    dc_id=doc.dc_id,
    file_reference=doc.file_reference,
    media_id=doc.id,
    access_hash=doc.access_hash,
    sticker_set_id=set_id,
    sticker_set_access_hash=set_hash).encode()

set_idset_access_hash是sticker set的,media_idaccess_hash是这个sticker的,不要搞错了哦。

然后生成的一长串字符串,就可以喂给 send_sticker啦。

建议事先把所有的sticker的file_id都跑出来,然后随机从里面选就好了~要不然容易触发rate limit导致Durov送你飞机票。

欢乐斗图

为了斗图更快乐,我们也要搞的更欢乐更随机!

那么最简单的办法,其实就random一下就好了,先随机选sticker,然后再自定义回复概率,比如我想要一半概率回复,那就……

if random.choice([1, 0]):
    client.send_chat_action(chat_id, "typing")
    message.reply_sticker("sticker file_id", quote=True)

或者比如我想要79%的概率回复,那就……

random.randint(1, 100) <= 79

要想要每次都随机的回复概率,那其实也不难

rand1 = random.randint(1, 100)
rand2 = random.randint(1, 100)
if rand1 > rand2:
    pass

当然啦,上述算法从整体上来讲,回复概率是50%的,样本数量越大就会越近于50%。毕竟嘛,要么发要么不发,这范围还是一样的……那肯定50%啦。

斗图结果

自然是非常开心了,24小时随时回复!小伙伴都惊呼我竟然大半夜不睡觉!

 


文章版权归原作者所有丨本站默认采用CC-BY-NC-SA 4.0协议进行授权|
转载必须包含本声明,并以超链接形式注明原作者和本文原始地址:
https://dmesg.app/telegram-sticker.html
喜欢 (26)
分享:-)
关于作者:
If you have any further questions, feel free to contact me in English or Chinese.
发表我的评论(代码和日志请使用Pastebin或Gist)
取消评论

                     

去你妹的实名制!

  • 昵称 (必填)
  • 邮箱 (必填,不要邮件提醒可以随便写)
  • 网址 (选填)
(1)个小伙伴在吐槽
  1. :idea: 这个功能写的真棒
    zhangsan2021-10-27 09:29 回复