Telegram Bot
10^11
目錄
- TG 簡介(5 min)
- 如何建立TG Bot(10 min)
- Python 語法簡介(45 min)
- 介紹TG Bot工具(60 min)
- 實作練習(共60 min)

開始課程前,請先下載好
- VS code
- Telegram app(手機版一定要/電腦版看心情)

線上版本也可以
相信各位都看得懂英文
一定可以自行操作的
啾咪><
不重要的講師介紹
姓名:陳芊邑(10^11)
職位:社長x教學
網名:C.Y
綽號:千億姊姊、小清
興趣:休眠、跟數學玩
專長:壓線不遲到、成為瘋子
附註:我的精神狀態有點美麗,見諒一下
然後我很喜歡跟其他瘋資幹部們偷抱抱,但我是異性戀

這是我DC頭像
對這是情頭
Telegram 簡介
TG提倡自由與開放,其程式碼和 API 向所有人公開。透過直觀的操作介面,使用者能輕鬆與機器人互動,完成教學、遊戲、搜尋、提醒,甚至控制物聯網等功能。
這是我的課程介紹,對這是一串贛話:
Telegram 簡介
TG就是跟line很像的社交軟體,但它的隱私性非常強,
且bot的程式碼是完全開放的,
你可以把別人的程式碼修一下然後再上傳,跟DC Bot不太一樣,
然後它功能一堆
我簡單翻譯一下:
Telegram 簡介
- 超大型群組(20萬人)
- 高隱私加密(端對端加密)
- 啊對所以這東西也是犯罪的溫床
如何建立TG Bot
- 下載電腦版&手機版TG Bot
- 請在 Telegram 搜尋欄搜尋 @botfather
- 輸入或點擊/start,可以得到所有指令

對我知道它很醜
但這就是生產機器人專用的帳號
它爸
如何建立TG Bot
4. 輸入 /newbot -> 輸入 Bot Name -> 輸入 Bot 的 username
*Emoji、圖片、貼圖都不能作為名稱 !
*Username 可用:
0-9、a-z、A-Z、-,
且要以 "bot" 作為結尾

如何建立TG Bot
5. 成功後,會回傳 API token,點一下就可以直接複製

*每個 Token 都對應到一個合法 Bot
*程式要有Token,Bot 才能夠被識別
如何建立TG Bot
6. 點選新建的 Bot 連結,並按下start


如何建立TG Bot

Python語法簡介
- 基礎語法(速)
- 資料結構(list、dictionary)
- 函式(function)
- 模組(module)
- JSON
- 套件(package)(補充)
- 物件導向(補充)
大概會講這些
Python基礎語法
如果各大電神覺得這part贛話太多,請幫我指導一下你隊友
這part可能很快就能過去了
- 輸出(output)&註解
- 變數(variable)&運算子(operator)
- 輸入(input)
- 判斷式(if-else statement)
- 迴圈(loop)

輸出&註解
print("easy")
#簡單的單行註解
"""
簡單的多行註解
"""然後python不用寫分號

name="瘋子"
print(name)變數&運算子
變數名稱=變數值,基本上概念你都學過了
| 型態 | 變數宣告 | 程式 | 執行結果 |
|---|---|---|---|
| 整數 | int | print(int(3.14)) | 3 |
| 浮點數 | float | print(float(1)) | 1.0 |
| 布林值 | bool | print(bool(1)) | True |
變數&運算子
算術運算子,基本上都是你學過的
| 運算子 | 說明 | 程式 | 執行結果 |
|---|---|---|---|
| + | 加 | A=5+3 | A=8 |
| - | 減 | A=5-3 | A=2 |
| * | 乘 | A=5*3 | A=15 |
| / | 浮點除法 | A=5/2 | A=2.5 |
| // | 整除 | A=5//2 | A=2 |
| % | 求餘 | A=5%2 | A=1 |
| ** | 次方 | A=5**2 | A=25 |
變數&運算子
邏輯運算子,基本上都是你學過的
and 且:連接的兩個敘述都要正確才是 True
or 或:連接的兩個敘述只要有一個正確就是 True
not 非:否定一個敘述
啊丟,python不能用&&這種東西
哭了
變數&運算子
常用字串處理方法:
s1 = "楓資是瘋資也是瘋子"
print(s1)
#單行字串
zsisc = '''
楓資
是瘋資
也是瘋子
'''
print(zsisc)
#多行字串變數&運算子
常用字串處理方法:
print("Hello World".lower())
# 變成小寫
print("Hello World".upper())
# 變成大寫str.split([分隔字])
將字串按照指定的分隔字分割
text="Hello World"
words=text.split()
print(words)
#['Hello','World']
print(words[0])
# Hello
print(words[1])
# World
date="2008-01-01"
parts=date.split('-')
print(parts)
# ['2008','01','01']變數&資料型態
額外介紹一個好用的東西,f-string
name="瘋子"
print("楓資幹部都是",name,"很合理")
#輸出:楓資幹部都是 瘋子 很合理name="瘋子"
print(f"楓資幹部都是{name}很合理")
##輸出:楓資幹部都是瘋子很合理first=8
second=9
print(f"楓資幹部都是{first+second}很合理")
##輸出:楓資幹部都是17很合理*使用單引號「'」與雙引號「"」
在Python都會被視為字串
輸入
變數=input([提示字串])
name=input("請輸入瘋子:")
print(f"{name}是怪人")
#輸入:吱吱 輸出:吱吱是怪人
判斷式
1.if…
2.if…else…
3.if…elif…else…
4.巢狀 if
比c++多elif、冒號、縮排,少括號
chieh=87
if chieh>90:
print("chieh is gami")
elif chieh>80:
print("chieh is 甲殼類動物")
else:
print("chieh is not human")對,它沒有下放的問題,我可以不用跟我女鵝吵架了
這種時候就會突然覺得Python挺好的
判斷式
巢狀長這樣:
chieh=87
gami=8+9
if chieh>90:
print("chieh is 企鵝")
else:
if gami>87:
print("gami is 怪人")
elif gami>66:
print("gami is 蜜獾")
else:
print("gami is 甲殼類動物")
#gami is 甲殼類動物迴圈
跟c++的語法有差,但概念都一樣
for i in range(5):
print("chieh is 企鵝")
# 輸出5次chieh is 企鵝
for i in range(2,10,2):
print(i)
# 輸出2 4 6 81.for 變數 in 序列:
其中,序列中的值可以依序賦值給變數
多數時候會使用range()遍歷,當然也可以是list、dictionary之類的
range(起始值,結束值,公差)
迴圈
sum=0
i = 3
while i < 13:
sum = sum + i
i = i + 3
print(i)
# 輸出 6 9 12 152.while 條件:
i=初始值
while i <= 終止值:
程式
i=i+-公差
*continue&break 在python的用法與c++同
分別是跳過當前迴圈繼續執行&跳出迴圈

