---
# System prepended metadata

title: 1207 對話機器人(4/5)
tags: [' 筆記', GCP]

---

---
title: 1207 對話機器人(4/5)
tags: GCP, 筆記
---
https://annieshing.pixnet.net/blog/post/460198511

AI：高運算力 資料
私有機房
共享機房 ->雲服務   驗證可行

colab 
環境快速重來過 ：套件可追朔 
要用就瞬間開起來 不要用就瞬間關掉 資源不浪費

GCP 3個月300美金


AI跟雲服務有很大的相關性

雲原生
雲服務體驗流程


---
## gcp的三大核心服務：

### 資料儲存：cloud storage 無限資料 (儲存)
### 資料運算：compute engine  （操作）
### 權限應用: IAM 				(權限)

---
## 實作:
![](https://i.imgur.com/J7rks5A.jpg)

### 1 .搜尋GCP
![](https://i.imgur.com/q5glKN0.png)

### 2. 頁面右上方點選『控制台』後會進入到下列畫面⬇︎

![](https://i.imgur.com/Rfusdgc.jpg)
### ->按下紅框區域,創建新的專案
![](https://i.imgur.com/e4qHUC1.png)



### 3. 專案取名，記得是無機構->建立

![](https://i.imgur.com/V8dH0nx.png)

### 若要更換語言：右上方『偏好設定』裡設定成英文

### 建立完成後，點選上方如圖->點選剛創好的專案

![](https://i.imgur.com/gUiMvFy.png)

### 點選左欄位的->Storage->Browser

 
![](https://i.imgur.com/1lT0uRG.png)
### 創建Bucket才能裝所需服務
![](https://i.imgur.com/9UIYouF.png)

### 命名Bucket->continue

![](https://i.imgur.com/ENnUNq0.png)

### 決定資料儲存地區：通常選Region->asia-east-taiwan存台灣比較便宜->continue

![](https://i.imgur.com/uk5yvBS.png)


### 越常存取選上方 不常存取選下方 這邊先選Standard
![](https://i.imgur.com/owUaeWO.png)

### 資料權限：有兩種 精細跟統一 這邊示範統一：權限統一收管
![](https://i.imgur.com/TNgIbQ4.png)

### 加密->create
![](https://i.imgur.com/KQMjAkP.png)

### 成功創建Bucket->上傳檔案 upload files
![](https://i.imgur.com/i101vww.png)

### 操作GCP可用內部的編輯器 跟外部程式來操作 這邊示範內建的：按右上方開啟 cloud shell
![](https://i.imgur.com/JTpNfxU.png)
### 開啟後按下open editor 之後往上拉
![](https://i.imgur.com/BXmkEZW.png)

### 建立一個py檔 用此來操作查看gcp內的檔案
![](https://i.imgur.com/2O3PcNS.png)

![](https://i.imgur.com/BoHntnl.png)


### 使用程式碼查看list objects
輸入以下程式碼->可從下方網站找到程式碼->更改bucket name(專案名稱)
#### 1. 進入網站 選python 複製下方程式碼至cloud shell
* [Listing objects  |  Cloud Storage  |  Google Cloud](https://cloud.google.com/storage/docs/listing-objects#code-samples)

#### 2. 如圖示
![](https://i.imgur.com/c7SwTrw.png)
#### 3. 複製到cloud shell 縮排 更改bucket name(跟專案名稱)

In GCP 內的範例程式碼
```
# 我要用python 去瀏覽桶子內有什麼檔案
# python cloud storage list all object in bucket
from google.cloud import storage
 
"""Lists all the blobs in the bucket."""
bucket_name = "自己的bucket名稱id:ai-cxcxc-demo"
 
storage_client = storage.Client()
 
# Note: Client.list_blobs requires at least package version 1.17.0.
blobs = storage_client.list_blobs(bucket_name)
 
for blob in blobs:
    print(blob.name)
```
![](https://i.imgur.com/DgJEdiJ.png)


### 開啟terminal
![](https://i.imgur.com/QZxdGMd.png)
![](https://i.imgur.com/vws8rxk.png)
### 輸入下方指令：把shell加進服務內（名稱是專案名的ID）
![](https://i.imgur.com/pAS1J3k.png)
p.s可以查看ID 名字小寫 不重複
![](https://i.imgur.com/3MjIeuS.png)

### 授權 
![](https://i.imgur.com/p3Goo2i.png)

### 程式碼在專案中才可以執行（有黃色專案名稱表示有加進去
->這邊是示範專案內操作使用
![](https://i.imgur.com/wCNKTQW.png)

### IAM權限使用：
#### 選擇IAM->Service Accounts->+create service account

![](https://i.imgur.com/m8FDU5A.png)


![](https://i.imgur.com/uhUkeLa.png)

### 創service account
![](https://i.imgur.com/khVi6yR.png)

### 給出有cloud storage的管理之權
> 權限管理可以有很細部的討論，同學在專題後可以再花時間研究
> 這邊先示範選cloud storage->storage admin
### p.s storage admin是最高權限 通常不會給到這麼大 這邊是示範

![](https://i.imgur.com/I8zuan5.png)

![](https://i.imgur.com/CYP6SpL.png)

### 未來其他使用者要操作時 可加入 課堂先不示範

![](https://i.imgur.com/zPmMeNK.png)
### 有了service accunt還要有key才能調度資料：新增key
#### 點剛剛創的名稱
![](https://i.imgur.com/CdV8Tie.png)
### 點選create new key
![](https://i.imgur.com/8523Ipy.png)

### 按create
![](https://i.imgur.com/OoI6ECw.png)
### key會存成一個json檔->改名成service_account(之後好操作)
![](https://i.imgur.com/eGesMje.png)
![](https://i.imgur.com/lDzGsp5.png)


### 使用外部程式操作：colab
要給json檔 +輸入》程式碼 才能從外部操作GCP

程式碼可參考共筆：* [004-2020-1207-第四天 - Google 文件](https://docs.google.com/document/d/1F7hN_VAtn-VzZeO5l1wyhhMX6ebvimyFAXVwBYcRoTw/edit)找到第二段有加上from_service_account_json('service_account.json')這段⬇︎

```
# 我要用python 去瀏覽桶子內有什麼檔案
# python cloud storage list all object in bucket
from google.cloud import storage
 
 
"""Lists all the blobs in the bucket."""
bucket_name = "ai-cxcxc-demo"
 
storage_client = storage.Client.from_service_account_json('service_account.json')
 
 
# Note: Client.list_blobs requires at least package version 1.17.0.
blobs = storage_client.list_blobs(bucket_name)
 
for blob in blobs:
    print(blob.name)
---
```
### colab 執行：查看cloud storage內的檔案
1. 程式碼
2. 上傳service_account.json至colab
3. 執行後可以查看cloud storage內的檔案
換句話說 在外部也可使用程式的操作來使用GCP
![](https://i.imgur.com/Rhmrgpp.png)


------

![](https://i.imgur.com/TbwrS7u.jpg)

已媒人為例，跟遠端服務溝通，都有隔壁大媽（客戶端）來溝通
要跟外部做互動 找程式碼先找客戶端


## 017 檔案操作示範

## 跟cloud storage作互動
 
* 先建個客戶端
* 用客戶端去:
上傳物件
瀏覽物件
下載物件
刪除物件



 
https://github.com/BingHongLi/ai-chatbot-tutorial/blob/main/017_%E8%8D%8A%E7%84%A1%E5%91%BD%E7%9A%84%E5%B7%A6%E6%89%8B%E5%8A%8D.ipynb

## 1. 建立客戶端 (必須要上傳service_account.json檔)


```
# step1 建立客戶端
# gcp cloud storage client python example
# 017就有了啦(以下複製017)
 
from google.cloud import storage
 
# 創建客戶端，由於在專案外，必須給一個service_account.json檔
storage_client = storage.Client.from_service_account_json('service_account.json')

```
![](https://i.imgur.com/pYd1Mdr.png)




## 2.用客戶端去上傳物件：圖中圈出來的要更改

```
# 用cloud storage的客戶端上傳物件
# python cloud storage upload object example
# 017就有了啦
 
# 上傳到指定的桶子內
# https://cloud.google.com/storage/docs/uploading-objects#storage-upload-object-code-sample
 
bucket_name='要改成自己的 如：ai-cxcxc-demo'
source_file_name= '要上傳檔案的名字13080001127357.jpg'
 
# object的名子
destination_blob_name= '上傳雲端要叫檔案名為：123/456.jpg'
 
# 指定桶子
bucket = storage_client.bucket(bucket_name)
 
# 指定本地檔案
blob = bucket.blob(destination_blob_name)
 
# 指定遠端位置
blob.upload_from_filename(source_file_name)
 
print(
    "File {} uploaded to {}.".format(
        source_file_name, destination_blob_name
    )
)

```
![](https://i.imgur.com/WCZnc2Q.png)

## 3 瀏覽物件: 執行完成後，至GCP確認檔案是否有成功上傳
### Storage->Browser
![](https://i.imgur.com/pORrT3D.png)
### 點選123資料夾
![](https://i.imgur.com/OS9TRFC.png)
### 資料有成功上傳
![](https://i.imgur.com/U6XIlqJ.png)

## 4. 下載物件：先設定權限公開 才可以下載

```
精細：每個檔案有一個權限
統一：檔案都統一權限
雲端資料預設都是不公開
```
### 選擇premission來調整權限

![](https://i.imgur.com/srzrGFL.png)
### 下方黃色區域表示在專案中擁有權限的人->按下ADD
![](https://i.imgur.com/bZKZXAI.png)


### 讓所有人都可以看到物件：選擇AllUsers->選擇Cloud Storage->Storage object viewer
![](https://i.imgur.com/W5J8SA8.png)
AllUsers 只能看 不能設定有操作權限
![](https://i.imgur.com/iNgB0ZZ.png)
### 確認：此動作後資料會公開
![](https://i.imgur.com/EPIjwSQ.png)
### 完成後，會顯示資料是公開狀態（因前面是設定統一，所以設定後所有檔案都會是公開）
![](https://i.imgur.com/28pTNju.png)

![](https://i.imgur.com/MGK0jCV.png)
### 這邊選擇任一檔案進入後，就能獲得public url,進入頁面後就可以下載資料了
![](https://i.imgur.com/TD1mr2p.png)

```
物件的權限調整
調整公開之後，物件都會有一個https連結
 
https://storage.googleapis.com/ai-cxcxc-demo/123/456.jpg
 
得到的url規律：
https://storage.googleapis.com/ + bucket_name + object_name
 
```
## 5 刪除物件：
新增程式碼：更改bucket_name和要刪除的檔案名稱

![](https://i.imgur.com/HhTi1NU.png)


```
# 刪除桶子內的物件
# https://cloud.google.com/storage/docs/deleting-objects

bucket_name = "這邊要改your-bucket-name"
blob_name = "這邊要改your-object-name"

bucket = storage_client.bucket(bucket_name)
blob = bucket.blob(blob_name)
blob.delete()

print("Blob {} deleted.".format(blob_name))
```

----
## 示範LineChatBot 與GCP結合
<!-- google 估得好 工程師當到老 -->

:::info
#### 用戶上傳照片到我方的機器人裡面，機器人將照片傳入cloud storge 內，並依照用戶id做資料夾

程式碼pattern：
* 安裝套件
* 引用套件
* 應用伺服器準備
* 消息素材準備
* 應用方法設計
* 伺服器起啟動
:::


### 1.安裝套件


```
!pip install line-bot-sdk flask flask-ngrok
```
![](https://i.imgur.com/RHvMwcF.png)
---
### 2.引用套件

```
'''
引用套件
'''

# 引用Web Server套件
from flask import Flask, request, abort, jsonify

# 載入json處理套件
import json

# 外部連結自動生成套件
from flask_ngrok import run_with_ngrok

# 從linebot 套件包裡引用 LineBotApi 與 WebhookHandler 類別
from linebot import (
    LineBotApi, WebhookHandler
)

# 引用無效簽章錯誤
from linebot.exceptions import (
    InvalidSignatureError
)
```
----
![](https://i.imgur.com/51GsGpD.png)

----
### 3.應用伺服器準備：app, handler,line-bot-api,storage-client
登入line api 更改CHANNEL_SECRET/CHANNEL_ACCESS_TOKEN
* [Messaging API 介紹 | LINE Developers](https://developers.line.biz/zh-hant/docs/messaging-api/overview/)


```
'''
建置主程序

建置handler與 line_bot_api
'''

# 設定Server啟用細節
app = Flask(__name__,static_url_path = "/material" , static_folder = "./material/")
run_with_ngrok(app)

# 生成實體物件
line_bot_api = LineBotApi("要改CHANNEL_ACCESS_TOKEN“)
handler = WebhookHandler("要改CHANNEL_SECRET")

from google.cloud import storage

# 本地端才如此作為，最好改用環境變數
storage_client = storage.Client.from_service_account_json('service_account.json')
```
![](https://i.imgur.com/BZHJyX1.png)

---

### 4.主程序的入口：讓line把消息傳過來，並依照我們設定處理

```
'''
建置主程序的API入口
  接受Line傳過來的消息
  並取出消息內容
  將消息內容存在google drive的檔案內
  並請handler 進行消息驗證與轉發
'''

# 啟動server對外接口，使Line能丟消息進來
@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)
    print(body)

    # 記錄用戶log，請去查更正確的logging作法
    f = open("./ai-event.log", "a")
    f.write(body)
    f.close()

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'
```
![](https://i.imgur.com/UqIj1PF.png)

----

### 5.業務方法處理：收到圖片消息的時候，把圖片抓回來，再上傳到cloud storage內(bucket_name要改GCP要存的專案id名稱)

```
'''
若收到圖片消息時，

先回覆用戶文字消息，並從Line上將照片拿回。

'''

from linebot.models import(
    MessageEvent,ImageMessage, TextSendMessage
)

# 吿知handler 收到消息事件時 且為圖片消息 做下面的方法
@handler.add(MessageEvent, message=ImageMessage)
def handle_message(event):
    
    #回覆用戶
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text='Image has Upload'+ ' ' + event.message.id))
    
    #請line_bot-api把圖片抓回來
    message_content = line_bot_api.get_message_content(event.message.id)
    with open(event.message.id+'.jpg', 'wb') as fd:
        for chunk in message_content.iter_content():
            fd.write(chunk)
    #指定上傳位置
    bucket_name='your_gcp_bucket_name'
    source_file_name= event.message.id+'.jpg'
    destination_blob_name=  event.source.user_id +'/'+ event.message.id+'.jpg'

    bucket = storage_client.bucket(bucket_name)

    blob = bucket.blob(destination_blob_name)

    blob.upload_from_filename(source_file_name)
```
![](https://i.imgur.com/HbyKbas.png)



### 6.伺服器啟動(將更新網址回傳到Line Webhook URL使用)
![](https://i.imgur.com/NJCdYAp.png)

### 7.執行後，用戶從line機器人上傳照片會出現在左邊以及在Cloud Storage內會自動依照用戶id存成資料夾。
![](https://i.imgur.com/phc8gNQ.png)


-----
## 解析google Text-to-Speech使用，若要直接應用在Line Chatbot可看老師019程式碼


### 1.先到GCP搜尋->按下啟用

![](https://i.imgur.com/xJV87NA.png)

![](https://i.imgur.com/n043alP.png)

### 2. 調度ai的範例 （參考老師019範例或共筆4內程式碼）


將下方程式碼複製至colab

```
# 安裝之後，點擊重新執行階段
!pip install google-cloud-texttospeech
 
from google.cloud import texttospeech
 
# Instantiates a client
client = texttospeech.TextToSpeechClient.from_service_account_json('service_account.json')
 
# Set the text input to be synthesized
synthesis_input = texttospeech.SynthesisInput(text="班代，每次都拍你，你是不是很開心？")
 
# Build the voice request, select the language code ("en-US") and the ssml
# voice gender ("neutral")
voice = texttospeech.VoiceSelectionParams(
    language_code='zh-TW',
    ssml_gender=texttospeech.SsmlVoiceGender.NEUTRAL)
 
# Select the type of audio file you want returned
audio_config = texttospeech.AudioConfig(
    audio_encoding=texttospeech.AudioEncoding.LINEAR16)
 
# Perform the text-to-speech request on the text input with the selected
# voice parameters and audio file type
response = client.synthesize_speech(input=synthesis_input, voice=voice, audio_config=audio_config)
 
# The response's audio_content is binary.
with open('output.wav', 'wb') as out:
    # Write the response to the output file.
    out.write(response.audio_content)
    print('Audio content written to file "output.wav"')
 
 

```
### 重新啟動並執行

![](https://i.imgur.com/BNXZDbT.png)
![](https://i.imgur.com/aGmU0VG.png)

### 按下圖中按鈕
![](https://i.imgur.com/awQmQWs.png)
## 執行成功後 檔案內會出現剛剛文字輸入的音檔
![](https://i.imgur.com/Ity1sjX.png)


-----
##  更換聲音：從SsmlVoiceGender查看原始碼
![](https://i.imgur.com/W1RRio3.png)

若要女聲，將程式碼從
```
ssml_gender=texttospeech.SsmlVoiceGender.NEUTRAL) 更改成
```

```
ssml_gender=texttospeech.SsmlVoiceGender.FEMALE)

```
![](https://i.imgur.com/yiHAhRf.png)


-----

## 將AI導入Line Chatbot:google Text-to-Speech：使用019實際操作，將需要改的名稱填上，就能使用了！

* [ai-chatbot-tutorial/019_GCP與Chatbot_2.ipynb at main · BingHongLi/ai-chatbot-tutorial](https://github.com/BingHongLi/ai-chatbot-tutorial/blob/main/019_GCP%E8%88%87Chatbot_2.ipynb)
```
!pip install line-bot-sdk flask flask-ngrok 

# 安裝後必須點擊Runtime -> Restart Runtime
!pip install  google-cloud-texttospeech
```

```
'''
引用套件
'''

# 引用Web Server套件
from flask import Flask, request, abort, jsonify

# 載入json處理套件
import json

# 外部連結自動生成套件
from flask_ngrok import run_with_ngrok

# 從linebot 套件包裡引用 LineBotApi 與 WebhookHandler 類別
from linebot import (
    LineBotApi, WebhookHandler
)

# 引用無效簽章錯誤
from linebot.exceptions import (
    InvalidSignatureError
)
```
```
'''
建置主程序

建置handler與 line_bot_api
'''

# 設定Server啟用細節
app = Flask(__name__,static_url_path = "/material" , static_folder = "./material/")
run_with_ngrok(app)

# 生成實體物件
line_bot_api = LineBotApi("CHANNEL_ACCESS_TOKEN")
handler = WebhookHandler("CHANNEL_SECRET")
  
from google.cloud import storage
from google.cloud import texttospeech
# 本地端才如此作為，最好改用環境變數
storage_client = storage.Client.from_service_account_json('service_account.json')
bucket_name='GCP Cloud Storage Bucket name'

# Instantiates a client
speech_client = texttospeech.TextToSpeechClient.from_service_account_json('service_account.json')

```


```
'''
建置主程序的API入口
  接受Line傳過來的消息
  並取出消息內容
  將消息內容存在google drive的檔案內
  並請handler 進行消息驗證與轉發
'''

# 啟動server對外接口，使Line能丟消息進來
@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)
    print(body)

    # 記錄用戶log，請去查更正確的logging作法
    f = open("./ai-event.log", "a")
    f.write(body)
    f.close()

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'

```

```
'''

若收到圖片消息時，

先回覆用戶文字消息，並從Line上將照片拿回。

'''

from linebot.models import(
    MessageEvent,ImageMessage, TextSendMessage
)

@handler.add(MessageEvent, message=ImageMessage)
def handle_message(event):
    
    line_bot_api.reply_message(
        event.reply_token,
        TextSendMessage(text='Image has Upload'+ ' ' + event.message.id))
    
    message_content = line_bot_api.get_message_content(event.message.id)
    with open(event.message.id+'.jpg', 'wb') as fd:
        for chunk in message_content.iter_content():
            fd.write(chunk)


    source_file_name= event.message.id+'.jpg'
    destination_blob_name=  event.source.user_id +'/'+ event.message.id+'.jpg'

    bucket = storage_client.bucket(bucket_name)

    blob = bucket.blob(destination_blob_name)

    blob.upload_from_filename(source_file_name)
```


```
'''
若收到文字消息時

將文字傳給GCP，轉譯成音訊後

放到cloud storage，並組合成AudioSendMessage，傳回給用戶

Podcast
'''

from linebot.models import(
    MessageEvent,TextMessage, AudioSendMessage
)


@handler.add(MessageEvent, message=TextMessage)
def handle_text_message(event):

  # Set the text input to be synthesized
  synthesis_input = texttospeech.SynthesisInput(text=event.message.text)


  # Build the voice request, select the language code ("en-US") and the ssml
  # voice gender ("neutral")
  voice = texttospeech.VoiceSelectionParams(
      language_code="zh-TW", ssml_gender=texttospeech.SsmlVoiceGender.NEUTRAL
  )

  # Select the type of audio file you want returned
  audio_config = texttospeech.AudioConfig(
      audio_encoding=texttospeech.AudioEncoding.MP3
  )

  # Perform the text-to-speech request on the text input with the selected
  # voice parameters and audio file type
  response = speech_client.synthesize_speech(
    input=synthesis_input, voice=voice, audio_config=audio_config
  )

  # The response's audio_content is binary.
  voice_mp3_file_path=event.message.id+".mp3"
  with open(voice_mp3_file_path, "wb") as out:
      # Write the response to the output file.
      out.write(response.audio_content)
      print('Audio content written to file '+voice_mp3_file_path)


  # 上傳檔案
  destination_blob_name=  event.source.user_id +'/'+ event.message.id+'.mp3'

  bucket = storage_client.bucket(bucket_name)

  blob = bucket.blob(destination_blob_name)

  blob.upload_from_filename(voice_mp3_file_path)

  # 回話
  line_bot_api.reply_message(
      event.reply_token,
      AudioSendMessage(
       original_content_url ="https://storage.googleapis.com/"+bucket_name+'/'+destination_blob_name,
       duration=60000
      ) 
  )
```

```

# 主程序運行
app.run()
```


Google ML 參考
https://colab.research.google.com/github/robeartoe/APIWorkshop/blob/master/MLWorkshop.ipynb#scrollTo=Snq8ehAu7JkD





-----


## 用Json檔轉成消息給用戶


```
!pip install line-bot-sdk flask flask-ngrok 
```

```
'''
引用套件
'''

# 引用Web Server套件
from flask import Flask, request, abort, jsonify

# 載入json處理套件
import json

# 外部連結自動生成套件
from flask_ngrok import run_with_ngrok

# 從linebot 套件包裡引用 LineBotApi 與 WebhookHandler 類別
from linebot import (
    LineBotApi, WebhookHandler
)

# 引用無效簽章錯誤
from linebot.exceptions import (
    InvalidSignatureError
)
```

```
''
建置主程序

建置handler與 line_bot_api
'''

# 設定Server啟用細節
app = Flask(__name__,static_url_path = "/material" , static_folder = "./material/")
run_with_ngrok(app)

# 生成實體物件
line_bot_api = LineBotApi("CHANNEL_ACCESS_TOKEN")
handler = WebhookHandler("CHANNEL_SECRET")
```

```
'''
建置主程序的API入口
  接受Line傳過來的消息
  並取出消息內容
  將消息內容存在google drive的檔案內
  並請handler 進行消息驗證與轉發
'''

# 啟動server對外接口，使Line能丟消息進來
@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)
    print(body)

    # 記錄用戶log，請去查更正確的logging作法
    f = open("./ai-event.log", "a")
    f.write(body)
    f.close()

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)

    return 'OK'
```

```
'''
line bot designer 的json字串檔
我們能不能判斷 json的type欄位
'''
demo_message_json_string='''
{
  "type":"location",
  "title":"test",
  "address":"test",
  "latitude":35.65910807942215,
  "longitude":139.70372892916203
}
'''
```

```
import json
demo_message_json=json.loads(demo_message_json_string)

```
```
'''
判斷Json檔的type格式 如果為text 那就用TextSendMessage 回應
如果為location 那就用LocationSendMessage回應
'''
from linebot. models import (ImageSendMessage, TextSendMessage, LocationSendMessage)
from linebot.models import (TextSendMessage,LocationSendMessage)
if demo_message_json.get('type')=='text':
    reply_text_send_message=TextSendMessage.new_from_json_dict(demon_message_json)
elif demo_message_json.get('type')=='location':
    reply_send_message=LocationSendMessage.new_from_json_dict(demon_message_json)
elif demo_message_json.get('type')=='image':
    reply_send_message= ImageSendMessage.new_from_json_dict(demon_message_json)
```

```
from linebot.models import (MessageEvent, TextMessage)
@handler.add(MessageEvent, message=TextMessage)
def handle_text_message(event):

    line_bot_api.reply_message(
            event.reply_token,
            text_send_message
            )
```

```
app.run()
```


line bot designer 的json字串檔


上方程式碼執行後，當用戶端傳訊息給機器人後，下方會出現json檔
把這些程式碼丟到Json Formatter可以方便看出格式
* [JSON Formatter & Validator](https://jsonformatter.curiousconcept.com/#)
* 
![](https://i.imgur.com/IquQCRj.png)




![](https://i.imgur.com/y8NAjpH.png)






------
### 小補充

* 創立專案：
名稱 跟ID通常一樣 除非有特別改
project 任何服務都不能執行!（空盤子）!換成無機構 不要用學校的

* 公司一個項目 建立一個GCP專案 
* 設立預算 （以防被盜後有些保障）
* 預算與快訊-> 設定預算
* service account 需要key 才能操作
----

### cloud storage
應用場景
巨量資料
空間無限的儲存服務

設計思路 核心名詞

資源object 裝載容器 bucket 
水 水杯
錢 錢包
鉛筆 鉛筆盒


創桶子 資料所在地 storage-level 1
取用權限
加密

---





![](https://i.imgur.com/pBPXivu.jpg)

# END