# 聊天機器人Chatbot
下載git跟heroku 並安裝
https://devcenter.heroku.com/articles/heroku-cli#download-and-install
https://git-scm.com/downloads
登入Line Developers
設置聊天機器人
使用VS Code編輯
```python=
from flask import Flask, request, abort
from linebot import(LineBotApi, WebhookHandler)
from linebot.exceptions import(InvalidSignatureError)
from linebot.models import *
app = Flask(__name__)
#Channel Access Token
line_bot_api = LineBotApi('5Lya6ueGDxDPVuM9WzSZte5NzxYGXT1W35Fws7DoFMD4/o6kofCp8+o4yuGMWIuBA2njV6hY16w/y7dpDz8j3mn3C4LFsdeWaoLmwjeykDdI5YHVnp/y/whEgYZVaxg2UKsTE3CpJJMe9px2CIlnLAdB04t89/1O/w1cDnyilFU=')
#Channel Secret
handler = WebhookHandler('f04479c2a3743e08c4b96412d0cbcaa0')
#監聽所有來自 /callback 的 Post Request
@app.route("/callback",methods=['POST'])
def callback():
#get X-Line_Signature header value
signature = request.headers['X-Line-Signature']
#get requeset body as text
body = request.get_data(as_text=True)
app.logger.info("Request body: "+body)
#handle webhook body
try:
handler.handle(body,signature)
except InvalidSignatureError:
abort(400)
return 'OK'
#處理訊息
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
message = TextSendMessage(text=event.message.text)
line_bot_api.reply_message(event.reply_token,message)
# message = StickerSendMessage(package_id='11537',sticker_id='52002735')
# # line_bot_api.reply_message(event.reply_token,message)
import os
if __name__=="__main__":
port = int(os.environ.get('PORT',5000))
app.run(host='0.0.0.0',port=port)
```
這是應聲鳥機器人
新增Line的webhook

螢光線的地方是在heroku的專案名稱

要新增這些key跟value
開啟Terminal

