初版作成 2022.3.24
最終更新 2024.04.01
2 つのことができる (1) push : 投稿する 具体的には https://api.line.me/v2/bot/message/push に 対して json 形式のデータを POST する (2) reply : 投稿されたメッセージを読み取り、応答メッセージを投稿する 具体的には、投稿されたメッセージを受信する url を用意し、 cgi プログラムを配置する。 その url に対して json 形式のデータが POST されてくる。 応答を json 形式で用意し、 https://api.line.me/v2/bot/message/reply に POST する。 必要な json の内容は若干異なるが、 https://api.line.me/v2/bot/message/push に POST しても 投稿に対応して、応答を投稿するという機能は 同じであると思われる。
チュートリアル:#_#link#https://developers.line.biz/ja/docs/messaging-api/line-bot-sdk/#https://developers.line.biz/ja/docs/messaging-api/line-bot-sdk/# - line developer へ登録する(無料) developers.line.biz/ja/ - プロバイダを新規作成 - チャンネルを新規作成 チャンネル名が Line の公式アカウントとなる チャンネルの種類は Messaging API - QR コードを使ってスマホで Line に参加する スマホで Line を起動し、 ホームの 上方の検索窓の右端の [ ] をタップして QR コードを読み取ると、友達追加の画面になり 友達追加をタップする。 その友達のトークルームが見あたらない。 もういちど、QR コードを読み取らせると、その友達のトークルームが 出現する。 - メッセージを送ったらコールされる url を設定する Message API 設定 のタブを押す Webhook URL を入力し更新する(https でないとダメ) Webhook の利用を on にする - 一番下に channel access token がある issue を押してトークンを取得する
- push に必要な情報は以下の 2 つ channel access token (Message API設定のタブの下の方) user id (チャネル基本設定のタブの下の方) push は普通のパソコンからできる。 - reply は投稿データを受信する url が必要 json データが送られてくる。その中に投稿データと replyToken が入っている 応答の投稿には来たデータの中にある replyToken と channel access token が必要
以下の 4 つが考えられる (1) Google google drive に google Apps Script を作成し、 「デプロイする」のボタンを押すと、 そのスクリプトに url が割り当てられ、 POST されたデータを受け取ることができる。 プログラムを変更した場合、デプロイし直す 必要があり、url が変わるので、開発効率が 悪い。 しかし、無料で使える環境の中では 最も優れた環境であると思われる。 (2) lolipop などのレンタルサーバ python でプログラムを書くなら、これが一番やりやすい。 月 400 円~ 700 円程度かかるが、python を使って 開発したいなら、開発効率は高い。 ただし、lolipop ではエラーログを見ることができないので、 開発効率が悪い。 (3) heroku heroku という無料で web アプリを配置できるサービスがあったが、 2022/11/27 で廃止されたらしい。heroku のしくみは以下の通り。 プログラムを手元の PC で作成し、heroku という独自コマンドと git コマンドを利用して、プログラムの作成とアップロードを行う。 この方法は flask を用いたサンプルプログラムが ネットに多数あるが、以下の欠点があり、開発効率が 絶望的に悪い。 > cme.exe において CLI (command line interface) の操作が必要 > git のシステムを理解し、コマンドを使いこなすのは敷居が高い > git でアップロードするのにある程度時間がかかる。 レンタルサーバを用いる方法だと、ssh で接続し、 プログラムを修正してセーブしたら、即実行可能である。 > flask は web サーバーを立てるモジュールである。 heroku の https (443) ポートに来たアクセスを、 ポート番号 5000 に転送し、5000 番で待っている flask サーバ が処理するという方法である。 その概念を理解するのに時間がかかる。 > flask を利用したプログラムはデコレータを利用しており、 非常に難易度が高い。 > heroku は 30 分経つとスリープ状態になるので実用的では ないらしい。 > レンタルサーバで flask で受ける場合 443 ではなく 8080 などの 番号で受けることになる。その場合、SSL のエンコードとデコードを 自力で行う必要があり、証明書の取得など難易度が高い。 (4) 自前のサーバ 自力でサーバを用意し、グローバル IP を取得し、 外部からアクセスできるようにする。 非常に敷居が高いが、スクリプトでエラーが発生したとき、 access_log, error_log を即座に確認できるので 開発効率は最も高いと思われる。
以下のようにすると開発効率が高いと思われる (Windows マシン使用) ・PC 版 Line をインストールし、Line への投稿、確認は PC で行う。 投稿は alt+Enter ではなく Enter でできるようにしておいた方が操作性がよい。 ウィンドウ左下の非常に薄い文字の「設定」をクリック ・Web ブラウザは Line Developer のサイト(投稿を受け取る url の 設定変更に必要)、投稿を受け取る url を常に開いておく。 ・プログラムは Google Apps Script で開発するならブラウザで、 レンタルサーバで python を使うなら、teraterm などで ssh 接続 してプログラミングする。
$ pip3 install line-bot-sdk $ pip3 install requests flask を使う場合、ファイル名を flask.py とすると、 import するときに自分を import しようとして エラーが出るので注意。
プログラムは最もシンプルになる import sys from linebot import LineBotApi from linebot.models import TextSendMessage token = 'トークンの値' user_id = "id の値' lines = "push line bot" messages = TextSendMessage(text=lines) print(messages) line_bot_api = LineBotApi(token) line_bot_api.push_message(user_id, messages=messages)
import requests
import json
token = "トークンの値"
user_id = "id の値"
api_url = 'https://api.line.me/v2/bot/message/push'
message = "send string"
token_dic = {"Content-Type": "application/json", "Authorization": "Bearer " + token}
send_dic = {"to": user_id, "messages":[{"type":"text", "text":message}]}
send_dic_json = json.dumps(send_dic)
requests.post(api_url, headers=token_dic, data=send_dic_json)
画像を push するには、あらかじめどこかの url に
画像をアップロードしておくことが必要。
notify ならローカルの画像ファイルを送信可能
import linebot
from linebot import LineBotApi
from linebot.models import TextSendMessage
from linebot.models import ImageSendMessage
token = 'トークン'
user_id = 'user id'
image_url = "https://xxx.yyy.zzz/dir/fname.jpg"
image_message = ImageSendMessage(
original_content_url = image_url,
preview_image_url = image_url)
print(image_message)
line_bot_api = LineBotApi(token)
line_bot_api.push_message(user_id, messages=image_message)
import requests
import json
token = 'トークンの値'
user_id = 'user id の値'
api_url = 'https://api.line.me/v2/bot/message/push'
image_url = 'https://xxx.yyy.zzz/dir1/fname.jpg'
token_dic = {"Content-Type": "application/json", \
"Authorization": "Bearer " + token}
send_dic = {"to": user_id, \
"messages": [ {"type": "image", \
"originalContentUrl": image_url, \
"previewImageUrl": image_url, \
}
] \
}
send_dic_json = json.dumps(send_dic)
requests.post(api_url, headers=token_dic, data=send_dic_json)
import json
import sys
import datetime
import linebot
from linebot import LineBotApi
from linebot.models import TextSendMessage
from linebot.models import ImageSendMessage
token = 'トークン'
line_bot_api = LineBotApi(token)
data = json.load(sys.stdin)
text = data["events"][0]["message"]["text"]
replyToken = data["events"][0]["replyToken"]
# ファイルに書き出して確認
f = open("json.txt","w")
print(json.dumps(data), file = f)
f.close()
# 応答の例
if text == "t":
messages = "reply by text"
line_bot_api.reply_message(replyToken, TextSendMessage(text=messages))
elif text == "c":
image_url = "https://aaa.bbb.jp/dir/image.jpg"
image_message = ImageSendMessage(
original_content_url = image_url,
preview_image_url = image_url)
line_bot_api.reply_message(replyToken, image_message)
else:
messages = "no action"
line_bot_api.reply_message(replyToken, TextSendMessage(text=messages))
import requests
import json
import sys
token = "トークンの内容"
url = 'https://api.line.me/v2/bot/message/reply'
data = json.load(sys.stdin)
text = data["events"][0]["message"]["text"]
replyToken = data["events"][0]["replyToken"]
# ファイルに書き出して確認
f = open("json.txt","w")
print(json.dumps(data), file = f)
f.close()
# 応答の例
if text == "a":
message = "you input a"
elif text == "b":
message = "you input b"
else:
message = "you input other"
token_dic = {"Content-Type": "application/json", \
"Authorization": "Bearer " + token}
send_dic = {"replyToken": replyToken, \
"messages":[{"type":"text", "text": message}]}
send_dic_json = json.dumps(send_dic)
requests.post(url, headers=token_dic, data=send_dic_json)
(1) line-bot-sdk のインストール 参考サイト https://dattesar.com/lolipop-pip-flask/ - pip3 をインストールする $ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py $ python3 get-pip.py --user - path を通す ~/.bash_profile に以下を記述 PATH=$PATH:/home/users/0/xxxxxxx/.local/bin export PATH $ . ~/.bash_profile - ライブラリのインストール $ pip3 install line-bot-sdk 既にインストールされているライブラリの確認法 $ pip3 freeze - cgi を配置する chmod 755 を忘れずに cgi は www-data ではなく、自分の権限で動作する。 ディレクトリを 777 にするとエラーになるので要注意
○ JavaScript での使い方
let data = {"key1": "data1", "key2": ["a","b"]};
a = data.key1;
b = data[1].key2; 配列へのアクセス
○ python での使い方
・web 上にあるファイルからの読み込み
url = 'https://www.jma.go.jp/bosai/forecast/data/overview_forecast/130000.json'
req = urllib.request.urlopen(url)
page = req.read().decode() # このサイトは decode() はなくても同じ結果
print(page)
dic = json.loads(page)
print(dic['reportDatetime']) # 1 つのフィールドを表示
for key in dic.keys(): # .keys() はなくてもよい
print("key = " + key + " value = " + dic[key])
・ファイルからの読み込み
f = open(fname, "r")
dic = json.load(f)
以下同じ
自分だけに通知するなら Line Notify を利用する方法が簡便である。 トークンだけで、投稿できる。 以下の url にアクセスする https://notify-bot.line.me/ja/ ログインして、右上の自分の名前 --- マイページ あるいは以下のページに直接アクセスする https://notify-bot.line.me/my/ 「トークンを発行する」を押す トークン名を入れ、通知を送信するトークルームを 選択する。 1:1でLINE Notifyから通知を受け取る という トークルームが先頭にある。これを選択すると LINE Notify というトークルームが新規作成され、 そのトークルームに投稿される。 「コピー」ボタンを押すと、トークンがクリップボードに コピーされる。プログラムの中に貼り付けて使用する。 それ以外のトークルームとして、 友達リストに登録されたグループ名が表示される。 この扱い方はよく分からない。
import requests
url = "https://notify-api.line.me/api/notify"
token = "トークン"
message = "投稿したい文字列"
headers = {'Authorization': f'Bearer {token}'}
data = {'message': f'{message}'}
response = requests.post(url, headers=headers, data=data)
print(response.status_code)
print(response.text)
import requests
token = 'トークン'
url = "https://notify-api.line.me/api/notify"
message = "notifyで画像送信"
fname = "./sample.jpg"
image = open(fname, "rb")
image_dic = {'imageFile': image}
token_dic = {'Authorization': f'Bearer {token}'}
send_dic = {'message': message}
response = requests.post(url, headers=token_dic, data=send_dic, files=image_dic)
print(response.text)