Python資料結構
如果各大電神覺得這part贛話太多,請幫我指導一下你隊友
這part可能很快就能過去了
- list
- dictionary
tupleset

Python資料結構
先來解釋資料結構的用途
Python資料結構
先來解釋資料結構的用途
如果說變數是一個盒子,我們把值丟在盒子裡
變數
Python資料結構
那麼,資料結構就是抽屜
變數
變數
變數
變數
變數
Python資料結構
我們把資料結構當成一種整理工具
將相關的資料整合
使程式碼更加簡潔、能更靈活的操作
進而進行資料分析
在製作專案上很常用
變數
變數
變數
變數
變數
Python資料結構
更生活一點的說法,就是把書分類,放在書櫃裡
重生文
帶球跑
穿越文
霸道總裁
強制愛
化學
物理
生物
數學
地科
笑鰲江湖
申鵰俠侶
田龍八部
路鼎記
血山飛狐
Python資料結構
很明顯他們應該這樣分配(沒有版權問題真好)
重生文
帶球跑
穿越文
霸道總裁
強制愛
化學
物理
生物
數學
地科
笑鰲江湖
申鵰俠侶
田龍八部
路鼎記
血山飛狐
網文
學術
仙俠
list
list的宣告方式&輸出
# 使用[] 宣告
empty_list=[]
anime_menu=["膽大黨","blue lock","哎咕島","夢幻島","我推"]
anime_like=[5,4,3,2,1]
print(anime_menu)
print(anime_like)
list
list的宣告方式&輸出
#使用list()將其它資料型態轉換成list
number_list=list(range(1,11))
print(number_list)
#輸出[1,2,3,4,5,6,7,8,9,10]list
list的宣告方式&輸出
#使用條件式(list comprehensions)
even_number_list=[i for i in range(1,11) if i%2==0]
#符合條件的數字i加入到新的清單中。
print(even_number_list)
#使用迴圈
even_number_list=[]
for i in range(1, 11):
if i % 2 == 0:
even_number_list.append(i)
print(even_number_list)
#輸出[2,4,6,8,10]list
使用index取用list的值
anime_menu=["膽大黨","blue lock","哎咕島","夢幻島","我推"]
anime_like=[5,4,3,2,1]
print(anime_menu[0])
print(anime_like[-1])
print(anime_menu[0:4:2])
print(anime_like[:])
print(anime_like[::-1])5個print分別輸出?
list
使用index取用list的值
anime_menu=["膽大黨","blue lock","哎咕島","夢幻島","我推"]
anime_like=[5,4,3,2,1]
print(anime_menu[0])
#膽大黨
print(anime_like[-1])
#1
print(anime_menu[0:4:2])
#['膽大黨','哎咕島']
#[開始:結束:間隔]
print(anime_like[:])
#[5,4,3,2,1]
print(anime_like[::-1])
#[1,2,3,4,5]
#[:n]->前n個元素
#[m:]->跳過前m個元素
list
使用index取用list的值(迴圈)
anime_menu=["膽大黨","blue lock","哎咕島","夢幻島","我推"]
anime_like=[5,4,3,2,1]
for i in range(5):
print(anime_menu[i])
for i in anime_menu:
print(i)
"""
輸出:
膽大黨
blue lock
哎咕島
夢幻島
我推
"""list
介紹一些常用的method:
(看看就好)
number_list=[5,4,3,2,1]
number_list.append(6)
#新增值到list的最後->[5,4,3,2,1,6]
number_list.insert(2,7)
#在指定位置新增值->[5,4,7,3,2,1,6]
number_list.remove(7)
#移除指定值->[5,4,3,2,1,6]
del number_list[5]
#移除指定位置的值->[5,4,3,2,1]
number_list.sort()
#排序->[1,2,3,4,5]
number_list.reverse()
#反轉->[5,4,3,2,1]
number_list.pop()
#移除最後一個值->[5,4,3,2]
number_list2=number_list.copy()
#將list複製到list2
number_list.clear()
#清空所有值[]
print(len(number_list2))
#計算list2中的值的數量->4.append()
.insert()
.remove()
del list[]
.reverse()
.pop()
.copy()
.clear()
len(list)
list
學完這些肯定會想:
那我們是不是可以把list合併呢?