把資料夾選到你的專案資料夾
然後登入heroku
git config --global user.name "你的名字"
git config --global user.email 你的信箱
git init 第一次才要輸入 之後不用
heroku git:remote -a {HEROKU_APP_NAME} 沒有大括號
git add .
git commit -m "Add code"
git push -f heroku master
上面的依序輸入
TemplateSendMessage
->ButtonsTemplate 按鈕介面
->ConfirmTemplate 確認介面
->CarouseTemplate (多個ButtonsTemplate)
訊息物件中 Image Template message提供互動式介面,會產稱一個Action,Action可以分為以下4種
1. Postback ->按下後透過action=buy&item=111傳送到後台,後台就知道user點了甚麼
2. Message ->幫使用者送出一個訊息
3. URL ->網站
4. Datetime ->告知後台user選擇的使用細節
```python=
import requests
import re
import random
import configparser
from bs4 import BeautifulSoup
from flask import Flask, request, abort
from imgurpython import ImgurClient
from flask import Flask, request, abort
from linebot import (
LineBotApi, WebhookHandler
)
from linebot.exceptions import (
InvalidSignatureError
)
from linebot.models import *
app = Flask(__name__)
#Channel Access Token
line_bot_api = LineBotApi('5Lya6ueGDxDPVuM9WzSZte5NzxYGXT1W35Fws7DoFMD4/o6kofCp8+o4yuGMWIuBA2njV6hY16w/y7dpDz8j3mn3C4LFsdeWaoLmwjeykDdI5YHVnp/y/whEgYZVaxg2UKsTE3CpJJMe9px2CIlnLAdB04t89/1O/w1cDnyilFU=')
#Channel Secret
handler = WebhookHandler('f04479c2a3743e08c4b96412d0cbcaa0')
#監聽所有來自 /callback 的 Post Request
@app.route("/callback",methods=['POST'])
def callback():
#get X-Line_Signature header value
signature = request.headers['X-Line-Signature']
#get requeset body as text
body = request.get_data(as_text=True)
app.logger.info("Request body: "+body)
#handle webhook body
try:
handler.handle(body,signature)
except InvalidSignatureError:
abort(400)
return 'OK'
def apple_news():
target_url = 'https://tw.appledaily.com/new/realtime'
print('Start parsing appleNews....')
rs = requests.session()
res = rs.get(target_url, verify=False)
soup = BeautifulSoup(res.text, 'html.parser')
content = ""
for index, data in enumerate(soup.select('.rtddt a'), 0):
if index == 5:
return content
link = data['href']
content += '{}\n\n'.format(link)
return content
def technews():
target_url = 'https://technews.tw/'
print('Start parsing movie ...')
rs = requests.session()
res = rs.get(target_url, verify=False)
res.encoding = 'utf-8'
soup = BeautifulSoup(res.text, 'html.parser')
content = ""
for index, data in enumerate(soup.select('article div h1.entry-title a')):
if index == 12:
return content
title = data.text
link = data['href']
content += '{}\n{}\n\n'.format(title, link)
return content
def oil_price():
target_url = 'https://gas.goodlife.tw/'
rs = requests.session()
res = rs.get(target_url, verify=False)
res.encoding = 'utf-8'
soup = BeautifulSoup(res.text, 'html.parser')
title = soup.select('#main')[0].text.replace('\n', '').split('(')[0]
gas_price = soup.select('#gas-price')[0].text.replace('\n\n\n', '').replace(' ', '')
cpc = soup.select('#cpc')[0].text.replace(' ', '')
content = '{}\n{}{}'.format(title, gas_price, cpc)
return content
def panx():
target_url = 'https://panx.asia/'
print('Start parsing ptt hot....')
rs = requests.session()
res = rs.get(target_url, verify=False)
soup = BeautifulSoup(res.text, 'html.parser')
content = ""
for data in soup.select('div.container div.row div.desc_wrap h2 a'):
title = data.text
link = data['href']
content += '{}\n{}\n\n'.format(title, link)
return content
def ptt_hot():
target_url = 'http://disp.cc/b/PttHot'
print('Start parsing pttHot....')
rs = requests.session()
res = rs.get(target_url, verify=False)
soup = BeautifulSoup(res.text, 'html.parser')
content = ""
for data in soup.select('#list div.row2 div span.listTitle'):
title = data.text
link = "http://disp.cc/b/" + data.find('a')['href']
if data.find('a')['href'] == "796-59l9":
break
content += '{}\n{}\n\n'.format(title, link)
return content
#處理訊息
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
if event.message.text == "油價查詢":
content = oil_price()
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text=content))
return 0
if event.message.text == "PTT":
content = ptt_hot()
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text=content))
return 0
if event.message.text == "科技新報":
content = technews()
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text=content))
return 0
if event.message.text == "PanX泛科技":
content = panx()
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text=content))
return 0
if event.message.text == "開始玩":
buttons_template = TemplateSendMessage(
alt_text='開始玩 template',
template=ButtonsTemplate(
title='選擇服務',
text='請選擇',
thumbnail_image_url='https://i.imgur.com/fUWTqXp.jpg',
actions=[
MessageTemplateAction(
label='新聞',
text='新聞'
),
MessageTemplateAction(
label='電影',
text='電影'
),
MessageTemplateAction(
label='看廢文',
text='看廢文'
)
]
)
)
line_bot_api.reply_message(event.reply_token, buttons_template)
return 0
if event.message.text == "新聞":
buttons_template = TemplateSendMessage(
alt_text='新聞 template',
template=ButtonsTemplate(
title='新聞類型',
text='請選擇',
thumbnail_image_url='https://i.imgur.com/vkqbLnz.png',
actions=[
MessageTemplateAction(
label='PTT',
text='PTT'
),
MessageTemplateAction(
label='科技新報',
text='科技新報'
),
MessageTemplateAction(
label='PanX泛科技',
text='PanX泛科技'
)
]
)
)
line_bot_api.reply_message(event.reply_token, buttons_template)
return 0
message = TemplateSendMessage(
alt_text='目錄 template',
template=CarouselTemplate(
columns=[
CarouselColumn(
thumbnail_image_url='https://i.imgur.com/c37XTQO.png',
title='選擇服務',
text='請選擇',
actions=[
MessageAction(
label='開始玩',
text='開始玩'
),
URIAction(
label='OP.GG',
uri='https://tw.op.gg/champion/statistics'
),
URIAction(
label='粉絲團',
uri='https://zh-tw.facebook.com/lolopgg'
)
]
),
CarouselColumn(
thumbnail_image_url='https://i.imgur.com/6JYzgMA.jpg',
title='選擇服務',
text='請選擇',
actions=[
MessageAction(
label='other bot',
text='imgur bot'
),
MessageAction(
label='油價查詢',
text='油價查詢'
),
URIAction(
label='浮動油價FB',
uri='https://zh-tw.facebook.com/gas.goodlife.tw'
)
]
),
CarouselColumn(
thumbnail_image_url='https://i.imgur.com/p5z9Nu9.png',
title='選擇服務',
text='請選擇',
actions=[
URIAction(
label='分享 bot',
uri='https://imgur.com/yW9ocfP'
),
URIAction(
label='TWITCH 首頁',
uri='https://www.twitch.tv/'
),
URIAction(
label='TWITCH 頻道分類',
uri='https://www.twitch.tv/directory'
)
]
)
]
)
)
line_bot_api.reply_message(event.reply_token, message)
import os
if __name__=="__main__":
port = int(os.environ.get('PORT',5000))
app.run(host='0.0.0.0',port=port)
```
pip install twder
打開terminal
cd 到你的資料夾
打 python manage.py runserver
再打開一個terminal
cd 到你的資料夾
打 ngrok http 8000(這是端口可以改)