在chatbot中,我們需要用到模式切換,而且不是用NLP處理,我們就需要寫一個中介的程式去處理這個工作。以下程式會詢問模式並記錄下來,10分鐘後會重問。此程式不需資料庫,直接記在檔案裡。
--------------------------------------------------------------------------------------------------------------------------------
$timeLimit = 600; // 保持模式的最長時間
$arrModeName = array();
$arrModeName[0] = '哈囉,這裡是入口,您想要處理務還是詢問相關問題? ';
$arrModeName[2] = '處理務';//務模式
$arrModeName[3] = '詢問相關問題';//問題模式
function router($message)
{
global $timeLimit;
global $arrModeName;
if($message['message']['text'] == $arrModeName[2])
{
setUserMode($message['source']['userId'],2);
}
else if($message['message']['text'] == $arrModeName[3])
{
setUserMode($message['source']['userId'],3);
}
list($mode,$time) = getUserMode($message['source']['userId']);
if(time() - $time > $timeLimit)
{//超過時間就重設為詢問模式
$mode = 1;
setUserMode($message['source']['userId'],$mode);
}
if($mode == 1)
{//詢問模式
echo $arrModeName[0];
}else if($mode == 2){
//傳給務模組
receiveMsg($message);
}
else if($mode == 3)
{//傳給問題模組
receiveMsg2($message);
}else
{
echo ("\n ERROR MODE");
}
}
function setUserMode($user,$mode)
{
$filename = './user/'.$user;
$strWrite = $mode.':'.time();
$filenum=fopen($filename,'w');
if(fwrite($filenum,$strWrite) === FALSE)
echo "Cannot write to file ($filename)";
fclose($filenum);
}
function getUserMode($user)
{
$filename = './user/'.$user;
if(file_exists($filename) ){
$filenum=fopen($filename,'r');
$str = fread($filenum,1);
fread($filenum,1);
$time = fread($filenum,10);
fclose($filenum);
$mode = intval($str);
$time = intval($time);
$strWrite = $mode.':'.time();
$filenum=fopen($filename,'w');
if(fwrite($filenum,$strWrite) === FALSE)
echo "Cannot write to file ($filename)";
}
else
{
$time = time();
$mode = 1;
$filenum=fopen($filename,'w');
$strWrite = $mode.':'.$time;
if(fwrite($filenum,$strWrite) === FALSE)
echo "Cannot write to file ($filename)";
chmod($filename,0666);
}
fclose($filenum);
return array($mode,$time);
}
?>
2020年1月31日 星期五
LINE機器人範例
中國信託LINE
- 選單是圖片,指定座標範圍當按鈕
- 訊息是圖片,點進去是網頁,看細節
- 美工圖片和自然語言處理一樣重要!
---------------------------------------------------------------------------------------------------------------------
卡米狗 - 各大Line群已被攻佔! 《卡米狗》嗆爆所有人
單純的上下句配對,就能達到吸引人的效果。
------------------------------------------------------------------------------------------------------------------------------------------------------------
Line@酒店攬客機器人
定時傳設計好的訊息
設計話語(資料庫?演算法?)
照片也很重要!
chatbots如何改善印度的醫療狀況
chatbots能同時提供多個使用者服務,節省時間和成本。
chatbots己經成功幫助數百萬人說明他們的健康問題並提供適當的指導
- 根據病患自己輸入的症狀,幫助歸納出自己的具體疾病
- 幫助病患參與(了解、決定)自己的治療過程
- 發送各種重要的提醒通知給病患
--------------------------------------------------------------------------------------------------------------------------
可以幫助使用者:
預約看診
醫院資訊
醫生資訊
疾病問題
利用選單幫助使用者Query
--------------------------------------------------------------------------------------------------------------------------
理解使用者要預約掛號。
接著問使用者的城市,利用Quick Reply做到。
2020年1月30日 星期四
line-bot-sdk套件 - Python
Line提供Python的套件,給Python程式設計者可以使用套件API跟LINE互動,就不需要撰寫太多複雜的程式及JSON傳輸格式。套件是以Flask提供服務,啟動後,就是LINE的Webhook。
下載套件方法:
pip install line-bot-sdk
範例程式碼,可以Echo使用者輸入的字句:
from flask import Flask, request, abort from linebot import ( LineBotApi, WebhookHandler ) from linebot.exceptions import ( InvalidSignatureError ) from linebot.models import ( MessageEvent, TextMessage, TextSendMessage, ) app = Flask(__name__) userNo = 1 line_bot_api = LineBotApi('k2j34l2kj34l2kj34l2kh143;kljh51;kl2h5;l1k2hj;45lkh12;l3k4h2kj3hn4kj2lh34lkj2h34lk2jh34lkjh1242kl3jh4lk2jh34lk2jh34lk1jh243lkjh2lk3j4hlk23h4') handler = WebhookHandler('kj2h34lkj2h433lk2jh4lk3j2h4') @app.route("/") def hello(): return "Hello World!" @app.route("/callback", methods=['POST']) def callback(): # get X-Line-Signature header value signature = request.headers['X-Line-Signature'] # get request 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): if (event.reply_token == '00000000000000000000000000000000'): return None global userNo text_message = TextSendMessage(text='Hello, world', quick_reply=QuickReply(items=[ QuickReplyButton(action=MessageAction(label="label", text="text")) ])) line_bot_api.reply_message( event.reply_token, TextSendMessage(text=userNo)) userNo += 1 if __name__ == "__main__": app.run( host = '0.0.0.0', port = 12345, debug = True, ssl_context ='adhoc' )
下載套件方法:
pip install line-bot-sdk
範例程式碼,可以Echo使用者輸入的字句:
from flask import Flask, request, abort from linebot import ( LineBotApi, WebhookHandler ) from linebot.exceptions import ( InvalidSignatureError ) from linebot.models import ( MessageEvent, TextMessage, TextSendMessage, ) app = Flask(__name__) userNo = 1 line_bot_api = LineBotApi('k2j34l2kj34l2kj34l2kh143;kljh51;kl2h5;l1k2hj;45lkh12;l3k4h2kj3hn4kj2lh34lkj2h34lk2jh34lkjh1242kl3jh4lk2jh34lk2jh34lk1jh243lkjh2lk3j4hlk23h4') handler = WebhookHandler('kj2h34lkj2h433lk2jh4lk3j2h4') @app.route("/") def hello(): return "Hello World!" @app.route("/callback", methods=['POST']) def callback(): # get X-Line-Signature header value signature = request.headers['X-Line-Signature'] # get request 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): if (event.reply_token == '00000000000000000000000000000000'): return None global userNo text_message = TextSendMessage(text='Hello, world', quick_reply=QuickReply(items=[ QuickReplyButton(action=MessageAction(label="label", text="text")) ])) line_bot_api.reply_message( event.reply_token, TextSendMessage(text=userNo)) userNo += 1 if __name__ == "__main__": app.run( host = '0.0.0.0', port = 12345, debug = True, ssl_context ='adhoc' )
Flask+HTTPS
如果直接用Python+Flask,提供REST API的服務,只會開啟http://127.0.0.1:5000的Daemon給別人呼叫,但現在流行用HTTPS,很多Webhook功能都強迫你要能提供HTTPS的通訊協定給它呼叫,故我上網查怎麼讓Flask支援SSL。
只要在你的app.run()裡,加上 ssl_context ='adhoc' 就可以了,如下列Python程式片段:
if __name__ == "__main__":
app.run(
host = '0.0.0.0',
port = 55373,
debug = True,
ssl_context ='adhoc'
)
上述用到adhoc功能,需要pyOpenSSL套件。但你如果有申請SSL憑證,就不需要這個套件。
有些Client要求你一定要用合法的憑證,否則就不連,甚至連用Postman測試HTTPS的API,也要求這樣,否則不幫你測(或到setting裡把SSL certificate verification)。
若你有合法的憑證,把ssl_context 改成下列參數就能用:
ssl_context =('/PATH/TO/SSL.CRT','/PATH/TO/SSL.KEY')
只要在你的app.run()裡,加上 ssl_context ='adhoc' 就可以了,如下列Python程式片段:
if __name__ == "__main__":
app.run(
host = '0.0.0.0',
port = 55373,
debug = True,
ssl_context ='adhoc'
)
上述用到adhoc功能,需要pyOpenSSL套件。但你如果有申請SSL憑證,就不需要這個套件。
有些Client要求你一定要用合法的憑證,否則就不連,甚至連用Postman測試HTTPS的API,也要求這樣,否則不幫你測(或到setting裡把SSL certificate verification)。
若你有合法的憑證,把ssl_context 改成下列參數就能用:
ssl_context =('/PATH/TO/SSL.CRT','/PATH/TO/SSL.KEY')
聊天機器人(Chatbot)的程式架構
我們在設計聊天機器人(Chatbot)時,直覺會用傳統的 「網路程式語言+資料庫」,例如PHP+MySQL,而PHP會用到資料庫的原因,除了要存一些長期用到的資料,還有短期的資料。所謂短期是指幾分鐘或幾秒,甚至以毫秒計算,例如一天的網站累計進站人次,一般常把累計值存在資料庫裡。
短期資料的問題是會造成經常性的資料庫存取,使得資料庫來不及反應,進而需要調整資料庫的參數、換更好的電腦,甚至需要Load Balance。
如果我們回到原點想一個機器人應該有的程式架構,就會發現為什麼不是程式自己記得前幾秒的資料,而是需要額外的資料倉儲機制。而原因也很簡單,因為像PHP之類的Web程式,用一次就關掉了,Process就消失了,它根本不記得幾秒鐘之前的request已經服務了什麼事,所以又額外需要一個資料庫,幫忙記東西。
我們希望程式能記得前一回的事情,就不能用傳統的架構。程式啟動後,會成為Process,這時我們應該要保持住這個Process,不能讓它被關掉,如果是一般Web程式寫法一定不行。
解決的方法就是,程式要能自己運行(例. 在command line呼叫起來且不會結束),程式會不斷的迴圈,監聽有沒有連線進來(例. 開Socket),有就開始處理、回傳訊息,然後再繼續監聽。利用程式的Global variable記憶短期的資料,就不需要存取資料庫。
自己運行也不需要一直initial程式,節省Initial時間,加快服務速度。如果需要資料庫存資料,也可以一直保持連線,節省communication成本。
要注意的是,記在Global variable短期的資料不能太多,否則會memory overflow,記憶體會不夠用。如果需要記的短期資料太多,可以存到資料庫或檔案。也可以增加電腦作Load Balance。
短期資料的問題是會造成經常性的資料庫存取,使得資料庫來不及反應,進而需要調整資料庫的參數、換更好的電腦,甚至需要Load Balance。
如果我們回到原點想一個機器人應該有的程式架構,就會發現為什麼不是程式自己記得前幾秒的資料,而是需要額外的資料倉儲機制。而原因也很簡單,因為像PHP之類的Web程式,用一次就關掉了,Process就消失了,它根本不記得幾秒鐘之前的request已經服務了什麼事,所以又額外需要一個資料庫,幫忙記東西。
我們希望程式能記得前一回的事情,就不能用傳統的架構。程式啟動後,會成為Process,這時我們應該要保持住這個Process,不能讓它被關掉,如果是一般Web程式寫法一定不行。
解決的方法就是,程式要能自己運行(例. 在command line呼叫起來且不會結束),程式會不斷的迴圈,監聽有沒有連線進來(例. 開Socket),有就開始處理、回傳訊息,然後再繼續監聽。利用程式的Global variable記憶短期的資料,就不需要存取資料庫。
自己運行也不需要一直initial程式,節省Initial時間,加快服務速度。如果需要資料庫存資料,也可以一直保持連線,節省communication成本。
要注意的是,記在Global variable短期的資料不能太多,否則會memory overflow,記憶體會不夠用。如果需要記的短期資料太多,可以存到資料庫或檔案。也可以增加電腦作Load Balance。
Restful的LOG
Flask預設就有log功能,但是不會直接存到外面的檔案,若需要存到LOG檔,就需要import logging來支援。
Flask產生LOG訊息,只需呼叫app.logger,有三種LOG項目: Debug、Warning、Error。
若要指定LOG檔,需要產生FileHandler,"logging.FileHandler('flask.log') "。
如下範例:
from flask import Flask
import logging
app = Flask(__name__)
@app.route('/')
def root():
app.logger.debug('A value for debugging')
app.logger.warning('A warning occurred (%d apples)', 42)
app.logger.error('An error occurred')
if __name__ == '__main__':
app.logger.addHandler( logging.FileHandler('flask.log') )
app.run( debug=True )
訂閱:
文章 (Atom)
-
Line提供Python的套件,給Python程式設計者可以使用套件API跟LINE互動,就不需要撰寫太多複雜的程式及JSON傳輸格式。套件是以Flask提供服務,啟動後,就是LINE的Webhook。 下載套件方法: pip install line-bot-sdk...
-
這個Python程式可以線上將TWNIC的台灣IP清單,轉成iptables的指令,貼到/etc/iptables.rules上,就可以限制只能台灣的IP能存取。 限制port時,用如下寫法,port 80使用"TaiwanIP"規則(平常我們是寫ACC...
-
https://blog.xuite.net/yh96301/blog/367515625-Ubuntu+15.1%E5%AE%89%E8%A3%9DVMware+Workstation+Player+12.1 https://blog.csdn.net/yzf0011/ar...