list
Emmmm......我們先來看看list裡面的list
啊對,就是大家最喜歡的二維
anime_menu=[["膽大黨",5],["blue lock",4],["哎咕島",3],["夢幻島",2],["我推",1]]
print(anime_menu[0])
#輸出['膽大黨',5]
anime_menu[2][1]=5
#修改二維list中的值['哎咕島',5]list
然後很直接了當的使用zip合併list
anime_menu=["膽大黨","blue lock","哎咕島","夢幻島","我推"]
anime_like=[5,4,3,2,1]
anime_menu_like=list(zip(anime_menu,anime_like))
print(anime_menu_like)
#輸出[('膽大黨',5),('blue lock',4),('哎咕島',3),('夢幻島',2),('我推',1)]list
小延伸:
a=[1,2,3]
b=a
b.append(4)
print(a)你們覺得這會輸出什麼?
list
小延伸:
a=[1,2,3]
b=a
b.append(4)
print(a)
#輸出[1,2,3,4]list
為什麼?
a
[1,2,3]
list
理想上
a
[1,2,3]
b
[1,2,3]
複製
list
實際上
a
[1,2,3]
b
list
使用copy就解決了這個問題
a
[1,2,3]
b
a=[1,2,3]
b=a.copy()
b.append(4)
print(a)
#輸出[1,2,3]Dictionary
每筆資料分別包含{"key":"value"}
key是唯一的,value可以是任何資料型態
Dictionary
舉例來說:
| key | value |
|---|---|
| 動畫 | Hunter × Hunter |
| 作者 | Yoshirin |
| 主角 | 大傑 |
| 我推角 | 奇犽、沒下船那個 |
| 更新速度 | 超慢 |
Dictionary
你們也可以把自我介紹弄成這樣
但由於本人有點害羞所以還是算了
| key | value |
|---|---|
| 動畫 | Hunter × Hunter |
| 作者 | Yoshirin |
| 主角 | 大傑 |
| 我推角 | 奇犽、沒下船那個 |
| 更新速度 | 超慢 |
anime={
"動畫":"Hunter × Hunter",
"作者":"Yoshirin",
"主角":"大傑",
"我推角":["奇犽","沒下船那個"],
"更新速度":"超慢"
}Dictionary
也可以這樣宣告
anime={
"動畫":"Hunter × Hunter",
"作者":"Yoshirin",
"主角":"大傑",
"我推角":["奇犽","沒下船那個"],
"更新速度":"超慢"
}anime=dict(
動畫="Hunter × Hunter",
作者="Yoshirin",
主角="大傑",
我推角=["奇犽","沒下船那個"],
更新速度="超慢"
)Dictionary
輸出方式:
anime={
"動畫":"Hunter × Hunter",
"作者":"Yoshirin",
"主角":"大傑",
"我推角":["奇犽","沒下船那個"],
"更新速度":"超慢"
}
print(anime)
#輸出整個字典
#{'動畫':'Hunter × Hunter','作者':'Yoshirin','主角':'大傑','我推角':['奇犽','沒下船那個'],'更新速度':'超慢'}
print(anime["我推角"])
#['奇犽','沒下船那個']Dictionary
使用方式跟list差不多
也是那幾種方法可以用
anime=dict(
動畫="Hunter × Hunter",
作者="Yoshirin",
主角="大傑",
我推角=["奇犽","沒下船那個"],
更新速度="超慢"
)
anime["更新速度"]="有點慢"
print(anime["更新速度"])
#有點慢
anime.update({"更新速度":"有在更新了"})
print(anime["更新速度"])
#有在更新了
like=anime.pop("我推角")
print(like)
#['奇犽','沒下船那個']Dictionary
如果想
從dict裡面抓取
key或value
該怎麼做?
anime=dict(
動畫="Hunter × Hunter",
作者="Yoshirin",
主角="大傑",
我推角=["奇犽","沒下船那個"],
更新速度="超慢"
)
key=anime.keys()
print(key)
#dict_key(['動畫','作者','主角','我推角','更新速度'])
value=anime.values()
for value in anime.values():
print(value)
"""
Hunter × Hunter
Yoshirin
大傑
['奇犽','沒下船那個']
超慢
"""Dictionary
如果想
兩個一起取得呢?
anime=dict(
動畫="Hunter × Hunter",
作者="Yoshirin",
主角="大傑",
我推角=["奇犽","沒下船那個"],
更新速度="超慢"
)
item=anime.items()
for key,value in item:
print(f"key:{key},value:{value}")
"""
key:動畫,value:Hunter × Hunter
key:作者,value:Yoshirin
key:主角,value:大傑
key:我推角,value:['奇犽', '沒下船那個']
key:更新速度,value:超慢
"""Dictionary
來做個小練習:
name_dic={
"吱吱":"變態",
"嘎米":"怪人",
"葉子":"熬葉",
"切魚":"女鵝",
"起飛":"官配",
"呱呱":"呱"
}
我在路上撿了來路不明的字典
我有點好奇,所以想要設計一個程式
有三個開發要求:
1.查詢此人特色
2.更新此人特色
3.印出此字典
4.結束程式
Dictionary
來做個小練習:
name_dic={
"吱吱":"變態",
"嘎米":"怪人",
"葉子":"熬葉",
"切魚":"女鵝",
"起飛":"官配",
"呱呱":"呱"
}
重視客戶UX體驗的人們,打算提供以下服務:
先詢問使用者選擇哪種操作
再問執行此操作的對象
若是使用者輸入的指令錯誤
可以另外告知他們
Dictionary
這是解答,盡量補藥複製喔啾咪
name_dic={
"吱吱":"變態",
"嘎米":"怪人",
"葉子":"熬葉",
"切魚":"女鵝",
"起飛":"官配",
"呱呱":"呱"
}
while True:
print("1.查詢此人特色")
print("2.更新此人特色")
print("3.印出此字典")
print("4.結束程式")
choice=input("是時候做出選擇了:")
if choice=="1":
name=input("輸入名字:")
if name in name_dic:
print(f"{name}的特色是:{name_dic[name]}")
else:
print("他不是瘋子")
elif choice=="2":
name = input("輸入名字:")
if name in name_dic:
new=input(f"請輸入{name}的新特色:")
name_dic[name]=new
print(f"{name}的特色已更新為:{new}")
else:
print("他不是瘋子")
elif choice=="3":
for name,name_dic[name] in name_dic.items():
print(f"{name}:{name_dic[name]}")
elif choice=="4":
print("結束")
break
else:
print("眼睛不好要去看醫生")
Dictionary

我們還有很多課程
這只是個開始
Python函式
如果各大電神覺得這part贛話太多,請幫我指導一下你隊友
這part可能很快就能過去了
- function
- lambda
- decorator

Python函式
function的基本架構
def zsisc(parameters1,parameters2):
chyun=parameters1+parameters2
return chyun
print(zsisc(8,9))
"""
def 函數名稱(參數1, 參數2, ...):
函數程式碼
return 返回值
"""Python函式
匿名函式 lambda:
簡潔的好東西
r=int(input())
#匿名用法
print((lambda r:r*r*3.14)(r))
#不匿名用法
area=lambda r:r*r*3.14
print(area(r))
#輸出圓面積Python函式
裝飾子Decorator:
裝飾器的本質是一個函數,它接收一個函數作為參數,並返回一個新的函數,從而動態地為原函數添加功能。
這聽起來有點難懂
我舉個栗子

