newbot.py 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. import copy
  2. import fastapi
  3. import fastapi.staticfiles as fastapiStaticfiles
  4. import linebot
  5. import linebot.models as linebotModels
  6. import suggests
  7. import os
  8. from GoogleNews import GoogleNews
  9. import dataset
  10. import datetime
  11. from fastapi.responses import HTMLResponse
  12. #
  13. from linebot.models import (
  14. MessageEvent, TextMessage, TextSendMessage,
  15. SourceUser, SourceGroup, SourceRoom,
  16. TemplateSendMessage, ConfirmTemplate, MessageAction,
  17. ButtonsTemplate, ImageCarouselTemplate, ImageCarouselColumn, URIAction,
  18. PostbackAction, DatetimePickerAction,
  19. CameraAction, CameraRollAction, LocationAction,
  20. CarouselTemplate, CarouselColumn, PostbackEvent,
  21. StickerMessage, StickerSendMessage, LocationMessage, LocationSendMessage,
  22. ImageMessage, VideoMessage, AudioMessage, FileMessage,
  23. UnfollowEvent, FollowEvent, JoinEvent, LeaveEvent, BeaconEvent,
  24. MemberJoinedEvent, MemberLeftEvent,
  25. FlexSendMessage, BubbleContainer, ImageComponent, BoxComponent,
  26. TextComponent, IconComponent, ButtonComponent,
  27. SeparatorComponent, QuickReply, QuickReplyButton,
  28. ImageSendMessage)
  29. #uvicorn newbot:app --host 0.0.0.0 --port 5443 --ssl-keyfile=/etc/letsencrypt/live/api.ptt.cx/privkey.pem --ssl-certfile=/etc/letsencrypt/live/api.ptt.cx/fullchain.pem
  30. #uvicorn main:app --host 0.0.0.0 --port 443 --ssl-keyfile=/etc/letsencrypt/live/ptt.cx/privkey.pem --ssl-certfile=/etc/letsencrypt/live/ptt.cx/chain.pem
  31. #uvicorn main:app --host 0.0.0.0 --port 443 --key-file=/etc/letsencrypt/live/ptt.cx/privkey.pem --certfile=/etc/letsencrypt/live/ptt.cx/cert.pem
  32. # --keyfile=./key.pem --certfile=./cert.pem
  33. # --ssl-cert-reqs 1
  34. #
  35. # --ssl-ca-certs=/etc/letsencrypt/live/ptt.cx/fullchain.crt
  36. app = fastapi.FastAPI()
  37. #app.mount(
  38. # '/static', fastapiStaticfiles.StaticFiles(directory='static'), name='static')
  39. from linebot import (
  40. LineBotApi, WebhookHandler
  41. )
  42. from linebot.exceptions import (
  43. InvalidSignatureError
  44. )
  45. from linebot.models import (
  46. MessageEvent, TextMessage,ImageSendMessage, TextSendMessage,FlexSendMessage, TemplateSendMessage,CarouselTemplate,ConfirmTemplate,PostbackAction,MessageAction,CarouselColumn,URIAction
  47. )
  48. import json
  49. import codecs
  50. seo=False
  51. s_news=False
  52. line_bot_api = LineBotApi('ExfYlsiGTvqJsMNdixocQ6PLYD+szmUj+GAxH99TXFPCn0RCX/iw06acFnL37pyHW1AYMZf34SOJEIRpdWb9heb9btIF2DaMqcBkYvJ3O2jYaKYv9RDUKbS57lUqcvvChK7ESQeuO2yjvYwes3Oq4wdB04t89/1O/w1cDnyilFU=')
  53. handler = WebhookHandler('5b05fed81cd9f6f1e75dbf7dda388479')
  54. #line_bot_api = LineBotApi('YOUR_CHANNEL_ACCESS_TOKEN')
  55. #handler = WebhookHandler('YOUR_CHANNEL_SECRET')
  56. def get_aws():
  57. result=''
  58. db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/hhh?charset=utf8mb4')
  59. cursor=db.query('SELECT from_unixtime(eventtime) as dt,area FROM hhh.aws_monitor order by eventtime desc limit 4;')
  60. for c in cursor:
  61. result+=str(c['dt'])+"\n"+c['area']+"\n"
  62. return result
  63. def get_idea():
  64. result=''
  65. db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/hhh?charset=utf8mb4')
  66. cursor=db.query('SELECT query FROM hhh.gsc_weekly where clicks > 500 order by rand() limit 10;')
  67. for c in cursor:
  68. result+=str(c['query'])+"\n"
  69. return result
  70. @app.get("/aws")
  71. async def aws():
  72. result='<html><head><link href="https://getbootstrap.com/docs/4.1/dist/css/bootstrap.min.css" rel="stylesheet"></head><body>'
  73. result+='製表時間: '+str(datetime.datetime.now())+'</br></br>\n\n'
  74. result+='<table class="table table-striped">'
  75. db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/hhh?charset=utf8mb4')
  76. cursor=db.query('SELECT from_unixtime(eventtime) as dt,area FROM hhh.aws_monitor order by eventtime desc limit 30;')
  77. for c in cursor:
  78. result+="<tr><td>"+str(c['dt'])+"</td><td>"+c['area']+"</td></tr>\n"
  79. result+='</table></body></html>'
  80. return HTMLResponse(content=result, status_code=200)
  81. @app.get("/msg/{item_id}")
  82. async def coffee_msg(item_id):
  83. True
  84. line_bot_api.push_message(item_id, TextSendMessage(text='開啟下方完整券樣(密碼9888)至櫃台掃碼兌換。https://txp.rs/v/EvX69b4Xq9'))
  85. return {"code":"ok" }
  86. @app.post('/callback')
  87. async def callback(request: fastapi.Request):
  88. signature = request.headers['X-Line-Signature']
  89. body = await request.body()
  90. handler.handle(body.decode('utf-8'), signature)
  91. return 'OK'
  92. def get_news_by_kw(keyword):
  93. googlenews = GoogleNews(lang='zh-TW')
  94. kw=keyword
  95. googlenews.set_lang('zh-TW')
  96. googlenews.search(kw)
  97. resultstr="新聞:"
  98. idx=0
  99. rs=googlenews.results()
  100. for r in rs:
  101. if idx>0:
  102. resultstr+=','
  103. else:
  104. idx+=1
  105. resultstr+=r['title']
  106. return resultstr
  107. # print(r['desc'])
  108. # print(r['link'])
  109. # print(r['datetime'])
  110. def flex_test():
  111. fname=os.path.abspath(__file__)
  112. elmts=fname.split(os.path.sep)
  113. path2=os.path.sep.join(elmts[0:-1])
  114. keysdir=path2+os.path.sep
  115. js=json.load(open(keysdir+'test.json','r',encoding='utf-8'))
  116. return js
  117. @handler.add(FollowEvent)
  118. def handle_follow(event):
  119. print(event.source.user_id)
  120. # do something
  121. @handler.add(linebotModels.MessageEvent, message=linebotModels.TextMessage)
  122. def message_text(event):
  123. global seo
  124. global s_news
  125. ## if event.message.text == 'push':
  126. # line_bot_api.push_message(
  127. # event.source.user_id, [
  128. # # TextSendMessage(text='PUSH!'),
  129. # ]
  130. # )
  131. if event.message.text.lower() == 'flex':
  132. FlexMessage = flex_test()
  133. line_bot_api.reply_message(event.reply_token, FlexSendMessage('ChoozMo',FlexMessage))
  134. return
  135. if event.message.text.lower() == 's_news':
  136. s_news=True
  137. line_bot_api.reply_message(
  138. event.reply_token,
  139. TextSendMessage(text='請輸入要搜尋新聞的關鍵字:'))
  140. return
  141. if event.message.text == 'q_aws':
  142. line_bot_api.reply_message(
  143. event.reply_token,[TextSendMessage(text=get_aws()),TextSendMessage(text='完整報告: https://api.ptt.cx:5443/aws')])
  144. return
  145. if event.message.text == 'q_idea':
  146. s_news=True
  147. line_bot_api.reply_message(
  148. event.reply_token,
  149. TextSendMessage(text=get_idea()))
  150. return
  151. if event.message.text.lower() == 'seo':
  152. seo=True
  153. line_bot_api.reply_message(
  154. event.reply_token,
  155. TextSendMessage(text='請輸入要找的關鍵字:'))
  156. return
  157. if event.message.text == '叫':
  158. line_bot_api.reply_message(
  159. event.reply_token, linebotModels.AudioSendMessage(
  160. original_content_url=f'{baseUrl}/static/audio/noot_noot.mp3', duration=1000))
  161. if event.message.text.lower()=='ok':
  162. line_bot_api.reply_message(
  163. event.reply_token,
  164. TextSendMessage(text='最欣賞ChoozMo團隊說OK的人!!'))
  165. if event.message.text=='c' or event.message.text=='C' :
  166. line_bot_api.reply_message(
  167. event.reply_token,
  168. TextSendMessage(
  169. text='快速鍵',
  170. quick_reply=QuickReply(
  171. items=[
  172. QuickReplyButton(
  173. action=MessageAction(label="幸福空間靈感", text="q_idea")
  174. ),
  175. QuickReplyButton(
  176. action=MessageAction(label="查AWS", text="q_aws")
  177. ),
  178. QuickReplyButton(
  179. action=MessageAction(label="關聯字", text="seo")
  180. ),
  181. ])))
  182. else:
  183. if s_news:
  184. result=get_news_by_kw(event.message.text)
  185. line_bot_api.reply_message(
  186. event.reply_token,
  187. TextSendMessage(text=result))
  188. s_news=False
  189. return
  190. if seo:
  191. res='相關字:'
  192. s = suggests.suggests.get_suggests(event.message.text, source='google')
  193. idx=0
  194. for sg in s['suggests']:
  195. if idx>0:
  196. res+=','
  197. else:
  198. idx+=1
  199. res+=sg
  200. line_bot_api.reply_message(
  201. event.reply_token,
  202. TextSendMessage(text=res))
  203. seo=False
  204. # print('test')
  205. #if __name__ == "__main__":
  206. # app.run(host='0.0.0.0', port=443,ssl_context=('/etc/letsencrypt/live/ptt.cx/fullchain.pem', '/etc/letsencrypt/live/ptt.cx/privkey.pem'))
  207. # app.run(host='0.0.0.0', port=14404,ssl_context=('/tmp/cert.pem','/tmp/chain.pem' ))