-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMainApp.py
2598 lines (2229 loc) · 179 KB
/
MainApp.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
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
from flask import Flask, request, abort,redirect
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent, TextMessage, TextSendMessage,TemplateSendMessage,ButtonsTemplate,ConfirmTemplate,PostbackEvent,PostbackTemplateAction,FlexSendMessage,FollowEvent,UnfollowEvent
from oauth2client.service_account import ServiceAccountCredentials as SAC
import datetime
import gspread
import configparser
import urllib
import json
import redis
import time
import random
app = Flask(__name__)
# 取得config記事本裡的 LINE 聊天機器人基本資料
config = configparser.ConfigParser()
config.read('config.ini',encoding="utf-8")#encoding一定要加,不然會當機
line_bot_api = LineBotApi(config.get('line-bot','channel_access_token'))
handler = WebhookHandler(config.get('line-bot','channel_secret'))
herokuApp_name = config.get('line-bot','herokuApp_name')
# 接收 LINE 的資訊
@app.route("/callback", methods=['POST'])
def callback():
signature = request.headers['X-Line-Signature']
body = request.get_data(as_text=True)
app.logger.info("Request body: " + body)
try:
print(body, signature)
handler.handle(body, signature)
except InvalidSignatureError:
abort(400)
return 'OK'
#Line Notify第一階段,產生授權網址
client_id = "4XVFGLChmjufoud813nheA"
client_secret = 'YJ9LmymadKN5AOmU85u7DY0gOayv0jsZYfBW6jOnmpP'
redirect_uri = "https://%s.herokuapp.com/callback/notify"%herokuApp_name
def create_auth_link(Id, client_id=client_id, redirect_uri=redirect_uri):
data={
'response_type': 'code',
'client_id': client_id,
'redirect_uri': redirect_uri,
'scope': 'notify',
'state': Id#此可為任何資料([]的資料不行,不知原因),此處用於船user_id
}
query_str = urllib.parse.urlencode(data)
return f'https://notify-bot.line.me/oauth/authorize?{query_str}'
#Line Notify第二,三階段,使用者完成授權網址的連動後,LINE Notify 會將 Code 和 State 等資料與使用者送到 Redirect URI,也就是此函式
@app.route("/callback/notify", methods=['GET'])
def callback_nofity():
#assert request.headers['referer'] == 'https://notify-bot.line.me/'#確認是從 LINE Notify 發送過來的資料(不知why IOS不是,反正不檢查應該沒事)
code = request.args.get('code')#Get code
Id = request.args.get('state')#get state(user_id)
# 第三階段函式(用code去get access_token)
access_token = get_token(code)#其他三項已有,只要code就好
#StoreToken
if Id[0] == "U":#註冊User
rds.hset("user:%s"%Id,"access_token",access_token)
send_message(access_token, "設定完成LineNotify了!!!")#這裡如果Notify已有加入群組,群組又被選到,就會發訊,我想不到更好的方法,只能等全班註冊完再加到班群
password = random.randrange(0,9999)
rds.hset("user:%s"%Id,"password",password)
send_message(access_token, "密碼:%i"%password)
time.sleep(1)
actList = [PostbackTemplateAction(label='我沒收到密碼...',data='start&Notify')]
line_bot_api.push_message(Id,TemplateSendMessage(alt_text='3.輸入密碼',template=ButtonsTemplate(title = "3.輸入密碼",text="請用訊息告訴我,剛剛Notify傳的密碼是(把密碼本體打出來即可)?",actions = actList)))#alt_text也會出現在跳出的視窗,所以必須改
rds.hset("user:%s"%Id,"step",3)#前進一步
return '<h1>恭喜完成 LINE Notify 連動!請關閉此視窗。</h1>'#使用者會看到的網頁
else:#註冊group#只有第一個管理者(發註冊開始的人)才可拿到註冊Group的Link
summary = line_bot_api.get_group_summary(Id)
things = {
"access_token":access_token,
"name":summary.group_name
}
rds.hmset("group",things)
send_message(access_token, "全部人都註冊完了!謝謝大家的配合!")
return '<h1>恭喜完成 LINE Notify Group連動!請關閉此視窗。</h1>'#使用者會看到的網頁
#Line Notify第三階段,用code去get access_token
def get_token(code, client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri):
url = 'https://notify-bot.line.me/oauth/token'
headers = { 'Content-Type': 'application/x-www-form-urlencoded' }
data = {
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': redirect_uri,
'client_id': client_id,
'client_secret': client_secret
}
data = urllib.parse.urlencode(data).encode()#把所有需要data準備好
req = urllib.request.Request(url, data=data, headers=headers)#傳送資料到 LINE Notify
page = urllib.request.urlopen(req).read()#讀取 LINE Notify 回傳的資料
res = json.loads(page.decode('utf-8'))#回傳的資料用json.loads轉換為字典物件
return res['access_token']#讀取字典其中一個key(access_token)
#Line Notify第四階段,有access_token就可以傳訊息了
def send_message(access_token, text_message):
url = 'https://notify-api.line.me/api/notify'
headers = {"Authorization": "Bearer "+ access_token}
data = {'message': text_message}#Line Notify必須傳文字訊息,所以"message"必須有
data = urllib.parse.urlencode(data).encode()
req = urllib.request.Request(url, data=data, headers=headers)
page = urllib.request.urlopen(req).read()
#設定redis物件
rds = redis.Redis(
host = config.get('redis','host'),
port = int(config.get('redis','port')),
password = config.get('redis','password')
)
#因為heroku多端執行,rpush指令會被重複執行(我都是被重複兩次),所以先push任意值,再改成想要的值才行#似乎在更新後沒問題了(不確定是不是This means that TLS v1.0 and v1.1 are no longer supported by clients using OpenSSL to make outbound requests造成)
def rdsRpush(Goal,Word):
rds.rpush(Goal,Word)#任意值(這裡用「龘」字)
#realEnd = rds.llen(Goal) - 2#因為重複兩次,所以-2就是End沒錯
#rds.lset(Goal, realEnd, Word)
#rds.lrem(Goal, 0, "0")#把所有「龘」刪掉(代表list不能有「龘」字),醬就不會產生任何影響
#set 資料(存於redis中),每一次push heroku main就會檢查一次
def setData():
if rds.exists("DoReport") == False:
rds.set("DoReport",1)#0是False
if rds.exists("DoBroadcast") == False:
rds.set("DoBroadcast",1)#0是False
if rds.exists("UnRegisterUser") == False and not rds.exists("HaveStarted"):#如果list沒東西就算是沒有exists!須限制
if rds.exists("TotalStudentNum") == True: #在還沒RunMeBeforeStart前上傳Heroku就會出錯,所以限制
TotalStudentNum = int(rds.get("TotalStudentNum").decode("utf-8"))
for i in range(1,TotalStudentNum+1):
rdsRpush("UnRegisterUser",i)
rdsRpush("UnRegisterUser","師")
if rds.exists("ReceiveBroadcastEditText") == False:
rds.set("ReceiveBroadcastEditText",0)#0是False
rds.set("BroadcastEditArea","Earth")
rds.set("BroadcastEditNum",2021)
setData()
#文字部分不會受重新開始干擾
if rds.exists("BroadcastWord:打掃") == False:
rdsRpush("BroadcastWord:打掃","打掃,偷懶重訓")
rdsRpush("BroadcastWord:打掃","不想愛校就乖乖打掃")
rdsRpush("BroadcastWord:打掃","請移動您尊貴的臀部執行打掃工作")
rdsRpush("BroadcastWord:打掃","打掃 ! 打掃長肌肉")
rdsRpush("BroadcastWord:打掃","打掃 ! 蓄積實力,打倒邪惡資本家!")
rdsRpush("BroadcastWord:打掃","掃具在手 ! 跟股長走 ! 打掃 !")
rdsRpush("BroadcastWord:打掃","我們無產階級,靠掃地崛起 ! 打掃!")
rdsRpush("BroadcastWord:打掃","一日不打掃,三日惡臭。打掃 !")
rdsRpush("BroadcastWord:打掃","掃地 ! 掃地 ! 掃地 !")
rdsRpush("BroadcastWord:打掃","拜託掃地 ! 掃地的人都是好人")
if rds.exists("BroadcastWord:午休") == False:
rdsRpush("BroadcastWord:午休","收手機睡覺")
rdsRpush("BroadcastWord:午休","誰想要重訓啊 ?")
rdsRpush("BroadcastWord:午休","你很.累.了,好..想..睡...覺...")
rdsRpush("BroadcastWord:午休","疲憊,勞累,很..想..睡...覺...")
rdsRpush("BroadcastWord:午休","還有4節課,好累,睡...覺...吧.")
rdsRpush("BroadcastWord:午休","好忙,好多事,睡...一...下....")
rdsRpush("BroadcastWord:午休","不睡覺練肌肉")
rdsRpush("BroadcastWord:午休","睡.覺..睡...覺....睡......ㄐ.")
rdsRpush("BroadcastWord:午休","你可以休..息..了...睡...吧...")
rdsRpush("BroadcastWord:午休","睡.............覺...........")
#設定google sheet
GDriveJSON = config.get('google-sheet','GDriveJSON')#GDriveJSON就輸入下載下來Json檔名稱
GSpreadSheet = config.get('google-sheet','GSpreadSheet') #GSpreadSheet是google試算表名稱
scope = ['https://www.googleapis.com/auth/drive']#定義存取的Scope(範圍),也就是Google Sheet
key = SAC.from_json_keyfile_name(GDriveJSON, scope)
gc = gspread.authorize(key)
worksheet = gc.open(GSpreadSheet).sheet1#sheet1指第一個sheet
@handler.add(MessageEvent, message=TextMessage)# 在此接收訊息事件,回傳值事件(postback)要在下面DataReply接收
def reply(event):
ReplyText = event.message.text
try:#只有group才可用指令
group_id = event.source.group_id
user_id = event.source.user_id
if ReplyText == "設定開始!!":#註冊Start#(可用於大家都有註冊一次後)
if not rds.exists("HaveStarted"):#只能用一次
rds.set("HaveStarted","1")
rdsRpush("Manager_Id",user_id)#發送者就會獲得管理權
rds.hset("group","group_id",group_id)
line_bot_api.reply_message(event.reply_token, TextSendMessage("大家好啊!麻煩大家跟我加好友!\n\n幫助我們不要到現在還在用「紙」「紙」這種19XX年前的骨董來紀錄打掃情況!"))
FlexMessage = json.load(open('座號選擇.json','r',encoding='utf-8'))
line_bot_api.broadcast(FlexSendMessage('註冊開始!!',FlexMessage))#傳給已是好友的人
elif ReplyText == "Beta測試開始!!":#beta測試,就是把UnRegisterUser改為3個人,其他不變(可用於大家都有註冊一次後)
if not rds.exists("HaveStarted"):#只能用一次
rds.set("HaveStarted","1")
rds.delete("UnRegisterUser")
rdsRpush("UnRegisterUser",10)
rdsRpush("UnRegisterUser",19)
rdsRpush("UnRegisterUser","師")
rdsRpush("Manager_Id",user_id)#發送者就會獲得管理權
rds.hset("group","group_id",group_id)
line_bot_api.reply_message(event.reply_token, TextSendMessage("大家好啊!麻煩大家跟我加好友!\n(如果已經是好友就不用了)\n\n幫助我們不要到2021年還在用「紙」這種19XX年前的骨董來紀錄打掃情況!"))
FlexMessage = json.load(open('座號選擇.json','r',encoding='utf-8'))
line_bot_api.broadcast(FlexSendMessage('註冊開始!!',FlexMessage))#傳給已是好友的人
except:#只有單人才可用指令
user_id = event.source.user_id
NowTime = datetime.datetime.now() #get現在時間
if rds.hexists("user:%s"%user_id,"step") and rds.hget("user:%s"%user_id,"step").decode("utf-8") == "3":#第四步,LineNotify確認密碼(因為LineNotify的accessToken無規律,LineBot也看不到Notify的訊息,無法確認是否正確註冊到一對一,所以只好人工確認) #ReplyTest即為密碼
password = ReplyText.rstrip().lstrip()#他們預設是刪除空白
actList = [PostbackTemplateAction(label='確定',data='start&ConfirmNotify&YES&%s'%password) , PostbackTemplateAction(label='手殘打錯',data='start&ConfirmNotify&NO')]
line_bot_api.reply_message(event.reply_token,TemplateSendMessage(alt_text='4.確認密碼',template=ConfirmTemplate(text='4.確認密碼\n\n密碼是%s嗎?'%password,actions = actList)))
rds.hset("user:%s"%user_id,"step",4)#前進一步
if int(rds.get("ReceiveBroadcastEditText")) and rds.hget("user:%s"%user_id,"step").decode("utf-8") == "ㄈ(1)":#編輯廣播文字的ㄈ-1步,要接收文字,所以寫此
EditArea = rds.get("BroadcastEditArea").decode("utf-8")
EditNum = rds.get("BroadcastEditNum").decode("utf-8")
rds.lset("BroadcastWord:%s"%EditArea,int(EditNum),ReplyText)#編輯完成
line_bot_api.push_message(user_id,TextSendMessage("修改完成 !"))#為了順暢體驗用push
#回到ㄇ(1)步(懶了寫函式)
BroadcastWordJSONMaking(EditArea)#製作JSON
FlexMessage = json.load(open('廣播文字編輯器.json','r',encoding='utf-8'))
line_bot_api.reply_message(event.reply_token, FlexSendMessage('ㄇ(1).文字編輯',FlexMessage))
rds.hset("user:%s"%user_id,"step","ㄇ(1)")#前進到ㄇ(1)
rds.set("ReceiveBroadcastEditText",0)#要改回來才可
if ReplyText == "確認註冊情形":
finalword = ""
if rds.exists("Cleaning_Id"):
cleaning_id = "打掃三股長user_id="+str(rds.lrange("Cleaning_Id", 0, -1))
finalword = finalword + cleaning_id+"\n"
tokens=[]
for i in rds.lrange("Cleaning_Id", 0, -1):
Id = i.decode("utf-8")
if rds.hexists("user:%s"%Id,"access_token"):
tokens.append(rds.hmget("user:%s"%Id,"access_token")[0].decode('utf-8'))
cleaning_token = "打掃三股長access_token="+str(tokens)
finalword = finalword + cleaning_token+"\n\n"
if rds.exists("Teacher_Id"):
Id = rds.get("Teacher_Id").decode("utf-8")
teacher_id = "老師user_id=" + Id
finalword = finalword + teacher_id+"\n"
tokens=[]
if rds.hexists("user:%s"%Id,"access_token"):
teacher_token = "老師access_token="+rds.hmget("user:%s"%Id,"access_token")[0].decode('utf-8')
finalword = finalword + teacher_token+"\n\n"
student_word = ""
TotalStudentNum = int(rds.get("TotalStudentNum").decode("utf-8"))
for i in range(1,TotalStudentNum+1):
if rds.hexists("Number_Id", str(i)):
student_id = rds.hmget("Number_Id", str(i))[0].decode('utf-8')
student_word = student_word + "%i號user_id="%i + student_id +"\n"
if rds.hexists("user:%s"%student_id,"access_token"):
student_token = rds.hmget("user:%s"%student_id,"access_token")[0].decode('utf-8')
student_word = student_word + "%i號access_token="%i + student_token +"\n"
student_word = student_word.rstrip()
finalword = finalword + student_word
line_bot_api.reply_message(event.reply_token,TextSendMessage("結果如下:\n"+finalword))
elif ReplyText == "確認大家分數":
student_score = ""
TotalStudentNum = int(rds.get("TotalStudentNum").decode("utf-8"))
for i in range(1,TotalStudentNum+1):
ExcelNum = i + 1#1號在B2格
Score = worksheet.get("B%i"%ExcelNum).first()
student_score = student_score + "%i號有 "%i + Score +" 分\n"
student_score = student_score.rstrip()
line_bot_api.reply_message(event.reply_token,TextSendMessage("大家分數如下:\n"+student_score+"\n\n附贈的PDF檔:\nhttps://docs.google.com/spreadsheets/d/1frVT_AvqGiZKkZQMBFYkS6twj2tMNbPSdXJjJ0FGyPM/export?format=pdf"))
elif ReplyText == "RealTest":
test = "1"
line_bot_api.reply_message(event.reply_token,TextSendMessage("%s"%test))
elif ReplyText == "RealTestOff":
rds.delete("UnRegisterUser")
rdsRpush("UnRegisterUser",10)
rds.lrem("UnRegisterUser",0,10)
test = "0"
line_bot_api.reply_message(event.reply_token,TextSendMessage("%s"%test))
elif ReplyText == "ReportTest":
CleaningCheckOn()
line_bot_api.reply_message(event.reply_token,TextSendMessage("Ok on"))
elif ReplyText == "ReportTestOff":
CleaningCheckOff()
line_bot_api.reply_message(event.reply_token,TextSendMessage("Ok off"))
elif ReplyText == "ResetRichMenu1":
for i in rds.hkeys("Number_Id"):
Id = rds.hget("Number_Id",i.decode("utf-8")).decode("utf-8")
line_bot_api.link_rich_menu_to_user(Id,config.get("RM_MiddleNormal","id"))
rds.hdel("user:%s"%i,"UsingRichMenu")
line_bot_api.reply_message(event.reply_token,TextSendMessage("Ok fin reset 1"))
elif ReplyText == "ResetRichMenu2":
rds.delete("APersonCanUsingRichMenu")
rds.delete("CleaningChangedNums")#要刪除所有可能的暫存變數
rds.delete("CleaningChangedNums")#要刪除所有可能的暫存變數
for i in rds.lrange("Manager_Id", 0, -1):
Id = i.decode("utf-8")
line_bot_api.link_rich_menu_to_user(Id,config.get("RM_MiddleManage","id"))
for i in rds.lrange("Cleaning_Id", 0, -1):
Id = i.decode("utf-8")
line_bot_api.link_rich_menu_to_user(Id,config.get("RM_MiddleCleaning","id"))
rds.delete("QuittingCleaning:%s"%Id)#要刪除所有可能的暫存變數
rds.delete("QuittingCleaning:%s"%Id)#要刪除所有可能的暫存變數
line_bot_api.reply_message(event.reply_token,TextSendMessage("Ok fin reset 2"))
elif ReplyText == "DeleteUsingRichMenu":
rds.delete("APersonCanUsingRichMenu")
line_bot_api.reply_message(event.reply_token,TextSendMessage("Ok delete"))
elif ReplyText == "Export":
line_bot_api.reply_message(event.reply_token,TextSendMessage("https://docs.google.com/spreadsheets/d/1frVT_AvqGiZKkZQMBFYkS6twj2tMNbPSdXJjJ0FGyPM/export?format=xlsx"))
elif ReplyText == "SendTest":
Send()
line_bot_api.reply_message(event.reply_token,TextSendMessage("Fin send"))
elif ReplyText == "Delete":
rds.delete("OriginalCleaningNum")#刪除暫存變數
line_bot_api.reply_message(event.reply_token,TextSendMessage("fin del" ))
elif ReplyText == "ManageTest":
line_bot_api.reply_message(event.reply_token,TextSendMessage(config.get("RM_MiddleManage","id")))
line_bot_api.link_rich_menu_to_user(user_id,config.get("RM_MiddleManage","id"))
rds.hdel("user:%s"%user_id,"UsingRichMenu")
elif ReplyText == "CleaningTest":
line_bot_api.reply_message(event.reply_token,TextSendMessage(config.get("RM_MiddleCleaning","id")))
line_bot_api.link_rich_menu_to_user(user_id,config.get("RM_MiddleCleaning","id"))
rds.hdel("user:%s"%user_id,"UsingRichMenu")
elif ReplyText == "BecomeManager":
rdsRpush("Manager_Id",user_id)
rds.lrem("Cleaning_Id",0,user_id)
line_bot_api.reply_message(event.reply_token,TextSendMessage("fin change Manager(del Cleaning)"))
elif ReplyText == "BecomeCleaning":
rdsRpush("Cleaning_Id",user_id)
rds.lrem("Manager_Id",0,user_id)
line_bot_api.reply_message(event.reply_token,TextSendMessage("fin change Cleaning(del Manager)"))
elif ReplyText == "Test":
line_bot_api.reply_message(event.reply_token,TextSendMessage(config.get("RM_MiddleNormal","id")))
line_bot_api.link_rich_menu_to_user(user_id, config.get("RM_MiddleNormal","id"))
rds.hdel("user:%s"%user_id,"UsingRichMenu")
elif ReplyText == "Register":
FlexMessage = json.load(open('座號選擇.json','r',encoding='utf-8'))
line_bot_api.reply_message(event.reply_token, FlexSendMessage('註冊開始!!',FlexMessage))
elif ReplyText == "ResetStep":
rds.hset("user:%s"%user_id,"step","0")
line_bot_api.reply_message(event.reply_token,TextSendMessage("fin ResetStep"))
elif ReplyText == "ResetUnRegisterUser":
rds.delete("UnRegisterUser")
setData()#把UnRegisterUser用回來
line_bot_api.reply_message(event.reply_token,TextSendMessage("fin ResetUnRegisterUser"))
elif ReplyText == "SetToFinishStep":
rds.hset("user:%s"%user_id,"step","5")
rds.hdel("user:%s"%user_id,"UsingRichMenu")
line_bot_api.reply_message(event.reply_token,TextSendMessage("fin SetStep"))
elif ReplyText == "ForceRestart":
Idlist = []
if rds.exists("Number_Id"):
for i in rds.hkeys("Number_Id"):
Id = rds.hget("Number_Id",i.decode("utf-8")).decode("utf-8")
Idlist.append(Id)
if rds.exists("Teacher_Id"):
Idlist.append(rds.get("Teacher_Id").decode("utf-8"))
line_bot_api.unlink_rich_menu_from_users(Idlist)
Token = rds.hget("group","access_token").decode("utf-8")
send_message(Token, "\n重製作業已啟動,所有服務都會中止") #原本超多訊息干擾會來不及做完,就會停止,所以改成群組說明
send_message(Token, "\n如果真的結束了,請封鎖或退好友Line Bot,才不會收到更多訊息")
send_message(Token, "\n非常感謝您的使用。")
actList = [PostbackTemplateAction(label='給我繼續',data='REsettingALL&KeepGoing')]
line_bot_api.reply_message(event.reply_token,TemplateSendMessage(alt_text='喘一下 :',template=ButtonsTemplate(text="肆(2)喘一下:\n\n有夠累,呼,但不能回頭了\n就等老大說繼續!",actions = actList)))
rds.hset("user:%s"%user_id,"step","肆(2)")#前進一步
elif ReplyText == "GetLink":
group_id = rds.hget("group","group_id").decode("utf-8")
send_message(rds.hget("user:%s"%user_id,"access_token").decode("utf-8"),"Group_link(請先加入群組再註冊):"+create_auth_link(group_id))
line_bot_api.reply_message(event.reply_token,TextSendMessage("temporary person linkk:"+create_auth_link(user_id)))
elif ReplyText == "Wonwon":
Token = event.reply_token
line_bot_api.reply_message(Token,TextSendMessage("OK!"))
Wonwon(user_id)
elif ReplyText == "Hour":
line_bot_api.reply_message(event.reply_token,TextSendMessage(NowTime.hour))
elif ReplyText == "Minute":
line_bot_api.reply_message(event.reply_token,TextSendMessage(NowTime.minute))
elif ReplyText == "Second":
line_bot_api.reply_message(event.reply_token,TextSendMessage(NowTime.second))
elif rds.hexists("user:%s"%user_id,"step") and rds.hget("user:%s"%user_id,"step").decode("utf-8") == "2":#以為要打密碼(測試後人性化修正)
line_bot_api.reply_message(event.reply_token,TextSendMessage("請再點一次連結,重新連動Notify!"))
else:#敷衍系統
if rds.exists("HaveStarted"):#全部重新開始後就不給聊
if not rds.exists("user:%s"%user_id) or rds.hget("user:%s"%user_id,"number") in rds.lrange("UnRegisterUser",0,-1):
line_bot_api.reply_message(event.reply_token,TextSendMessage("請先註冊,不要瞎聊"))
else:
words = ["喔~","摁~","蛤?","好喔","喔。","耶?","...","已讀","笑死","隨便"]
line_bot_api.reply_message(event.reply_token,TextSendMessage(words[random.randint(0,9)]))
@handler.add(FollowEvent)# 加好友事件在此接收
def FollowReply(event):
if rds.exists("HaveStarted"): #開始才發
FlexMessage = json.load(open('座號選擇.json','r',encoding='utf-8'))
line_bot_api.reply_message(event.reply_token, FlexSendMessage('註冊開始!!',FlexMessage))#傳給剛加好友的人
@handler.add(UnfollowEvent)# 封鎖事件在此接收(相當於刪除帳號)
def UnFollowReply(event):
if rds.exists("HaveStarted"): #開始才發
user_id = event.source.user_id
if bytes(user_id,"utf-8") in rds.lrange("Manager_Id", 0, -1):#移除管理員身分
rds.lrem("Manager_Id",0,user_id)
elif rds.exists("Cleaning_Id") and bytes(user_id,"utf-8") in rds.lrange("Cleaning_Id", 0, -1):#移除打掃股長身分
num = rds.hget("user:%s"%user_id,"number").decode("utf-8")
rds.lrem("Cleaning_Num",0,num)#刪除選擇,不然重複註冊時仍會成為打掃股長
rds.lrem("Cleaning_Id",0,user_id)
LeadArea = rds.hget("user:%s"%user_id,"LeadSection").decode("utf-8")
rds.hdel("user:%s"%user_id,"LeadSection")
rds.delete("CleaningSection:%s"%user_id)
rds.delete("CleaningSection:%s"%LeadArea)
if rds.exists("QuittingCleaning:%s"%user_id):#有可能正在等是否要替代打掃股長,無效他!
DeleteAskingQuitting(user_id)
if rds.exists("CleaningTemporaryReplace:%s"%user_id):#有可能正在暫時委託他人做打掃股長
DeleteTemporaryReplacement(user_id)
FirstManager_id = rds.lindex("Manager_Id", 0).decode("utf-8")
send_message(rds.hget("user:%s"%FirstManager_id,"access_token").decode("utf-8"),"有打掃股長很沒品地封鎖我了...,麻煩您重選打掃股長!不然股長會從缺!")
if rds.exists("Teacher_Id") and rds.get("Teacher_Id").decode("utf-8") == user_id:#是老師
rds.delete("Teacher_Id")
rdsRpush("UnRegisterUser","師")
else:#同學
num = rds.hget("user:%s"%user_id,"number").decode("utf-8")
rds.hdel("Number_Id", num)
rdsRpush("UnRegisterUser",num)
if rds.hexists("user:%s"%user_id,"UsingRichMenu") and rds.exists("APersonCanUsingRichMenu"):
UsingClickedRichMenu = rds.hget("user:%s"%user_id,"UsingRichMenu").decode("utf-8")
if bytes(UsingClickedRichMenu,"utf-8") in rds.hkeys("APersonCanUsingRichMenu"):#正在用的是只能一個人用的RcihMenu,要讓別人可以用
rds.hdel("APersonCanUsingRichMenu",UsingClickedRichMenu)#讓其他人可用
rds.delete("user:%s"%user_id)
line_bot_api.unlink_rich_menu_from_user(user_id)#刪除RichMenu
rds.hdel("user:%s"%user_id,"UsingRichMenu")#要換新RichMenu,把舊的使用紀錄刪除
@handler.add(PostbackEvent)# 回傳值事件在此接收
def DataReply(event):
user_id = event.source.user_id
ReplyData = event.postback.data
if rds.hexists("user:%s"%user_id,"step"):#第一次時才不會出問題
NowStep = rds.hget("user:%s"%user_id,"step").decode("utf-8")#步數系統
#================================註冊系統==================================#
#-----------------註冊--------------------#
if ReplyData[0:3] == "del":#[0:3]指第0個起到第3個前#重新註冊
if ReplyData[4:9] == "start":
if NowStep == "5" or (NowStep == "A" or NowStep == "a"):#完成註冊,或是(正要開始選打掃股長 或 正要開始捲打掃成員)才可用
word = '6.你認真要重新註冊?'
if bytes(user_id,"utf-8") in rds.lrange("Manager_Id", 0, -1):#是管理員需要額外提醒
if rds.llen("Manager_Id") == 1:#只剩一個管理員,不行移除
word = word + "\n。只剩您是管理員,權力不移除\n。打掃股長也會留著"
else:
word = word + "\n。管理員身分會被一起移除\n。打掃股長仍會留著"
word = word + "\n。打掃股長身分不會被移除\n(如果)"
actList = [PostbackTemplateAction(label='認真的',data='del&do&YES') , PostbackTemplateAction(label='後悔了',data='del&do&NO')]
line_bot_api.reply_message(event.reply_token,TemplateSendMessage(alt_text='快跟我說要不要重新註冊!!',template=ConfirmTemplate(text=word,actions = actList)))
rds.hset("user:%s"%user_id,"step",6)#前進一步
rds.hset("user:%s"%user_id,"PreStep",NowStep) # 因為開始時可能為5 A a,要特別標記,在6回5的時候才能回到正確的開頭
else:
line_bot_api.reply_message(event.reply_token,TextSendMessage("%s"%ReplyWrongStep(NowStep)))
elif ReplyData[4:6] == "do":#刪除!!
if NowStep == "6":
if ReplyData[7:10] == "YES":
if bytes(user_id,"utf-8") in rds.lrange("Manager_Id", 0, -1):#移除管理員身分
if rds.llen("Manager_Id") != 1:#只剩一個管理員,不行移除
rds.lrem("Manager_Id",0,user_id)
elif rds.exists("Cleaning_Id") and bytes(user_id,"utf-8") in rds.lrange("Cleaning_Id", 0, -1):#移除打掃股長身分
rds.lrem("Cleaning_Id",0,user_id)
LeadArea = rds.hget("user:%s"%user_id,"LeadSection").decode("utf-8")
rds.hdel("user:%s"%user_id,"LeadSection")
rds.delete("CleaningSection:%s"%user_id)
rds.delete("CleaningSection:%s"%LeadArea)
if rds.exists("QuittingCleaning:%s"%user_id):#有可能正在等是否要替代打掃股長,無效他!
DeleteAskingQuitting(user_id)
if rds.exists("CleaningTemporaryReplace:%s"%user_id):#有可能正在暫時委託他人做打掃股長
DeleteTemporaryReplacement(user_id)
if rds.exists("Teacher_Id") and rds.get("Teacher_Id").decode("utf-8") == user_id:#是老師
rds.delete("Teacher_Id")
rdsRpush("UnRegisterUser","師")
else:#同學
num = rds.hget("user:%s"%user_id,"number").decode("utf-8")
rds.hdel("Number_Id", num)
rdsRpush("UnRegisterUser",num)
rds.delete("user:%s"%user_id)
rds.hset("user:%s"%user_id,"step",0)#避免此時以前的步驟被亂點
line_bot_api.unlink_rich_menu_from_user(user_id)#刪除RichMenu
if rds.hexists("user:%s"%user_id,"UsingRichMenu"):
rds.hdel("user:%s"%user_id,"UsingRichMenu")#要換新RichMenu,把舊的使用紀錄刪除
line_bot_api.reply_message(event.reply_token, TextSendMessage("你的資料全部刪好了。有需要就重新再註冊一次吧!"))
FlexMessage = json.load(open('座號選擇.json','r',encoding='utf-8'))
line_bot_api.push_message(user_id, FlexSendMessage('profile',FlexMessage))
else:#No
word = "不用重新註冊!沒事就好 沒事就好"
PreStep = rds.hget("user:%s"%user_id,"PreStep").decode("utf-8")
if PreStep != "5":
word = word + "\n可以回去繼續選了~"
rds.hset("user:%s"%user_id,"step",PreStep)#回到做完狀態
line_bot_api.reply_message(event.reply_token, TextSendMessage(word))
if rds.hexists("user:%s"%user_id,"UsingRichMenu") == True and rds.hget("user:%s"%user_id,"UsingRichMenu").decode("utf-8") == "RightDeleteAccountClicked":#使用RichMenu重新註冊紐,
RichMenuFunctionEnd(user_id, "Right")
if rds.hexists("user:%s"%user_id,"BeChoosenAsCleaning"):#可能註冊完者在思考重新註冊時觸發,導致可以避免任命
line_bot_api.unlink_rich_menu_from_user(user_id)#刪除RichMenu
rds.hdel("user:%s"%user_id,"UsingRichMenu")#要換新RichMenu,把舊的使用紀錄刪除
rds.hdel("user:%s"%user_id,"BeChoosenAsCleaning")#刪除暫存變數
FlexMessage = json.load(open('打掃成員選擇.json','r',encoding='utf-8'))
line_bot_api.push_message(user_id, FlexSendMessage('選擇你掃區的人!!',FlexMessage))
rds.hset("user:%s"%user_id,"step","a")
else:
line_bot_api.reply_message(event.reply_token,TextSendMessage("%s"%ReplyWrongStep(NowStep)))
elif ReplyData[0:5] == "start":#註冊
if rds.hexists("user:%s"%user_id,"step") == False:#步數設定(才不會以前的步驟被亂點),做一次點擊就前進一步
rds.hset("user:%s"%user_id,"step",0)
NowStep = rds.hget("user:%s"%user_id,"step").decode("utf-8")
if ReplyData[6:9] == "num":#第一步,號碼註冊
if NowStep == "0":#步數確認(做完第0步)
num = ReplyData[10:]
if num == "師" and not rds.exists("Teacher_Id"):#是沒註冊老師,發確認消息("UnRegisterUser"是最後才更改,Number_Id在較前面更改,同時在註冊時被選走機率較低)
actList = [PostbackTemplateAction(label='YES',data='start&ConfirmNum&YES&%s'%num) , PostbackTemplateAction(label='NO',data='start&ConfirmNum&NO&%s'%num)]
line_bot_api.reply_message(event.reply_token, TemplateSendMessage(alt_text='我確認一下,你是老師嗎?',template=ConfirmTemplate(text='1.我確認一下,你是老師嗎?',actions = actList)))#alt_text不可省略
rds.hset("user:%s"%user_id,"step",1)#前進一步
elif num != "師" and not rds.hexists("Number_Id",num):#是沒註冊號碼
actList = [PostbackTemplateAction(label='YES',data='start&ConfirmNum&YES&%s'%num) , PostbackTemplateAction(label='NO',data='start&ConfirmNum&NO&%s'%num)]
line_bot_api.reply_message(event.reply_token, TemplateSendMessage(alt_text='我確認一下,你是%s號嗎?'%num,template=ConfirmTemplate(text='1.我確認一下,你是%s號嗎?'%num,actions = actList)))
rds.hset("user:%s"%user_id,"step",1)#前進一步
else:#是已註冊號碼,提醒(不會前進一步)
if num == "師":
HasGotUseid = rds.get("Teacher_Id").decode("utf-8")
if bytes(num,"utf-8") in rds.lrange("UnRegisterUser",0,-1):#完全註冊好了
HasGotName = rds.hget("user:%s"%HasGotUseid,"name").decode("utf-8")
line_bot_api.reply_message(event.reply_token, TextSendMessage("老師已被%s註冊走了,如果你是老師,就請他重新註冊吧!"%HasGotName))
else:
line_bot_api.reply_message(event.reply_token, TextSendMessage("老師被「暫時」註冊走了,如果你是老師,可以等一下再按一次,可能就可以註冊or知道是誰註冊走的"))
else:
HasGotUseid = rds.hget("Number_Id",num).decode("utf-8")
if bytes(num,"utf-8") in rds.lrange("UnRegisterUser",0,-1):#完全註冊好了
HasGotName = rds.hget("user:%s"%HasGotUseid,"name").decode("utf-8")
line_bot_api.reply_message(event.reply_token, TextSendMessage("%s號已被%s註冊走了,如果%s是你的號碼,就請他重新註冊吧!"%(num,HasGotName,num)))
else:
line_bot_api.reply_message(event.reply_token, TextSendMessage("%s號「暫時」註冊走了,如果你是%s號,可以等一下再按一次,可能就可以註冊or知道是誰註冊走的"%(num,num)))
else:
line_bot_api.push_message(user_id,TextSendMessage("%s"%ReplyWrongStep(NowStep)))
elif ReplyData[6:16] == "ConfirmNum":#第二步,確認號碼註冊正確+註冊好號碼,學號與名子
if NowStep == "1":#步數確認(做完第1步)
if ReplyData[17:20] == "YES":
num = ReplyData[21:]
if num == "師":
userProfile = line_bot_api.get_profile(user_id)
rds.set("Teacher_Id",user_id)
rds.hset("user:%s"%user_id,"name",userProfile.display_name)
if bytes(user_id,"utf-8") not in rds.lrange("Manager_Id",0,-1):#如果招集者 == 老師,就不用再給一次
rdsRpush("Manager_Id",user_id)#老師有管理員權力
line_bot_api.reply_message(event.reply_token,TextSendMessage("2.連動Line Notify\n\n老師,請連動Line Notify!步驟:\n\t(1)點下面的連結\n\t(2)選擇「透過 1 對 1 聊天接收 LINE Notify 通知」然後按「同意並連動」即可\n\n網址:"+"https://%s.herokuapp.com/CheckNotify/%s"%(herokuApp_name,user_id)))
else:
userProfile = line_bot_api.get_profile(user_id)
rds.hset("Number_Id",num,user_id)
rds.hset("user:%s"%user_id,"name",userProfile.display_name)
rds.hset("user:%s"%user_id,"number",num)
line_bot_api.reply_message(event.reply_token,TextSendMessage("2.連動Line Notify\n\n%s同學,請連動Line Notify!步驟:\n\t(1)點下面的連結\n\t(2)選擇「透過 1 對 1 聊天接收 LINE Notify 通知」然後按「同意並連動」即可\n\n網址:"%userProfile.display_name + "https://%s.herokuapp.com/CheckNotify/%s"%(herokuApp_name,user_id)))
rds.hset("user:%s"%user_id,"step",2)#前進一步
else:#No
line_bot_api.reply_message(event.reply_token,TextSendMessage("好喔,取消註冊。\n記得再重頭(第0步)註冊一次喔!"))
rds.hset("user:%s"%user_id,"step",0)#回到第0步
else:
line_bot_api.reply_message(event.reply_token,TextSendMessage("%s"%ReplyWrongStep(NowStep)))
elif ReplyData[6:12] == "Notify":#第四步,LineNotify確認密碼(因為LineNotify的accessToken無規律,LineBot也看不到Notify的訊息,無法確認是否正確註冊到一對一,所以只好人工確認)
if NowStep == "3":#步數確認(做完第3步)
line_bot_api.reply_message(event.reply_token,TextSendMessage("那應該是選到群組了。選「透過 1 對 1 聊天接收 LINE Notify 通知」才對!再回去點一次連結吧!"))
rds.hset("user:%s"%user_id,"step",2)#前進一步
else:
line_bot_api.reply_message(event.reply_token,TextSendMessage("%s"%ReplyWrongStep(NowStep)))
elif ReplyData[6:19] == "ConfirmNotify":#第五步,註冊完成 + 確認資料正確 + 重新註冊
if NowStep == "4":#步數確認(做完第4步)
if ReplyData[20:23] == "YES":
password = ReplyData[24:]
if password != rds.hget("user:%s"%user_id,"password").decode("utf-8"):
line_bot_api.reply_message(event.reply_token,TextSendMessage("密碼錯誤!再打一次吧!\n如果不知密碼就按 沒收到密碼... 求救"))
rds.hset("user:%s"%user_id,"step",3)#回到第3步
else:
if rds.exists("Teacher_Id") and user_id == rds.get("Teacher_Id").decode("utf-8"):#是老師#沒exists就不會執行get,避免出錯
num = "老師"
rds.lrem("UnRegisterUser",0,"師")
else:
num = rds.hget("user:%s"%user_id,"number").decode("utf-8")
rds.lrem("UnRegisterUser",0,num)
if rds.hexists("user:%s"%user_id,"access_token"):
HasNotify = "已註冊"
else:
HasNotify ="未註冊"
actList = [PostbackTemplateAction(label='重新註冊(長存)',data='del&start')]
line_bot_api.push_message(user_id,TextSendMessage("密碼正確!謝謝你的配合!!最後,請確認你的資料是否正確:\n\n\t座號(老師):%s\n\tLineNotify:%s\n\n如果有錯,請點下面的重新註冊鈕,沒錯就全部註冊完了,謝謝你的配合!!"%(num,HasNotify)))
line_bot_api.reply_message(event.reply_token,TemplateSendMessage(alt_text='註冊完了!!',template=ButtonsTemplate(title="5.註冊完了!!",text='需要重新註冊來這~',actions = actList)))#text有字數限制,在這裡做JSON檔太麻煩了,只好push Message
rds.hset("user:%s"%user_id,"step",5)#道第5步(完成步)
time.sleep(3)
if num == "老師":#老師要選打掃股長
if not rds.exists("Cleaning_Id"):#沒有人選過才需要選
FlexMessage = json.load(open('打掃股長選擇.json','r',encoding='utf-8'))
line_bot_api.push_message(user_id, FlexSendMessage('選擇打掃股長!!',FlexMessage))
rds.hset("user:%s"%user_id,"step","A")#到第A步
else:
line_bot_api.link_rich_menu_to_user(user_id,config.get("RM_MiddleManage","id"))#可以直接有RichMenu
elif bytes(num,"utf-8") in rds.lrange("Cleaning_Num", 0, -1):#是打掃股長
FlexMessage = json.load(open('打掃成員選擇.json','r',encoding='utf-8'))
line_bot_api.push_message(user_id ,FlexSendMessage('選擇你掃區的人!!',FlexMessage))
rds.hset("user:%s"%user_id,"step","a")#到第a步
elif bytes(user_id,"utf-8") in rds.lrange("Manager_Id", 0, -1):#是管理員,可以直接有RichMenu(老師也是管理員,但已被if else語句去除,沒問題)
line_bot_api.link_rich_menu_to_user(user_id,config.get("RM_MiddleManage","id"))
else:#一般人可以使用RichMenu了
line_bot_api.link_rich_menu_to_user(user_id,config.get("RM_MiddleNormal","id"))
if rds.llen("UnRegisterUser") == 0:#全部人註冊完了,註冊Group時間(請先加入群組再註冊)
FirstManager_id = rds.lindex("Manager_Id", 0).decode("utf-8")#由第一個Manager(發設定開始者)為代表
group_id = rds.hget("group","group_id").decode("utf-8")
send_message(rds.hget("user:%s"%FirstManager_id,"access_token").decode("utf-8"),"Group_link(請先加入群組再註冊):"+create_auth_link(group_id))
else:#No
line_bot_api.reply_message(event.reply_token,TextSendMessage("再打一次吧!\n如果不知密碼就按 沒收到密碼... 吧!"))
rds.hset("user:%s"%user_id,"step",3)#回到第3步
else:
line_bot_api.reply_message(event.reply_token,TextSendMessage("%s"%ReplyWrongStep(NowStep)))
#-------------------------------------------#
#---------------選打掃股長-------------------#
elif ReplyData[0:11] == "GetCleaning":#老師註冊打掃股長
NowStep = rds.hget("user:%s"%user_id,"step").decode("utf-8")
if ReplyData[12:15] == "num":#第A步,選號碼
if NowStep == "A":
num = ReplyData[16:]
if num == "Fin":#選完了
if not rds.exists("Cleaning_Num") or (rds.exists("Cleaning_Num") and rds.llen("Cleaning_Num") != 3):
line_bot_api.reply_message(event.reply_token,TextSendMessage("打掃股長要有也只有三個!回去再選吧!"))
else:
SortRedisList("Cleaning_Num")
Chosen = ""
for i in rds.lrange("Cleaning_Num", 0, -1):
Chosen = Chosen + i.decode("utf-8") + ","
Chosen = Chosen.rstrip(",")
actList = [PostbackTemplateAction(label='OK!',data='GetCleaning&done&YES') , PostbackTemplateAction(label='不OK',data='GetCleaning&done&NO')]
line_bot_api.reply_message(event.reply_token,TemplateSendMessage(alt_text='確定選完了嗎?',template=ConfirmTemplate(text='B.確定選:%s為打掃股長?'%Chosen,actions = actList)))
rds.hset("user:%s"%user_id,"step","B")#到第B步
else:#選擇號碼
if rds.hexists("Number_Id",num) and rds.hget("Number_Id",num) in rds.lrange("Manager_Id",0,-1):#一個人不可以同時為管理員與打掃股長,會出問題(未註冊不會是管理員,增減管理員功能在註冊好後才開放)
line_bot_api.reply_message(event.reply_token,TextSendMessage("他/她是管理員,沒辦法同時當打掃股長!"))
else:
if rds.exists("Cleaning_Num") and (bytes(num,"utf-8") in rds.lrange("Cleaning_Num", 0, -1)):#是選過的,取消選取
rds.lrem("Cleaning_Num",0,num)
else:#增加
rdsRpush("Cleaning_Num",num)
Chosen = ""
for i in rds.lrange("Cleaning_Num", 0, -1):
Chosen = Chosen + i.decode("utf-8") + ","
Chosen = Chosen.rstrip(",")
line_bot_api.reply_message(event.reply_token,TextSendMessage("目前你選了 : "+Chosen))
else:
line_bot_api.reply_message(event.reply_token,TextSendMessage("%s"%ReplyWrongStep(NowStep)))
elif ReplyData[12:16] == "done":#第B步,確認選擇正確
if NowStep == "B":
if ReplyData[17:] == "YES":
CheckNum = ""
for i in rds.lrange("Cleaning_Num", 0, -1):#完全註冊好者,發選成員的訊息
num = i.decode("utf-8")
CheckNum = CheckNum + num + ","
if (not rds.exists("OriginalCleaningNum")) or (i not in rds.lrange("OriginalCleaningNum",0,-1)):#第一次選or重選,都是沒有變有(三種情況:沒註冊、沒註冊完、已註冊完平民)
if bytes(num,"utf-8") not in rds.lrange("UnRegisterUser",0,-1):#如沒有就是未註冊,無須主動發訊(等註冊完會發)
ChosenId = rds.hget("Number_Id",num).decode("utf-8")
ChosenStep = rds.hget("user:%s"%ChosenId,"step").decode("utf-8")
if ChosenStep == "5":#完全註冊好者,發選成員的訊息,未註冊完全者,無須主動發訊(等註冊完會發)
line_bot_api.unlink_rich_menu_from_user(ChosenId)#刪除RichMenu
rds.hdel("user:%s"%ChosenId,"UsingRichMenu")#要換新RichMenu,把舊的使用紀錄刪除
FlexMessage = json.load(open('打掃成員選擇.json','r',encoding='utf-8'))
line_bot_api.push_message(ChosenId, FlexSendMessage('選擇你掃區的人!!',FlexMessage))
rds.hset("user:%s"%ChosenId,"step","a")
else:
if ChosenStep == "6":#可能註冊完者在思考重新註冊時觸發,導致可以避免任命
rds.hset("user:%s"%ChosenId,"BeChoosenAsCleaning",1)
CheckNum = CheckNum.rstrip(",")
if rds.exists("OriginalCleaningNum"):
taker = rds.hget("user:%s"%user_id, "name").decode("utf-8")
for i in rds.lrange("OriginalCleaningNum", 0, -1):#與原本比對沒有的人
num = i.decode("utf-8")
if i not in rds.lrange("UnRegisterUser",0,-1):#根本沒註冊就不用改
DisChosenId = rds.hget("Number_Id",num).decode("utf-8")
DisChosenStep = rds.hget("user:%s"%DisChosenId,"step").decode("utf-8")
if i not in rds.lrange("Cleaning_Num", 0, -1):#重選,有變沒有(四種情況:股長未選成員、股長選成員中、已註冊完股長未用RichMenu、已註冊完股長正在用RichMenu),打掃股長RcihMenu在選完掃區才會給,所以要看如何刪除RichMenu
if not rds.hexists("user:%s"%DisChosenId,"LeadSection"):#未選完成員
if DisChosenStep == "a":#股長未選成員
line_bot_api.push_message(DisChosenId, TextSendMessage("%s把您的打掃股長權限收回了,不用選成員了,那就全部註冊完成了~"%taker))
rds.delete("CleaningSection:%s"%DisChosenId)#刪除暫存變數(可能選1個人時被換)
rds.hset("user:%s"%DisChosenId,"step","5")#強制回歸完成步
else:#股長選成員中
rds.delete("CleaningSection:%s"%DisChosenId)#刪除暫存變數(那時是依靠ReplyData傳資料,所以暫存變數很少,其實也不算站存,這還有用處)
rds.hset("user:%s"%DisChosenId,"step","5")#強制回歸完成步
line_bot_api.push_message(DisChosenId, TextSendMessage("%s把您的打掃股長權限收回了,不用再選了,那就全部註冊完成了~"%taker))
line_bot_api.link_rich_menu_to_user(DisChosenId,config.get("RM_MiddleNormal","id"))#給他RichMenu
else:#選完成員(刪除打掃股長時只有刪Cleaning_Num(暫存變數),其他的紀錄(選成員的變數)在此一並刪)
rds.lrem("Cleaning_Id",0,DisChosenId)
LeadArea = rds.hget("user:%s"%DisChosenId,"LeadSection").decode("utf-8")
rds.hdel("user:%s"%DisChosenId,"LeadSection")
rds.delete("CleaningSection:%s"%DisChosenId)
rds.delete("CleaningSection:%s"%LeadArea)
if DisChosenStep == "5":#未用RichMenu
if rds.exists("QuittingCleaning:%s"%DisChosenId):#有可能正在等是否要替代打掃股長,無效他!
DeleteAskingQuitting(DisChosenId)
if rds.hget("user:%s"%DisChosenId,"UsingRichMenu").decode("utf-8") == "MiddleCleaning" or rds.hget("user:%s"%DisChosenId,"UsingRichMenu").decode("utf-8") == "DownCleaning":#只有這兩種需要主動切換
line_bot_api.link_rich_menu_to_user(DisChosenId,config.get("RM_MiddleNormal","id"))#變回原本RichMenu
rds.hdel("user:%s"%DisChosenId,"UsingRichMenu")#把使用紀錄刪除才可
line_bot_api.push_message(DisChosenId, TextSendMessage("%s把您的打掃股長權限收回了,您變回普通人了,十分抱歉!"%taker))
else:#正在用RichMenu
UsingClickedRichMenu = rds.hget("user:%s"%DisChosenId,"UsingRichMenu").decode("utf-8")
if UsingClickedRichMenu != "RightDeleteAccountClicked":#使用這個會回到Right,對RichMenu無影響
line_bot_api.link_rich_menu_to_user(DisChosenId,config.get("RM_MiddleNormal","id"))#強制變回原本RichMenu
rds.hdel("user:%s"%DisChosenId,"UsingRichMenu")#把使用紀錄刪除才可
if bytes(UsingClickedRichMenu,"utf-8") in rds.hkeys("APersonCanUsingRichMenu"):#正在用的是只能一個人用的RcihMenu,要讓別人可以用
rds.hdel("APersonCanUsingRichMenu",UsingClickedRichMenu)#讓其他人可用
if DisChosenStep != "6":#在此步強制回歸完成步會出問題
rds.hset("user:%s"%DisChosenId,"step","5")#強制回歸完成步
rds.delete("CleaningChangedNums")#要刪除所有可能的暫存變數
rds.delete("QuittingCleaning:%s"%DisChosenId)#要刪除所有可能的暫存變數
line_bot_api.push_message(DisChosenId, TextSendMessage("%s把您的打掃股長權限收回了,十分抱歉!\n\n如果您正在使用刪除帳號功能,會等到您用完再收回,其他功能已被強制停止"%taker))
if rds.exists("CleaningTemporaryReplace:%s"%DisChosenId):#有可能正在暫時委託他人做打掃股長(可能有or沒有在用RichMenu)
DeleteTemporaryReplacement(DisChosenId)
rds.delete("OriginalCleaningNum")#刪除暫存變數
actList = [PostbackTemplateAction(label='重新選擇(長存)',data='DelCleaning&start')]
line_bot_api.push_message(user_id,TextSendMessage("謝謝配合!!最後,請確認你選的是否正確:\n\n\t打掃股長:%s\n\n如果有錯,請點下面的重新選擇鈕,沒錯就真的全部完成了,謝謝你的配合!!"%CheckNum))
line_bot_api.reply_message(event.reply_token,TemplateSendMessage(alt_text='選完了!!',template=ButtonsTemplate(title="C.選完了!!",text='需要重新選擇來這~',actions = actList)))#text有字數限制,在這裡做JSON檔太麻煩了,只好push Message
rds.hset("user:%s"%user_id,"step","5")#到完成步
if rds.hexists("user:%s"%user_id,"UsingRichMenu") == True and rds.hget("user:%s"%user_id,"UsingRichMenu").decode("utf-8") == "DownManageCleaningReportSettingClicked":#使用RichMenu重新許股長,要讓RichMenu回復
RichMenuFunctionEnd(user_id, "DownManage")
rds.hdel("APersonCanUsingRichMenu","DownManageCleaningReportSettingClicked")#讓其他人可用
else:#第一次選(在註冊完後),沒有RichMenu,老師謝在可以有了
line_bot_api.link_rich_menu_to_user(user_id,config.get("RM_MiddleManage","id"))#老師可以用RichMenu了
else:#NO
rds.hset("user:%s"%user_id,"step","A")#回到第A步
line_bot_api.reply_message(event.reply_token,TextSendMessage("好,那請繼續選吧~(第A步)"))
else:
line_bot_api.reply_message(event.reply_token,TextSendMessage("%s"%ReplyWrongStep(NowStep)))
elif ReplyData[0:11] == "DelCleaning":#老師刪除打掃股長
if (not rds.exists("Teacher_Id") or bytes(user_id,"utf-8") != rds.get("Teacher_Id")) and (bytes(user_id,"utf-8") not in rds.lrange("Manager_Id", 0, -1)): #只有老師能操作(可能同學不小心註冊成老師,就可能用的到)
line_bot_api.reply_message(event.reply_token,TextSendMessage("很抱歉,你現在沒有權限使用這些功能了喔!!"))
else:
NowStep = rds.hget("user:%s"%user_id,"step").decode("utf-8")
if ReplyData[12:] == "start":#確認真的要重選
if NowStep == "5" :#確認在完成步
actList = [PostbackTemplateAction(label='沒錯。',data='DelCleaning&sure&YES') , PostbackTemplateAction(label='按錯而已啦',data='DelCleaning&sure&NO')]
line_bot_api.reply_message(event.reply_token,TemplateSendMessage(alt_text='認真要重選?',template=ConfirmTemplate(text='D.認真要重選打掃股長?',actions = actList)))
rds.hset("user:%s"%user_id,"step","D")#到第D步
else:
line_bot_api.reply_message(event.reply_token,TextSendMessage("%s"%ReplyWrongStep(NowStep)))
elif ReplyData[12:16] == "sure":#刪除+重新選擇打掃股長
if NowStep == "D":#確認在第D步
if ReplyData[17:20] == "YES":
for i in rds.lrange("Cleaning_Num",0,-1):
rdsRpush("OriginalCleaningNum", i.decode("utf-8"))#紀錄原有股長,有改動就要通知+改RichMenu
rds.delete("Cleaning_Num")
line_bot_api.reply_message(event.reply_token,TextSendMessage("打掃股長全部刪除好了!重新選吧!!"))
rds.hset("user:%s"%user_id,"step","A")
FlexMessage = json.load(open('打掃股長選擇.json','r',encoding='utf-8'))
line_bot_api.push_message(user_id, FlexSendMessage('選擇打掃股長!!',FlexMessage))
else:#NO
rds.hset("user:%s"%user_id,"step","5")#到完成步
line_bot_api.reply_message(event.reply_token,TextSendMessage("沒關係,這樣我也省事"))
if rds.hexists("user:%s"%user_id,"UsingRichMenu") == True and rds.hget("user:%s"%user_id,"UsingRichMenu").decode("utf-8") == "DownManageCleaningReportSettingClicked":#使用RichMenu重新許股長,要讓RichMenu回復#此時必有RichMenunp,
RichMenuFunctionEnd(user_id, "DownManage")
rds.hdel("APersonCanUsingRichMenu","DownManageCleaningReportSettingClicked")#讓其他人可用
else:
line_bot_api.reply_message(event.reply_token,TextSendMessage("%s"%ReplyWrongStep(NowStep)))
#-----------------------------------------#
#----------------股長選成員---------------#
elif ReplyData[0:7] == "GetCrew":#股長選成員
NowStep = rds.hget("user:%s"%user_id,"step").decode("utf-8")
if ReplyData[8:11] == "num":#第a步,選號碼
if NowStep == "a":
num = ReplyData[12:]
if num == "Fin":#選完了
if not rds.exists("CleaningSection:%s"%user_id) or (rds.exists("CleaningSection:%s"%user_id) and rds.llen("CleaningSection:%s"%user_id) == 0):#沒選人
line_bot_api.reply_message(event.reply_token,TextSendMessage("怎麼可能沒有人!去選人啦!"))
else:
SortRedisList("CleaningSection:%s"%user_id)
Chosen = ""
for i in rds.lrange("CleaningSection:%s"%user_id, 0, -1):
Chosen = Chosen + i.decode("utf-8") + ","
Chosen = Chosen.rstrip(",")
actList = [PostbackTemplateAction(label='Wright!',data='GetCrew&DoneNum&YES') , PostbackTemplateAction(label='Wrong',data='GetCrew&DoneNum&NO')]
line_bot_api.reply_message(event.reply_token,TemplateSendMessage(alt_text='確定選完人了嗎?',template=ConfirmTemplate(text='b.確定你的人是:%s?'%Chosen,actions = actList)))
rds.hset("user:%s"%user_id,"step","b")#到第b步
else:#選擇號碼
if rds.hexists("Number_Id",num) and rds.hget("Number_Id",num).decode("utf-8") == user_id:#選到自己
line_bot_api.reply_message(event.reply_token,TextSendMessage("不用選自己喔!再去選其他人吧!"))
else:
if rds.exists("CleaningSection:%s"%user_id) and (bytes(num,"utf-8") in rds.lrange("CleaningSection:%s"%user_id, 0, -1)):#是選過的,取消選取
rds.lrem("CleaningSection:%s"%user_id,0,num)
else:#增加
rdsRpush("CleaningSection:%s"%user_id,num)
Chosen = ""
for i in rds.lrange("CleaningSection:%s"%user_id, 0, -1):
Chosen = Chosen + i.decode("utf-8") + ","
Chosen = Chosen.rstrip(",")
line_bot_api.reply_message(event.reply_token,TextSendMessage("目前你選了 : " + Chosen))
else:
line_bot_api.reply_message(event.reply_token,TextSendMessage("%s"%ReplyWrongStep(NowStep)))
elif ReplyData[8:15] == "DoneNum":#第b步,確認選擇正確
if NowStep == "b":
if ReplyData[16:] == "YES":
actList = [PostbackTemplateAction(label='外掃',data='GetCrew&Area&外掃') , PostbackTemplateAction(label='內掃',data='GetCrew&Area&內掃'),PostbackTemplateAction(label='倒垃圾',data='GetCrew&Area&倒垃圾') ]
line_bot_api.reply_message(event.reply_token,TemplateSendMessage(alt_text='選區域!!',template=ButtonsTemplate(text='c.那你管的是哪個區域?',actions = actList)))
rds.hset("user:%s"%user_id,"step","c")#到第c步
else:#NO
rds.hset("user:%s"%user_id,"step","a")#回到第a步
line_bot_api.reply_message(event.reply_token,TextSendMessage("好,那請繼續選人吧~(第a步)"))
else:
line_bot_api.reply_message(event.reply_token,TextSendMessage("%s"%ReplyWrongStep(NowStep)))
elif ReplyData[8:12] == "Area":#第c步,選擇區域
if NowStep == "c":
area = ReplyData[13:]#很神奇的,中英文可以一起切割字串
if rds.exists("CleaningSection:%s"%area):#是被選過的區域,退貨(只要兩個人同時在c步就可以閃過審核,出bug,但機率太低,不要因此複雜化程式碼)
getter = ""
for i in rds.lrange("Cleaning_Id",0,-1):
CleaningId = i.decode("utf-8")
if rds.hget("user:%s"%CleaningId,"LeadSection").decode("utf-8") == area:
getter = rds.hget("user:%s"%CleaningId,"name").decode("utf-8")
line_bot_api.reply_message(event.reply_token,TextSendMessage("%s已管理此區域了,換個區域,在選一次吧!"%getter))
else:
actList = [PostbackTemplateAction(label='是的',data='GetCrew&DoneArea&YES&%s'%area) , PostbackTemplateAction(label='不是的',data='GetCrew&DoneArea&NO')]
line_bot_api.reply_message(event.reply_token,TemplateSendMessage(alt_text='確定選完區域了嗎?',template=ConfirmTemplate(text='d.確定你是管%s的?'%area,actions = actList)))
rds.hset("user:%s"%user_id,"step","d")#到第d步
else:
line_bot_api.reply_message(event.reply_token,TextSendMessage("%s"%ReplyWrongStep(NowStep)))
elif ReplyData[8:16] == "DoneArea":#第d步,確認選區域擇正確 + 製作JSON + 重新選擇鈕
if NowStep == "d":
if ReplyData[17:20] == "YES":
if rds.exists("CleaningReporting"):#可能在打掃時間註冊完,會出錯
line_bot_api.reply_message(event.reply_token,TextSendMessage("抱歉,在打掃股長們回報時註冊完成,會出錯,所以請等打掃時節結束再來,很抱歉!"))
else:
LeadArea = ReplyData[21:]
rdsRpush("Cleaning_Id",user_id)#傳訊用
rds.hset("user:%s"%user_id,"LeadSection",LeadArea)#傳特定JSON用
CheckNum = ""
for i in rds.lrange("CleaningSection:%s"%user_id,0,-1):
num = i.decode("utf-8")
rdsRpush("CleaningSection:%s"%LeadArea,num)#製作JSON會用上
CheckNum = CheckNum + num + ","
CheckNum = CheckNum.rstrip(",")
changer = rds.hget("user:%s"%user_id,"name").decode("utf-8")
for i in rds.lrange("Manager_Id",0,-1):#跟管理員說一下,不然會被濫用
ManagerId = i.decode("utf-8")
ManagerAccessToken = rds.hget("user:%s"%ManagerId,"access_token").decode("utf-8")
send_message(ManagerAccessToken, "打掃股長 %s 將\n\n自己的掃區設為:%s\n自己館的人設為:\n%s\n\n跟您報備一下,避免這個功能被濫用"%(changer,LeadArea,CheckNum))
actList = [PostbackTemplateAction(label='重新選擇(長存)',data='DelCrew&start')]
line_bot_api.push_message(user_id,TextSendMessage("謝謝你的配合!!最後,請確認你選的是否正確:\n\n\t你管的人:%s\n\t你管的區域:%s\n\n如果有錯,請點下面的重新選擇鈕。沒錯了話你從現在起,就是打掃股長!之後合作愉快啦!!"%(CheckNum,LeadArea)))
line_bot_api.reply_message(event.reply_token,TemplateSendMessage(alt_text='選完了!!',template=ButtonsTemplate(title="e.選完了!!",text='需要重新選擇來這~',actions = actList)))#text有字數限制,在這裡做JSON檔太麻煩了,只好push Message
rds.hset("user:%s"%user_id,"step","5")#到完成步
if rds.hexists("user:%s"%user_id,"UsingRichMenu") == True and rds.hget("user:%s"%user_id,"UsingRichMenu").decode("utf-8") == "DownCleaningCleaningRechooseFellowsClicked":#使用RichMenu重新選成員,要讓RichMenu回復
RichMenuFunctionEnd(user_id, "DownCleaning")
else:
line_bot_api.link_rich_menu_to_user(user_id,config.get("RM_MiddleCleaning","id"))#打掃股長選完成員就可以有RichMenu了
else:#NO
rds.hset("user:%s"%user_id,"step","c")#回到第c步
line_bot_api.reply_message(event.reply_token,TextSendMessage("那再選一次你的區域吧(第c步)!"))
else:
line_bot_api.reply_message(event.reply_token,TextSendMessage("%s"%ReplyWrongStep(NowStep)))
elif ReplyData[0:7] == "DelCrew":#股長刪除成員
if (rds.exists("Cleaning_Id") and bytes(user_id,"utf-8") not in rds.lrange("Cleaning_Id",0,-1)) and (bytes(user_id,"utf-8") not in rds.lrange("Manager_Id", 0, -1)): #只有打掃股長能操作(可能老師不小心選錯,就可能用的到)
line_bot_api.reply_message(event.reply_token,TextSendMessage("很抱歉,你現在沒有權限使用這些功能了喔!!可能是因為老師拔除了你的權限,問問老師吧!"))
else:
NowStep = rds.hget("user:%s"%user_id,"step").decode("utf-8")
if ReplyData[8:] == "start":#確認真的要重選
if NowStep == "5":#確認在完成步
actList = [PostbackTemplateAction(label='沒錯。',data='DelCrew&sure&YES') , PostbackTemplateAction(label='按錯而已啦',data='DelCrew&sure&NO')]
line_bot_api.reply_message(event.reply_token,TemplateSendMessage(alt_text='認真要重選?',template=ConfirmTemplate(text='f.認真要重選你管的人和區域?\n (作者:把人與區域分開好麻煩~)',actions = actList)))
rds.hset("user:%s"%user_id,"step","f")#到第D步
else:
line_bot_api.reply_message(event.reply_token,TextSendMessage("%s"%ReplyWrongStep(NowStep)))
elif ReplyData[8:12] == "sure":#刪除+重新選擇成員
if NowStep == "f":#確認在第f步
if ReplyData[13:] == "YES":
LeadArea = rds.hget("user:%s"%user_id,"LeadSection").decode("utf-8")
rds.lrem("Cleaning_Id",0,user_id)
rds.hdel("user:%s"%user_id,"LeadSection")
rds.delete("CleaningSection:%s"%user_id)
rds.delete("CleaningSection:%s"%LeadArea)
line_bot_api.reply_message(event.reply_token,TextSendMessage("你管的人和區域全部刪除好了!重新選吧!!"))
FlexMessage = json.load(open('打掃成員選擇.json','r',encoding='utf-8'))
line_bot_api.push_message(user_id, FlexSendMessage('選擇你掃區的人!!',FlexMessage))
rds.hset("user:%s"%user_id,"step","a")
else:#NO
rds.hset("user:%s"%user_id,"step","5")#到完成步
line_bot_api.reply_message(event.reply_token,TextSendMessage("沒關係,這樣我也省事"))