Python函式
裝飾子Decorator:
簡單來說就是裝飾
腦子(函式)


書(裝飾)
+
Python函式
裝飾子Decorator:
簡單來說就是裝飾
會讀書的腦子(裝飾後函式)



Python函式
裝飾子Decorator:先來看看沒有語法蜜糖的情況
這種每用一次就要寫一次有點麻煩
import time
def timing(func):
print("Start...")
t1 = time.time()
func()
t2 = time.time()
print("Elapsed time(secs):", t2 - t1)
def works():
total = 0
for i in range(10000):
total += i
print("total:", total)
timing(works)Python函式
函式裡面包一個函式
import time
def timing(func):
def wrapper():
print("Start...")
t1 = time.time()
func()
t2 = time.time()
print("Elapsed time(secs):", t2 - t1)
return wrapper
def works():
total = 0
for i in range(10000):
total += i
print("total:", total)
works = timing(works)
#將包裝過的函式再重新命名回原來被包裝的函式名稱
#為原始的函式加上了計時的功能, 同時又可以維持原始的函式名稱
works()有沒有可能更簡潔?
Python函式
裝飾子Decorator:
import time
def timing(func):
def wrapper():
print("Start...")
t1 = time.time()
func()
t2 = time.time()
print("Elapsed time(secs):", t2 - t1)
return wrapper
@timing
def works():
total = 0
for i in range(10000):
total += i
print("total:", total)
works()用@就解決了
Python函式
作用域scope:
def zsisc(parameters1,parameters2):
chyun=parameters1+parameters2
return chyun
print(zsisc(8,9))
print(chyun)#報錯global全域變數
local區域變數
Python函式
作用域scope:
def zsisc(parameters1,parameters2):
global chyun
chyun=parameters1+parameters2
return chyun
print(zsisc(8,9))
print(chyun)global全域變數
local區域變數
Python函式

Python模組
如果各大電神覺得這part贛話太多,請幫我指導一下你隊友
這part可能很快就能過去了

Python模組
什麼是module?

假設你今天穿越異世界
到了農業大國
結果發現那邊的攤販賣了一堆蔬果
但完全沒有分類
有強迫症的你會選擇?
Python模組
這就是module存在的意義
讓你依照功能整理你的程式
1.整理它
2.再丟一堆蔬果讓它更亂
聰明的你肯定會選1對吧?
對吧?
除非你有密集恐懼症

Python模組
假設你有一堆程式碼
你又很想要重複利用function?
那就依照功能把你家的程式碼打包成module,
你就不用一行一行看了

Python模組
什麼是模組(module):
是一個Python檔案,
每一個Python檔案被視為一個模組,
可以在程式中匯入其他Python模組,
模組就可以不斷地被其他程式再利用

Python模組
什麼是模組(module):
main.py



math.py
typing.py
Python模組
什麼是模組(module):
main.py



math.py
typing.py
Python模組
如何使用module?
使用import
1.引入單個模組
2.引入模組內某功能

Python模組
引入單個模組:
math是內建模組
floor()是取比該數小的最大整數
#語法結構
import <模組>import math
print(math.floor(3.14))
# 3Python模組
引入模組內的某些功能:
被import的對象可以是
子模組、函式、常數、類別
->可以import模組內任何東西
#語法結構
from <模組> import <模組內任何東西>
from <模組> import <子模組>,<函式>,<常數>,<類別>from math import pi
print(pi)
# 3.141592653589793Python模組
取別名:
也可以給它新的綽號
方便使用或辨認
import math as m
from math import pi as p
print(m.gcd(21,35))#最大公因數
print(p)Python模組
常用的模組?
自己翻一下資料
Python模組
time()常用的:
import time
print(time.time())
#顯示從 1970/1/1 00:00 到此刻的秒數
print(time.sleep(3))
#讓程式停止幾秒
print(time.ctime())
#顯示本地時間
print(time.strftime("%Y年%m月%d日 %H:%M:%S", time.localtime()))
#將時間轉換為可讀的字符串格式->string format time
#(指定格式,默認為當前時間)Python模組
random()常用的:
import random
print(random.random())
#返回一個0到1之間的隨機浮點數[0.0, 1.0)
print(random.uniform(1, 10))
#返回a和b之間的隨機浮點數[a,b]
print(random.randint(1, 10))
#返回a和b之間的隨機整數[a,b]
print(random.randrange(1, 10, 2))
#返回指定範圍內的隨機整數(選擇1,3,5,7,9)
print(random.choice([1,2,3,4,5]))
#從序列中隨機選擇一個元素
print(random.choices(['a', 'b', 'c'], weights=[1, 2, 3], k=5))
#從序列中隨機選擇k個元素,允許重複選擇
#可以指定權重weights來影響選擇的機率
print(random.sample(range(1, 10), 3))
#從序列中隨機選擇k個不重複的元素Python模組

Python套件
如果各大電神覺得這part贛話太多,請幫我指導一下你隊友
這part可能很快就能過去了

Python套件
如果說module是一個.py檔
那package就是很多個.py檔的資料夾
而__init__.py 是讓電腦將這個資料夾識別為 package,而不是普通的資料夾

package1
package2
Python套件
1.有效組織多個 module
package 之間命名隔離->
可以出現重複的變數/函數名稱,否則可能產生命名衝突
2.不需要重造輪子
自由下載/上傳寫好的 package
為什麼需要package?
Python套件
module v.s package?
| Module | Package |
|---|---|
| .py檔 |
__init__.py + 數個 .py 檔 |
| 可被其他 .py 引用 | 可被其他 .py 引用 |
| 定義 class, functions, variables | 管理 Module |
Python套件
package哪裡來?
1.自己寫:)
2.從 PyPI 或 GitHub 下載
3.自己寫好後上傳讓大家下載使用
Python套件
Json
如果各大電神覺得這part贛話太多,請幫我指導一下你隊友
這part可能很快就能過去了

