使用pyTelegramBotAPI零基础搭建Telegram私聊机器人

本文最后更新于:19 天前

点击获得封面头图

此文章使用CC-BY-NC协议,协议详情介绍请看此文


😘提前祝大家农历新年快乐!🎉

前言

定睛一看, 我好像已经有小半年没写过博客了…

不知道现在是否还有读者呢?

读到这篇的你请务必在评论区留个言!

然而, 也正好是一位我的博客的读者, 激起了我”写作”的欲望:

是他告诉我, 按照我旧文章的方法”折腾了几个小时无果”.

恰逢近日, 我重拾了对Telegram机器人的热情, 亦发现了一些前所未有的新鲜东西.

于是在此分享给大家.

准备

  • Telegram和翻墙工具;

  • 电脑或安卓手机.

由于机器人由python编写, 所以我们还需要配好python环境:

  • 对于使用Mac或Windows的用户:

下载并安装即可.

1
2
3
Mac - https://www.python.org/ftp/python/3.12.1/python-3.12.1-macos11.pkg

Windows - https://www.python.org/ftp/python/3.12.1/python-3.12.1-amd64.exe

建议安装一个代码编辑器, 如Sublime Text

  • 对于使用Linux或安卓的用户:
1
2
3
4
5
Linux - sudo apt/dnf install python3

安卓 - 下载并安装Termux - https://github.com/termux/termux-app/releases/download/v0.118.0/termux-app_v0.118.0+github-debug_arm64-v8a.apk
打开并输入 pkg update -y && pkg upgrade -y && pkg install python3 micro
过程中如有卡住不动的现象请回车

安装好python环境后, 需要安装主角: pyTelegramBotAPI库

打开系统的终端(Win用户可用win R快捷键, 输入cmd打开终端), 安卓则打开Termux即可, 输入:

1
pip3 install pyTelegramBotAPI

接下来, 创建一个bot.py, 这就是我们的机器人啦:

Win/Linux/Mac用户只需打开Sublime Text或其他编辑器, 左上角新建文件(File > New file), 创建一个名为bot.py的文件即可.

Termux用户输入micro bot.py, 继而使用micro编辑器编写机器人(保存快捷键: Ctrl S, 退出快捷键: Ctrl Q).

在打开的bot.py中粘贴:

1
2
3
4
5
6
7
8
9
10
11
12
13
import telebot

# ''内粘贴你的bot token
API_TOKEN = '你的token'

bot = telebot.TeleBot(API_TOKEN)

# 处理 '/start' 和 '/help'
@bot.message_handler(commands=['help', 'start'])
def send_welcome(message):
bot.reply_to(message, "你好, 欢迎使用此bot")

bot.infinity_polling()

https://t.me/BotFather 获取自己bot的token, 具体操作可看这里, 并替换上述代码第四行你的token.

Ctrl S保存, 现在尝试运行一下.

对于Win/Mac用户, 在终端中输入python3 (记得有空格), 再把文件拖拽进终端(就像文件夹之间移动文件那样), 最后回车即可.

对于Termux用户, 从屏幕左边缘向右滑, 点击下方的NEW SESSION以打开一个新的终端窗口, 在此窗口中输入python3 bot.py, 回车即可(这种情况默认是把bot.py放在了Termux默认的启动路径下, 即完全按照上述教程创建的文件).

如果接下来什么反应都没有, 则说明机器人成功运行, 反而如果出现了一大堆文字, 则运行失败.

可能的原因: 代理软件没开系统代理, 或没有安装pyTelegramBotAPI库.

此时, 对Telegram中的bot发送/help/start, 它们会向你发送你好的消息.

接着, 在bot正在运行的终端中Ctrl C即可停止bot, 此后每次编辑完成后我们执行运行 - 停止运行这套流程即可对bot进行调试.

至此, 准备工作结束啦!


编程

python作为代码世界里相当简单的一门语言, 向来都是很好入门的. 这篇文章并不打算详细讲解关于python的知识(就像之前那个Google Script机器人一样), 而打算让读者一知半解, 更多是直接套模板般做好自己的机器人.

因为一开始我就是这样, 在一知半解中产生了兴趣, 最后逐渐主动去了解与创造, 渐渐摆脱了他人的模板. 如果这篇文章能让读者你对编程产生兴趣, 那我的终极目标算是达到了.

研究上面的代码:

1
2
3
4
# 处理 '/start' 和 '/help'
@bot.message_handler(commands=['help', 'start'])
def send_welcome(message):
bot.reply_to(message, "你好, 欢迎使用此bot")

我们可以复制这块代码 粘贴在其下方, 现在变成了:

1
2
3
4
5
6
7
8
9
# 处理 '/start' 和 '/help'
@bot.message_handler(commands=['help', 'start'])
def send_welcome(message):
bot.reply_to(message, "你好, 欢迎使用此bot")

