-
Notifications
You must be signed in to change notification settings - Fork 1
/
telegram_process.py
349 lines (312 loc) · 14.6 KB
/
telegram_process.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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
import requests
import pandas as pd
from fugle_realtime import intraday
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from config import FUGLE_API_TOKEN,ACCESS_TOKEN
from PIL import Image
from io import BytesIO
#TODO
# string:菜雞,菜雞
# number:股票代碼
# string:適合買嗎?/ 適合賣嗎?
# string:給我圖表 / 給我蠟燭
# string:最佳五檔
# string:注冊某某 API
# string:好友清單
# string:發給某某(全部)
class TelegramBot:
def __init__(self):
"""
Initialize and create use constant variable.
"""
self.chat_id = None
self.in_msg = None
self.first_name = None
self.last_name = None
self.api_db = {}
self.share_db = {}
self.temp_msg = ''
self.temp_share_no = ''
self.prev_action = ''
self.out_msg = ''
self.import_share_no()
def process_data(self,in_msg):
"""
To process and assign the first hand data.
"""
in_msg = in_msg['message']
# Assign to variable
self.chat_id = in_msg['chat']['id']
self.first_name = in_msg['from']['first_name']
self.last_name = in_msg['from']['last_name']
self.content = in_msg['text']
def data_message_judge(self):
"""
Main function to classify the situation.
"""
success = None # To make sure message had been sent
# To double-check that previous action
if str(self.content) in self.share_db.keys():
keyword = self.content
success = self.serv_share_num(keyword,None)
return success
else:
msg_received = self.content
keyword = msg_received[:2]
# Start with the sentence response function
if keyword in ['菜雞','/s']: # serv_greeting
success = self.serv_greeting()
elif keyword in ['代號','股票','代碼','serv_share_num']: # serv_share_num
success = self.serv_share_num(keyword,msg_received)
elif keyword in ['適合','建議','serv_buy_sell']: # serv_buy_sell
success = self.serv_buy_sell(keyword,msg_received)
elif keyword in ['給我','serv_candle_stick']: # serv_candle_stick
success = self.serv_candle_stick(keyword,msg_received)
elif keyword in ['最佳','serv_top_share']: # serv_top_share
success = self.serv_top_share()
elif keyword in ['注冊']: # serv_api_register
success = self.serv_api_register(msg_received)
elif keyword in ['好友']: # serv_friend_list
success = self.serv_friend_list()
elif keyword in ['發送','轉發','分享','轉送','發給']: # serv_forward_msg
success = self.serv_forward_msg(keyword,msg_received)
else: # serv_others
success = self.serv_others(msg_received)
self.prev_action = ''
# Return Boolean as confirmation
return success
def serv_greeting(self):
"""
A welcome content for greeting.
"""
print('【serv_greeting】')
user_name = self.first_name + self.last_name
text = "您好"+ user_name +",菜雞非常高興能夠爲您服務。您可輸入以下關鍵字:\n\
📌 查詢股票資訊【代碼、股票、代號】\n\
📌 當冲交易 【適合、建議】\n\
📌 查詢K綫圖【給我圖標(蠟燭)】\n\
📌 至多最佳5檔【最佳x檔】\n\
📌 注冊好友API【注冊 名稱 API】\n\
📌 轉發資訊給好友【轉發 名稱】\n "
self.out_msg = text
success = self.send_message()
return success
def serv_share_num(self,keyword,msg_received):
"""
To find out the latest price by share number.
"""
print('【serv_share_num】')
# Check whether is previous action
if msg_received == None:
share_no = keyword
else:
share_no = msg_received.split('{}'.format(keyword))[1]
# Collect data from FUGLE API
share_data = intraday.chart(apiToken = FUGLE_API_TOKEN,symbolId = '{}'.format(share_no), output = 'raw')
# Template for Share detail
try:
share_date_time = list(share_data.keys())[-1]
share_res = share_data[share_date_time]
share_res_date_time = share_date_time.split('T')
text = "【{} 最新資訊】\n\
🔺行業類別:{}\n\
🔺日期:{}\n\
🔺時間:{}\n\
🔺開盤價:{}\n\
🔺收盤價:{}\n\
🔺最高價:{}\n\
🔺最低價:{}\n\
🔺交易張數:{}\n\
🔺交易量:{}\n ".format(share_no, \
self.share_db[share_no], \
share_res_date_time[0], \
share_res_date_time[1].split('.')[0], \
share_res['open'], \
share_res['close'], \
share_res['high'], \
share_res['low'], \
share_res['unit'], \
share_res['volume'])
except:
text = "非常抱歉,菜雞能力不及 😥,請重新輸入有效股票代號!"
self.prev_action = "serv_share_num"
self.out_msg = self.temp_msg = text
self.temp_share_no = share_no
success = self.send_message()
return success
def serv_buy_sell(self,keyword,msg_received):
"""
To get information for buy sell in a day.
"""
print('【serv_buy_sell】')
# Check whether has share number in memory
if self.temp_share_no:
share_data = intraday.meta(apiToken = FUGLE_API_TOKEN, symbolId = '{}'.format(self.temp_share_no), output = 'raw')
if share_data['canDayBuySell'] == True and share_data['canDaySellBuy'] == True:
text = "菜雞調查後 😃,建議【{}】{}可進行當冲交易,但最終決定在您手中!😉".format(self.share_db[self.temp_share_no],self.temp_share_no)
else:
text = "菜雞調查後 😃,建議【{}】{}可不進行當冲交易,但最終決定在您手中!😉".format(self.share_db[self.temp_share_no],self.temp_share_no)
else:
text = "抱歉,菜雞不懂您 😥,無法得知您想瞭解的股票!請您重新輸入!"
self.prev_action = "serv_buy_sell"
self.out_msg = self.temp_msg = text
success = self.send_message()
return success
def serv_candle_stick(self,keyword,msg_received):
"""
To get the candle stick graph.
"""
print('【serv_candle_stick】')
# Check whether has share number in memory
if self.temp_share_no:
self.out_msg = "請稍後,菜雞在幫您取圖中,請不要怪我 !😊"
self.send_message()
# Open Candle Stick Web to crop Picture
driver = webdriver.Chrome()
driver.get('https://s.yimg.com/nb/tw_stock_frontend/scripts/TaChart/tachart.a350178a.html?sid=' + str(self.temp_share_no))
png = driver.get_screenshot_as_png()
driver = driver.find_element_by_class_name('tafont')
crop_location = driver.location
crop_size = driver.size
# Crop Picture
img_candle_stick = Image.open(BytesIO(png))
crop_size = {
'top' : crop_location['y'] + 20,
'bottom' : crop_location['y'] + crop_size['height'],
'left' : crop_location['x'],
'right' : crop_location['x'] + crop_size['width'] + 40
}
img_candle_stick = img_candle_stick.crop(
(crop_size['left'],
crop_size['top'],
crop_size['right'],
crop_size['bottom'])
)
img_candle_stick.save('candle_stick.png')
print('PHOTO HERE')
# Send Picture
self.out_msg = self.temp_msg = [img_candle_stick,'截圖 GET!這是【{}】{}之K綫圖。🎉'.format(self.share_db[self.temp_share_no],self.temp_share_no)]
else:
self.out_msg = self.temp_msg = "抱歉,菜雞不懂您 😥,無法得知您想瞭解的股票!請您重新輸入!"
self.prev_action = "serv_candle_stick"
success = self.send_message()
return success
def serv_top_share(self):
"""
To get the best 5 sell and buy price by share number.
"""
print('【serv_top_share】')
# Check whether has share number in memory
if self.temp_share_no:
share_data = intraday.quote(apiToken = FUGLE_API_TOKEN,symbolId = self.temp_share_no, output = 'raw')['order']
# Creat Template For ask bid price
text_ask = "您好 😁,菜雞偷了Fugle的最佳5檔機密,請參考!\n 最佳五檔(買價):\n"
text_bid = "您好 😁,菜雞偷了Fugle的最佳5檔機密,請參考!\n 最佳五檔(賣價):\n"
# Build Specific Text
count = 1
for ask,bid in zip(share_data['bestAsks'],share_data['bestBids']):
temp_ask = '➡' + str(count)+'.價格: '+str(ask['price'])+' 交易張數:'+str(ask['unit'])+' 交易量:'+str(ask['volume']) + "\n "
temp_bid = '➡' + str(count)+'.價格: '+str(bid['price'])+' 交易張數:'+str(bid['unit'])+' 交易量:'+str(bid['volume']) + "\n "
text_ask = text_ask + "{}".format(temp_ask)
text_bid = text_bid + "{}".format(temp_bid)
count+=1
# Send message by List
for send_content in [text_ask,text_bid]:
self.out_msg = send_content
success = self.send_message()
# Save Temp Data
self.temp_msg = [text_ask,text_bid]
else:
self.out_msg = self.temp_msg = "抱歉,菜雞不懂您 🙃,無法得知您想瞭解的股票!請您重新輸入!"
self.prev_action = "serv_top_share"
success = self.send_message()
return success
def serv_api_register(self,msg_received):
"""
To register other bot API for sharing use.
"""
print('【serv_api_register】')
msg_received = msg_received.split(' ')
api_owner,api_token = msg_received[1:]
# Check exist list in db
if api_owner in self.api_db.keys():
self.api_db[api_owner] = api_token
text = "您好,菜雞發現您已針對用戶進行注冊,爲了方便,菜雞已爲您更新 API 咯!🤣"
else:
self.api_db[api_owner] = api_token
text = "好了,恭喜注冊成功 ! 🎉🎉🎉"
self.out_msg = text
success = self.send_message()
return success
def serv_friend_list(self):
"""
To list out the friend list.
"""
print('【serv_friend_list】')
# Check whether is empty
if not bool(self.api_db):
text = "好可憐哦,主人!您目前沒朋友!🤣"
else:
text = "👨💻 您的好友列別如下: \n"
for name in self.api_db.keys():
text = text + "✔ {} \n".format(name)
self.out_msg = self.temp_msg = text
success = self.send_message()
return success
def serv_forward_msg(self,keyword,msg_received):
"""
To forward the importand news to other registered bot.
"""
print('【serv_forward_msg】')
# Check whether is empty
if not bool(self.api_db):
self.out_msg = self.temp_msg = "好可憐哦,主人!您目前沒朋友!🤣"
success = self.send_message()
elif msg_received.split(keyword)[1] not in self.api_db.keys():
self.out_msg = self.temp_msg = "抱歉查無此人!!! 重新再來吧 🤣"
success = self.send_message()
else:
to_api_token = self.api_db[msg_received.split(keyword)[1]]
success = self.send_message(to_api_token)
self.out_msg = self.temp_msg = "報告主人,菜雞已幫您完成轉達!😎"
success = self.send_message()
return success
def serv_others(self,msg_received):
"""
To response the word which not in the service list.
"""
print('【serv_others】')
self.out_msg = self.temp_msg = "{} <- 😒 是在,哈咯!?!".format(msg_received)
success = self.send_message()
return success
def send_message(self,access_token=ACCESS_TOKEN):
"""
To send out the message.
"""
# Create a specific URL
TELEGRAM_BASE = 'https://api.telegram.org/bot{}/'.format(access_token)
api_msg_type = ['sendPhoto','sendMessage']
get_type = str(type(self.out_msg)).split("'")[1]
# Check the type of response message
if get_type == 'str':
res = requests.get(TELEGRAM_BASE + '{}?chat_id={}&text={}'.format(api_msg_type[1],self.chat_id,self.out_msg))
if get_type == 'list':
files = {'photo': open('candle_stick.png','rb')}
data = {'chat_id': self.chat_id}
res = requests.post(TELEGRAM_BASE + '{}'.format(api_msg_type[0]), files = files, data = data)
res = requests.get(TELEGRAM_BASE + '{}?chat_id={}&text={}'.format(api_msg_type[1],self.chat_id,self.out_msg[1]))
return True if res.status_code == 200 else False
def import_share_no(self):
"""
To import the industry list.
"""
df = pd.read_csv('symbol_info.csv', encoding = 'big5')
for industry,symbol_id in zip(df['industry'],df['symbol_id']):
self.share_db[symbol_id] = industry
@staticmethod
def webhook_init(webhook_link):
"""
To connect the ngrok service.
"""
requests.get(webhook_link)