Json
json是?
JavaScript Object Notation (JSON)
是一種資料交換的格式
易於人讀寫,同時也易於電腦分析與生成
Json
如何在python使用json?
1.import json
2.json.loads() json.dumps()
Json
在.py中python、json互換
import json
data ="""
{
"楓資幹部": [
{
"姓名": "吱吱",
"個性": "中二怪人",
"習性": {
"食物": "人",
"每日睡眠時間": "24hr"
}
},
{
"姓名": "嘎米",
"個性": "蜜獾",
"習性": {
"興趣": "愛錢"
}
}
]
}
"""
py_dict=json.loads(data)
#將json字串轉換為Python字典
new_json=json.dumps(py_dict,ensure_ascii=False, indent=4,sort_keys=True)
#將Python字典轉換為json字串
print(py_dict)
print(py_dict["楓資幹部"][0])
print(new_json)Json
在.py中開啟&寫入json(記得開一個json檔)
import json
with open("file.json","r",encoding="utf-8") as f:
data=json.load(f)
#不加s->我們這次處理的是file不是string
print(data)
print(data.keys())
with open("file2.json","w",encoding="utf-8") as f2:
json.dump(data,f2,ensure_ascii=False, indent=4)
#將Python的資料結構(data)保存為json格式並寫入文件。Json
檔案讀寫的部分再講一點
開啟模式:
'r':read 唯讀模式,只能讀,不能更改內容
'w':write 寫入模式(覆寫),會直接覆蓋原本檔案
'a':append 寫入模式(續寫),會從原本的檔案繼續寫下去,不會覆蓋掉
Json
這裡有淺顯易懂的解說(按圖片)
(雖然是全英但應該聽得懂)
物件導向
如果各大電神覺得這part贛話太多,請幫我指導一下你隊友
這part可能很快就能過去了

物件導向
什麼是物件導向?
物件導向(Object-Oriented programming,簡稱OOP)
一句話總結:
物件(Object)是類別(class)的實例(Instance)

物件導向
什麼是物件導向?
你想想,我們剛剛學的那些
看起來很難用在生活上吧?
誰會沒事走在路上看到一個東西就幫它寫dict或list?
物件導向就是把生活融入程式
用程式表達生活中會出現的東西
物件導向
有什麼好處?
1.開發時易於維護,可讀性提高
2.擴充功能時更加方便
3.使語意更為清晰
4.減少重複代碼
物件導向
在開始之前
先有個概念
類(Class):藍圖
類別屬性(Class Attribute):設計預定的材料
物件(Object):類的實例(Instance)
物件屬性(Object Attribute):實際製作的材料
物件導向
舉個栗子:
class Club_member:
club_name="zsisc"
def __init__(self,name,style,habit):
self.name=name
self.style=style
self.habit=habit
cheer=Club_member("吱吱","中二怪人","從早睡到晚")
leaf=Club_member("葉子","葉氏集團總裁","不睡覺")
print(cheer.style)
print(leaf.habit)物件導向
類別變數(Class variable)
實例變數(Instance variable)
吱吱
葉子
社團幹部
zsisc是類別變數
兩人都有各自的實例變數(名字、個性、習性)
補充:
物件導向
如果好奇TG Bot裡哪些是物件,哪些是類別,哪些是屬性,可以參考一下,等等上課疑惑的時候就拿出來翻
這是chat gpt弄出來的東西
Telegram Bot
對終於要講正事了
1.打開vs code
2.下載 python (extensions)
3.在終端(terminal)輸入:
pip install pyTelegramBotAPI
TG前置作業
檢查一下你的token
TG前置作業
https://api.telegram.org/bot<TOKEN>/getme
成功會回傳json檔案

token不小心洩漏出去怎麼辦?
TG前置作業
找BotFather,輸入指令/revoke,選擇想要更改的bot
我的token當然已經改掉了,不要想著偷講師的

Token?
TG前置作業
https://api.telegram.org/bot<TOKEN>/getUpdates
將自己 Bot 的 Token 替換掉 URL 的<TOKEN>
丟到google
然後你發訊息給你家bot,刷新網頁
好像有什麼東西改變了?

Token?
TG前置作業
你會發現裡面多了這些東西
- 你傳送訊息的時間
- 訊息來自哪個使用者
- 訊息在哪個聊天室被傳送
- 傳送的訊息內容

好像有點不太妙?
Token?
TG前置作業
所以你要保護好它
剛剛大家應該有注意到,
我們透過把 Token 輸入到 getMe、getUpdate 等 API 中,就能夠得到 Bot 的各種資訊
Token 就像 Bot 的身份證,API 藉此來辨別 Bot
PyTelegramBotAPI ?
TG前置作業
就是把剛剛大家體驗過的 getMe、getUpdates
還有其他很多 API 包裝成 Package 來使用
初始化:
TG前置作業
import telebot
TOKEN=""
bot=telebot.TeleBot(TOKEN,parse_mode=None)
#None也可以改成html或Markdown
#用來設定訊息的解析模式,影響你發送訊息時如何處理文字中的樣式@bot.message_handler(commands=["start"])
def welcome(message):
bot.reply_to(message,"hi")
bot.infinity_polling()先確認一下有沒有連到:
TG前置作業
@bot.message_handler(commands=["start"])
def welcome(message):
bot.reply_to(message,"hi")
bot.infinity_polling()講解一下:
1.PyTelegramBotAPI 把傳入的訊息分類成很多種型別(Ex: text, audio, photo, video)等
2.message_handler有各種不同條件的過濾器,
用於篩選輸入訊息,讓函式拿到我們想要的訊息種類
3.Command 是一個特別的訊息,格式是:/[string]
TG前置作業
@bot.message_handler(commands=["start"])
def welcome(message):
bot.reply_to(message,"hi")
bot.infinity_polling()講解一下 bot.infinity_polling():
簡單來說就是可以讓 Bot 不斷地自動接收更新,
並且通知對應的函式有事件發生
TG前置作業
@bot.message_handler(commands=["start"])
def welcome(message):
bot.reply_to(message,"hi")
bot.send_message(message.chat.id,f"hi")
bot.infinity_polling()講解一下 reply_to() & send_message() :