# 处理 '/start' 和 '/help'
@bot.message_handler(commands=['help', 'start'])
def send_welcome(message):
bot.reply_to(message, "你好, 欢迎使用此bot")

将下面那块进行如下处理:

1
2
3
4
# 处理 '/bye'
@bot.message_handler(commands=['bye'])
def send_bye(message):
bot.reply_to(message, "再见")

至此, 我们创建了一块能够处理/bye指令的代码, 仔细看, 每行都有变化, 但每行的变化都似乎只是改了个字符.

的确如此, 此时我们保存代码运行bot, 对bot发送/bye, 它会回复我们再见.

以此类比, 我们可以写出处理各种指令的不同的代码块, 这个代码块在python中称为函数.

不过我们的目的是做出一个私聊bot: 当别的用户给机器人发消息时, 机器人会将消息转发给, 当给机器人回复消息时, 它会把消息转发给那个用户.

那么, 我们该怎么写这个函数呢?

逻辑大概如下: 判断发送消息的人是用户还是, 如果是用户, 则将用户的消息转发给; 如果是, 则向回复的那条消息的来源用户回复我的消息内容.

所以我们需要一个函数来处理所有消息, 而不是上面那个简单的函数, 只能处理指令.

代码如下:

1
2
3
4
5
6
7
8
ADMIN=123123123

@bot.message_handler(func=lambda message: True)
def for_message(message):
if ADMIN==message.chat.id:
pass
else:
pass

pass代表尚未写的代码.

在这个函数中, 加入了一个if判断id是否等于ADMIN, 从而实现了上面判断是不是的过程, 注意粘贴时将123123123改为自己的ID, 如果不知道ID可以向 https://t.me/getmyid_bot 发消息.

先处理用户的消息, 即第二个pass的内容:

1
bot.send_message(ADMIN,'来自 @%s [%s] 的消息:\n%s'%(message.chat.username,message.chat.id,message.text))

由于pyTelegramBotAPI这个库的某些问题, 无法获取转发消息的来源ID, 因此我们必须把用户的ID放在bot转发给我们的消息中, 继而我们可以获得ID, 再通过此ID向bot发消息, bot再进行转发.

因此, 我们可以使用正则表达式处理第一个pass中获取用户ID的问题, 但是直接提取数字可能会有混淆问题, 这也是为什么在上面的语句中, 我使用[]包裹用户的ID的原因: 使其更好被正则匹配

于是第一个pass如下:

1
2
import re
bot.send_message(re.findall(r'\[([^\]]+)\]',message.reply_to_message.text)[0],message.text)

这条语句对回复的那条消息进行解析, 得出由中括号包裹的用户ID, bot再向ID为此的用户发送回复那条消息的内容.

但假设我不小心没有回复内容, 而是直接发给bot一条消息.

可以自己试一下, 会报错.

因此, 我们可以加入一对tryexcept:

1
2
3
4
try:
bot.send_message(re.findall(r'\[([^\]]+)\]',message.reply_to_message.text)[0],message.text)
except:
bot.reply_to(message,'请回复一条其他用户转发的消息')

作用是: 当不小心没有回复消息而触发报错时, 向发送一条提醒消息.

综上, 这个函数的全部代码是:

1
2
3
4
5
6
7
8
9
@bot.message_handler(func=lambda message: True)
def for_message(message):
if ADMIN==message.chat.id:
try:
bot.send_message(re.findall(r'\[([^\]]+)\]',message.reply_to_message.text)[0],message.text)
except:
bot.reply_to(message,'请回复一条其他用户转发的消息')
else:
bot.send_message(ADMIN,'来自 @%s [%s] 的消息:\n%s'%(message.chat.username,message.chat.id,message.text))

而整个bot.py的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import telebot
import re

API_TOKEN = '你的token'
ADMIN=123123123

bot=telebot.TeleBot(API_TOKEN)

# 处理 '/start' 和 '/help'
@bot.message_handler(commands=['help', 'start'])
def send_welcome(message):
bot.reply_to(message,'你好')

# 处理 '/bye'
@bot.message_handler(commands=['bye'])
def send_bye(message):
bot.reply_to(message, "再见")

@bot.message_handler(func=lambda message: True)
def for_message(message):
if ADMIN==message.chat.id:
try:
bot.send_message(re.findall(r'\[([^\]]+)\]',message.reply_to_message.text)[0],message.text)
except:
bot.reply_to(message,'请回复一条其他用户转发的消息')
else:
bot.send_message(ADMIN,'来自 @%s [%s] 的消息:\n%s'%(message.chat.username,message.chat.id,message.text))

bot.infinity_polling()

其实完全零基础的读者是比较难理解上面的内容的, 但还是那句话, 希望能够激起这部分读者的兴趣, 从而自主地去研究, 探索.


我是听话的便当.

Bye~❛‿˂̵✧