---
# System prepended metadata

title: 第三次段考電子商務—LINE機器人

---

# 第三次段考電子商務—LINE機器人
#### 

### 目前功能

* 問名字
* 問功能
* 打招呼
* 找表情包（笑/翔/滾/慌/罵人/試探/笨蛋/比心/無奈/迷惑/生氣/閉嘴/吃驚/加一/哈哈哈/不夠變態/我超棒的/不回訊息/我活得好憂傷/...）

___ 

### 機器人實測圖片
![](https://upload.cc/i1/2020/01/19/L3ygYF.jpg)

![](https://upload.cc/i1/2020/01/19/dsnVfo.jpg)

![](https://upload.cc/i1/2020/01/19/14bxB9.jpg)

![](https://upload.cc/i1/2020/01/19/yeEG3f.jpg)

___

### 介紹影片(?)
* LUNE機器人1

{%youtube KuHdWX_BT6Q %}
* LINE機器人2

{%youtube j0Y9kgWP9Bg %}
* LINE機器人3

{%youtube 8bn2uAoVB6A %}

* LINE機器人4 安裝與設定

{%youtube SAUl6J_4J5g %}

___ 

### 程式碼

==config.ini==
```ini=
; 這裡你要改成你自己的LINE機器人的資料
[Line的設定]
Channel_Secret = 846d64326e5e8afc016e22d303737e1d
Channel_Access_Token = BtyWnMdg3ozvsyR5A+yDN30pXVu6z/zkYA94xtCsvNxudWSHkSl9yhFI16MO7pXIaH9dqA2iI1nIm6XN6B/x5h79TY1eiQDtgh9QxcVXQKK9KY6+73WYAfoQdyyX9Rd2qSA3xdX8erqg6yKgkKtWNQdB04t89/1O/w1cDnyilFU=
User_Id = Ubb209c0ca6e78dc8d884d9fb1514be80
```

### 

==test-ini.py==
```python=
import configparser

ini = configparser.ConfigParser()
ini.optionxform = str           # 設定要分大小寫不同

ini.read('config.ini', encoding = 'utf-8')

# 讀取[Line的設定]小節中的「Channel_Access_Token」的資料
s = ini.get('Line的設定','Channel_Access_Token')
print('Channel_Access_Token = ' + s)

# 把修改後的 ini 資料寫回去 line.ini 的檔內
# with open('config.ini', 'w', encoding = 'utf-8') as iniFile:
#     ini.write(iniFile)
```

### 

==myconfig.py==
```python=
# 讀取Line的設定檔
import configparser

def readConfig(iniFile):
    ini = configparser.ConfigParser()
    #ini.optionxform = str           # 設定要分大小寫不同
    ini.read(iniFile, encoding = 'utf-8')

    return ini
```

### 

==index.py==
```python=
from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
    return "你好Flask!!!"

@app.route('/about')
def about():
    return "<html><head></head><body><p>我是<b>李大仁</b>!!!</p></body></html>"

if __name__ == '__main__':
    app.run(debug=True)
```

### 

==app.py==
```python=
import random, myconfig

#從 flask Package(資料夾) 引入Flask, request, abort 三個Module(檔案)
from flask import Flask, request, abort

# 引入有關 LinebotAPI的東西
from linebot import LineBotApi, WebhookHandler

# 引入有關 Linebot 的錯誤處理
from linebot.exceptions import InvalidSignatureError

# 引入有關 Linebot 的各類訊息模組
from linebot.models import *

#--------------------------------------
# 程式開始
#--------------------------------------

# 用 Flask 架一個 http 的 server
# __name__ 代表這個python應用程式的名稱變數
app = Flask(__name__)

# 讀取有關的設定config.ini
ini = myconfig.readConfig('config.ini')

# 設定 Line bot 相關資料
line_bot_api = LineBotApi(ini['Line的設定']['Channel_Access_Token'])
handler = WebhookHandler(ini['Line的設定']['Channel_Secret'])

# 下面是給 Line後台呼叫的程式
# 把網址 https://xxx.xxx.xxxx/ 到Line管理網站的 Webhook Url 地方填上才行
@app.route("/", 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


# 這裡是傳送TextMessage文字訊息進來的處理
@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):

    msg = event.message.text
    
    if msg == '圖':
        url = 'https://upload.cc/i1/2019/12/25/c6VRMe.jpg'
        line_bot_api.reply_message(
            event.reply_token,
            ImageSendMessage(original_content_url=url, preview_image_url=url)
        )
    else :
        line_bot_api.reply_message(
            event.reply_token,
            TextSendMessage(text='哈哈， 你說「' + event.message.text + '」')
        )

# 如果你傳貼圖給bot，bot也就回傳貼圖給你
@handler.add(MessageEvent, message=StickerMessage)
def handle_sticker_message(event):
    print("package_id:", event.message.package_id)
    print("sticker_id:", event.message.sticker_id)

    # ref. https://developers.line.me/media/messaging-api/sticker_list.pdf
    sticker_ids = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 21, 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, 401, 402]

    index_id = random.randint(0, len(sticker_ids) - 1)
    sticker_id = str(sticker_ids[index_id])
    print(index_id)

    sticker_message = StickerSendMessage(
        package_id='1',
        sticker_id=sticker_id
    )

    line_bot_api.reply_message(
        event.reply_token,
        sticker_message)


# 主動推送TextMessage文字訊息給自己
@app.route('/push')
def push_message():

    line_bot_api.push_message( 
        ini['Line的設定']['User_Id'],  #自己的User Id
        TextSendMessage(text='哈哈，我會主動和你說話了哦！')
    )

    return 'ok'

if __name__ == "__main__":
    app.run()
```

___

### 心得
#### 我還是第一次知道windows 10安裝了也不能使用VS Code，差點以為交不出來了(´Ａ｀。)
#### 做完其他部分開始打最後的心得的現在，感覺自己已經快要虛脫了
#### 初次嘗試錄這種教程(?)影片時用自動便籤來當字幕，檢查之後感覺效果還不錯，大概之後都會用這種方式錄影了吧。
#### 不過感覺位置沒有調整好，下次換到中間一點的地方小視窗比較不會擋到
###### ~~話說YouTube的畫質真的有夠差欸，不管是我遊戲的錄影還是交作業的錄影都感覺很糊~~

#### *

#### 再次感謝同班的淯卿，我能夠有成績都是她一手帶起來的，她真的超級有耐心，我問了什麼智障問題她都會慢慢教我，根本神仙本仙，普渡世人( ¯ ³¯)♡ㄘゅ

#### 然後感覺很對不起老師，因為我家這台windows 7的電腦在第二次段考就裝了Python，結果做的時候太習慣是安裝正常功能良好的Python，然後就問了智障問題:(

#### 其實在問之前我有在Google瀏覽器上搜尋過啦，但是網路上的回答可能是太文言還是太官腔，我就沒有看懂，還是要跟老師說對不起・゜・(PД`q｡)・゜・

#### 英文真的有夠困難，我還是看不太懂...
#### 搞不好要認真的考慮一下轉換跑道甚麼的

#### *

#### 我到現在還是不太明白為什麼我的VS Code會接不上LINE機器人，因為我的機器人又可以跟我說"哈哈，我會主動跟你說話了"，感覺應該是沒有什麼太大的問題啊？

#### 如果在開學之前我有弄明白了原因的話就再補交一次好了...如果有時間的話啦

#### 這一年辛苦老師了，感覺自己特別懶散，老師忍耐我們~~這些傻逼~~應該很久了，對不起QAQ