reply_to()
就跟我們平常傳訊息會使用的回覆一樣
TG前置作業
@bot.message_handler(commands=["start"])
def welcome(message):
bot.reply_to(message,"hi")
bot.send_message(message.chat.id,f"hi")
bot.infinity_polling()講解一下 reply_to() & send_message() :
send_message()是傳送訊息到指定的聊天室中
welcome() 接收聊天室的 message,
這個 message 帶有聊天室 ID的資訊
聊天室 ID讓 send_message() 知道對話發生在哪個聊天室中
TG前置作業
@bot.message_handler(commands=["start"])
def welcome(message):
bot.reply_to(message,"hi")
bot.send_message(message.chat.id,f"hi")
bot.infinity_polling()講解一下 reply_to() & send_message() :
reply_to() 因為回覆該訊息,所以接收 message
send_message() 因為要直接傳送訊息在聊天室,所以接收 message.chat.id
TG前置作業
接下來是大家期待已久的實作環節~


Telegram Bot
先講基礎一點的
初學者必學的echo bot:

TG基礎班
初學者必學的echo bot:
開發要求:
1./help:描述bot功能
2.接受你輸入的所有訊息,回覆相同的訊息
3.對特定語句有反應
eg.輸入:我愛IZCC四校聯合寒訓
輸出:不要再業配了
TG基礎班
初學者必學的echo bot:
小提示:
1.可以用 message.text 來取得輸入訊息的字串
2.利用 @message_handler() 中的 filter(func)來實作
3.可以試看看使用lambda
TG基礎班
初學者必學的echo bot:

對我就是不讓你們複製,啾咪
TG基礎班
初學者必學的echo bot:

函數過濾器,判斷訊息是否要被接收
輸入聊天室的訊息會被 message_handler() 接收,送入 lambda 函式
不管傳入什麼訊息,都會被接收
TG基礎班
初學者必學的報時仔:
TG基礎班
開發要求:

初學者必學的報時仔:
TG基礎班
開發要求:
輸入/time 回傳目前時間
初學者必學的報時仔:
TG基礎班
小提示:
1.from datetime import datetime
2.datetime.now()可以取目前時間
3.strftime: 把結構化的 datetime 轉變成指定格式的字串
初學者必學的報時仔:
TG基礎班

除了運用我們已經會的簡單指令以外,來學點有趣的
TG基礎班


先來看如何下載使用者所傳送的照片
TG基礎班
@bot.message_handler(content_types=['photo'])
def handle_photo(message):
file_id=message.photo[-1].file_id
#取得解析度最高的照片
#取得照片的 file_id
#file_id 是 Telegram 的一個唯一標識符,用於獲取該檔案
file_info=bot.get_file(file_id)
#獲取檔案詳細信息,包括檔案的路徑、大小等
downloaded_file=bot.download_file(file_info.file_path)
#下載檔案
with open("received_image.jpg", "wb") as new_file:
new_file.write(downloaded_file)
#檔案名稱可以根據需要任意修改(.PNG/.jpg)
#"w"是write,"b"是二進位模式(binary mode)開啟檔案(如圖片、音訊等會需要使用)
bot.reply_to(message, "圖片已接收並保存!")
簡單說,流程長這樣
TG基礎班
with open("received_image.jpg", "wb")
received_image.jpg(new_file)
創建
以二進位模式寫入資料
簡單說,流程長這樣
TG基礎班
downloaded_file
new_file.write(downloaded_file)
二進位數據(圖片內容)寫入
new_file
簡單說,流程長這樣
TG基礎班
檔案自動關閉
new_file
成功儲存檔案
再來看看如何將照片傳給使用者
有兩種方法:
TG基礎班
1.從本機上傳
2.以連結方式上傳
TG基礎班
從本機上傳照片
@bot.message_handler(commands=['send_photo'])
def send_photo_command(message):
with open("檔名", "rb") as photo:
#圖片不能被解釋成文字,使用r
bot.send_photo(message.chat.id, photo, caption="描述圖片")TG基礎班
以連結方式上傳照片
@bot.message_handler(commands=['send_photo'])
def send_photo_url(message):
url = "檔案連結"
bot.send_photo(message.chat.id, url, caption="描述圖片")
#就是把中間換成url而已TG基礎班
PhotoSize (class)使用:

想要獲取圖片信息?
TG基礎班
PhotoSize (class)使用:
想要獲取圖片信息?
@bot.message_handler(content_types=['photo'])
def handle_photo(message):
photo=message.photo[-1]
file_id=photo.file_id
#唯一標識,用於下載圖片。
unique_id=photo.file_unique_id
#永久標識符(不同bot間保持一致)。
width=photo.width
#寬度(像素)
height=photo.height
#高度(像素)
size=photo.file_size
#檔案大小(bytes)
#圖片信息回覆
response=(
f"圖片信息:\n"
f"File ID: {file_id}\n"
f"Unique ID: {unique_id}\n"
f"尺寸: {width}x{height} 像素\n"
f"檔案大小: {size / 1024:.2f} KB"
# 1 KB = 1024 bytes
# 以浮點數格式輸出,並保留小數點後兩位
)
bot.reply_to(message, response)TG基礎班
file_unique_id跟file_id差在哪裡?
Emmmmmm.......
好像有哪裡怪怪的?
(無論是圖片、音訊、影片都適用)
TG基礎班
file_unique_id跟file_id差在哪裡?
| file_id | file_unique_id | |
|---|---|---|
| 定義 | 唯一標識 | 永久標識 |
| 用途 | 檔案下載和處理 | 檔案比對、 唯一性檢查 |
| 變化 | 不同 bot發送時可能不同 | 永久固定,不隨 bot 變化 |
| 下載文件 | 可以用於下載 | 無法用於下載 |
| 時效性 | 可能會失效 | 永久有效 |
TG基礎班
其實音訊也是類似原理:如何下載使用者傳出的音訊?
@bot.message_handler(content_types=['audio'])
def download_audio(message):
file_info = bot.get_file(message.audio.file_id)
downloaded_file = bot.download_file(file_info.file_path)
#保存到本地
with open(message.audio.file_name, 'wb') as audio_file:
audio_file.write(downloaded_file)
bot.reply_to(message, f"音訊已下載並儲存")TG基礎班
其實語音也是類似原理:如何下載使用者傳出的語音?
把audio改成voice
把.mp3改成.ogg
TG基礎班
那影片呢?
改成video
改成.mp4
聽起來真不戳,對吧
那短影片呢?
對,沒錯,我備課備這裡的時候也很意外
telegram居然有短視頻這種東西?!(圓形影片)
改成video_note就行
TG基礎班
現在來教大家一個酷東西:傳送多個檔案
我們有了新工具:
from telebot.types import InputMediaPhoto
InputMediaPhoto(class)
TG基礎班
現在來教大家一個酷東西:傳送多個檔案
from telebot.types import InputMediaPhoto
@bot.message_handler(commands=['send_photos'])
def send_photos_group(message):
media_group=[
InputMediaPhoto(media=open("1.jpg","rb"), caption="第一張照片"),
InputMediaPhoto(media=open("2.jpg","rb"), caption="第二張照片"),
InputMediaPhoto(media=open("3.jpg","rb"), caption="第三張照片")
]
bot.send_media_group(message.chat.id, media_group)
TG基礎班
再補充一點:
duration():影片和音訊->持續時長(秒)
length():影片的直徑(像素)
TG基礎班
TG Bot內建了很多有趣好玩的小工具
來介紹幾個
TG基礎班
dice功能:
@bot.message_handler(commands=['dice'])
def roll_dice(message):
sent_message=bot.send_dice(message.chat.id, emoji='🎲')
result=sent_message.dice.value #骰子的結果
time.sleep(5)
bot.reply_to(message, f"你擲出了 {result}!")TG基礎班
dice功能:
不只有骰子可以用,同樣的語法可以換不同動畫
大家可以玩看看
🎲 骰子(數字 1 到 6)
🎯 飛鏢(數字 1 到 6,1 表示命中靶心)
🏀 籃球(數字 1 到 5,5 表示投籃成功)
🎳 保齡球(數字 1 到 6)
⚽ 足球(數字 1 到 6)
🎰 老虎机(數字 1 到 64)
TG基礎班
poll投票功能:可以做成quiz測驗!
q="楓資最瘋的幹部是?"
opt=["嘎米", "吱吱", "葉子", "起飛", "咕嚕", "呱呱", "C.Y", "以上皆是"]
correct_answer_index=7
@bot.message_handler(commands=['quiz'])
def send_quiz(message):
bot.send_poll(
chat_id=message.chat.id,
question=q,
options=opt,
is_anonymous=False,
allows_multiple_answers=False
)
bot.send_message(message.chat.id, "請選擇正確的答案!")
@bot.poll_answer_handler()
def handle_poll_answer(poll_answer):
user_id = poll_answer.user.id
selected_option = poll_answer.option_ids[0]
# 因為不允許多選,每次只有一個選項
is_correct = selected_option == correct_answer_index
if is_correct:
result = "恭喜你,答對了!"
else:
result = "抱歉,答案錯誤!"
bot.send_message(user_id, result)TG基礎班
poll投票功能:可以做成quiz測驗!
TG基礎班

但你還有進階班的課哈哈
Telegram Bot
再講進階一點的
今天要讀哪本書
好煩惱啊
來問問bot好了
TG進階班

來製作讀書計畫小幫手叭!
TG進階班
開發要求:
1./help:讓使用者知道 Bot 有哪些指令可以使用
2./add<書>:將書加入book中,並回傳提示訊息給使用者
3./list:用print()將book中的書本全部印出來
4./read:隨機選擇book中的一種科目,並且回傳給使用者
5./import:將Json檔案匯入book
6./export:將存在book中的資料匯出成Json檔案
來製作讀書計畫小幫手叭!
TG進階班
小提示:
1.開始前先複習List和Json檔案讀寫!
2.用 random.choice() 來選擇 list 中的食物
3.記得book要用global
第一個希望大家都能寫出來
TG進階班


我們要避開"add ",所以要用4:
TG進階班

這個應該也該寫出來了(叭?
TG進階班

要判斷一下是不是list為空
TG進階班

用"w"寫入,中文的話也要注意ensure_ascii=False
TG進階班

記得因為book被重新賦值,系統會判定其為區域變數
所以要另外global一次
TG進階班

在這次實作中,我們使用全域變數 "book" 來儲存資料,
這會讓所有使用者的資料是共用的
若是想要讓每個使用者能夠保存自己的資料,
可以使用 Dictionary:
Key 是使用者名稱
Value 是使用者的書單列表
TG進階班
這個問題就留給有興趣的弟妹玩
TG進階班
Inline Keyboard:

TG進階班
Inline Keyboard,按鈕的玩法:
def gen_markup():
markup = InlineKeyboardMarkup()
markup.row_width = 1
markup.add(InlineKeyboardButton('💕', callback_data="double"),
InlineKeyboardButton('💖', callback_data="star"),
InlineKeyboardButton('💘', callback_data="arrow"))
return markup
@bot.message_handler(commands=['inline'])
def message_handler(message):
bot.send_message(message.chat.id, "按鈕選擇", reply_markup=gen_markup())
@bot.callback_query_handler(func=lambda call:True)
def callback(call):
player_choice=call.data
if player_choice=="double":
bot.reply_to(call.message,"double")
elif player_choice=="star":
bot.reply_to(call.message,"star")
else:
bot.send_message(call.message.chat.id,"arrow")TG進階班
蛤?
啊如果我要弄兩個不同功能的按鈕怎麼辦?
call:call.data in ["double", "star","arrow"]
#把call:True改掉就好記得之前說的過濾作用嗎?
只要指定需要的過濾的訊息就好了
TG進階班
按完按鈕會覺得怪怪的?有按跟沒按好像一樣?
pop_message=f"你選的是{player_choice}"
bot.answer_callback_query(call.id,pop_message,show_alert=True)注重客戶UX的我們
肯定要來個方便的小東西來提醒他們對叭?
萬一有五星好評呢?XD
TG進階班
用按鈕實作一個猜拳bot:


TG進階班
用按鈕實作一個猜拳bot:
開發要求:
/game - 顯示出 Inline Keyboard,包含剪刀、石頭、布三個選項
使用者點選 Keyboard 後,Bot 要隨機選擇要出什麼
回傳使用者、Bot 分別出什麼,並且「平手」、「使用者贏」、「Bot 贏」三個情況要分別回傳不同訊息到聊天室中
TG進階班
別忘了要先import


TG進階班
這個一定要寫出來的
對叭?(懇切的眼神

TG進階班
gesture是為了方便取用才寫的list

TG進階班
要有兩個變數,分別表示bot跟player

TG進階班
再來要介紹的是ReplyKeyboardMarkup:
大家在跟bot father聊天的時候,
會發現有個加速溝通的神祕鍵盤
那個東西就被稱為回覆鍵盤
from telebot.types import KeyboardButton, ReplyKeyboardMarkupTG進階班
就這個東西:


TG進階班
可以這樣使用:
@bot.message_handler(commands=['start'])
def send_welcome(message):
keyboard = ReplyKeyboardMarkup(resize_keyboard=True,input_field_placeholder="請選擇一個選項",one_time_keyboard=True)
#按鈕的寬度會根據內容的長度自動調整,節省螢幕空間
#keyboard = ReplyKeyboardMarkup(resize_keyboard=True, row_width=2) 至多兩個按鈕一行
button1 = KeyboardButton("吱吱好中二")
button2 = KeyboardButton("吱吱是怪人")
keyboard.add(button1, button2)
bot.send_message(message.chat.id, "請選擇一個最合適的選項:", reply_markup=keyboard)
@bot.message_handler(func=lambda message: True)
def handle_message(message):
if message.text == "吱吱好中二":
bot.reply_to(message, "確實!")
elif message.text == "吱吱是怪人":
bot.reply_to(message, "雀食!")
else:
bot.reply_to(message, f"收到消息:{message.text}")
bot.infinity_polling()
TG進階班
最後再介紹一個酷東西:
location!!!
相信各位在探索telegram的路途上
會發現這東西居然有定位功能?!
對,我們來借用剛剛學到的鍵盤玩看看

TG進階班
location定位功能:傳送使用者位置
@bot.message_handler(commands=['location'])
def ask_for_location(message):
location_button = KeyboardButton(text="發送我的位置", request_location=True)
markup = ReplyKeyboardMarkup(row_width=1, resize_keyboard=True)
markup.add(location_button)
bot.send_message(message.chat.id, "請分享你的地理位置:", reply_markup=markup)
@bot.message_handler(content_types=['location'])
def handle_location(message):
latitude = message.location.latitude
longitude = message.location.longitude
bot.send_message(message.chat.id, f"你的地理位置是:\n緯度: {latitude}\n經度: {longitude}")
TG進階班
location定位功能:傳送指定位置
@bot.message_handler(commands=['send_location'])
def send_location(message):
latitude=25.07110660725248
longitude=121.52090323406448
bot.send_location(
chat_id=message.chat.id,
latitude=latitude,
longitude=longitude
)TG進階班
恭喜各位結束實作教程,有什麼問題都可以問看看
(關愛的眼神)

Telegram Bot
補充教學
TG進階班
大家在週二的網頁前端似乎也學了點東西
有沒有可能跟bot一起用呢?
哼哼,當然有,講師來補充一下遊戲鑲嵌
TG進階班
直接跟大家分享步驟
詳細的資料在簡報後面給各位研究一下
TG進階班
1.準備一個HTML/JS(遊戲)檔案
2.上傳到GitHub Pages,獲取遊戲網址
3.在BotFather裡輸入指令/newgame
並依指示傳送訊息
4.連接TG Bot程式
TG進階班
1.準備一個HTML/JS(遊戲)檔案
2.上傳到GitHub Pages,獲取遊戲網址
3.在BotFather裡輸入指令/newgame
並依指示傳送訊息
4.連接TG Bot程式
TG進階班
連接TG Bot程式
#你的GitHub Pages遊戲網址
GAME_URL = ""
#遊戲按鈕
@bot.message_handler(commands=['game'])
def send_game(message):
bot.send_game(message.chat.id, "game short name")
# 點擊遊戲按鈕回應
@bot.callback_query_handler(func=lambda call: True)
def game_callback(call):
if call.game_short_name == "game short name":
bot.answer_callback_query(callback_query_id=call.id, url=GAME_URL)
else:
bot.answer_callback_query(callback_query_id=call.id, text="遊戲未找到!")TG進階班
Telegram Bot
設定一下privacy
TG點綴版
1.Enable Privacy mode:不會收到其他人訊息
->Bot 權限不大,要 mention、回覆這個 bot,Bot 才會收到
->預設
2.Disable Privacy mode:Bot 可以讀取輸入的所有訊息
TG的privacy有兩種模式:
TG點綴版
1.找到 Bot Father,輸入 /mybots 選擇你要設定的 Bot
2.依序點選 Bot Settings -> Group Privacy -> Turn off
TG的privacy有兩種模式:
TG點綴版
1.到bot資訊頁面
2.點擊加入群組
3.選擇你的小隊群組
4.開始轟炸你的群組
(如果發現你家bot怪怪的,請按下ctrl+C,拯救你們的群組
將你家bot加入群組:

Telegram Bot
有什麼bot
TG點綴版
用來過濾非真人使用者的互動型 bot,如:
TG點綴版
狼人殺:
TG點綴版
TG點綴版
文件轉換器:
TG點綴版
TG點綴版
遊戲
TG點綴版
Spotify 下載機器人


TG bot
By 愛錢成癡,嗜賭成癮
TG bot
- 153


