@0113arata2

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

PythonでLINEAPIを使うときになぜかエラーが出てしまう...

解決したいこと

PythonのTikinterとLINEAPIを連携させて、入力したものを送信するというアプリを作っている途中でなぜかエラーが発生してしまいました。こんなときどうしたらいいでしょうか?

発生している問題・エラー

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\ユーザー名\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 1948, in __call__
    return self.func(*args)
           ^^^^^^^^^^^^^^^^
  File "C:\Users\ユーザー名\Desktop\file\API\Line\Send\main.py", line 24, in main
    accesstoken.push_message(user_id, messages)
  File "C:\Users\ユーザー名\AppData\Local\Programs\Python\Python311\Lib\site-packages\linebot\api.py", line 163, in push_message
    self._post(
  File "C:\Users\ユーザー名\AppData\Local\Programs\Python\Python311\Lib\site-packages\linebot\api.py", line 1860, in _post
    self.__check_error(response)
  File "C:\Users\ユーザー名\AppData\Local\Programs\Python\Python311\Lib\site-packages\linebot\api.py", line 1896, in __check_error
    raise LineBotApiError(
linebot.exceptions.LineBotApiError: LineBotApiError: status_code=400, request_id=44c21f36-1fd9-4984-940a-762be5161157, error_response={"details": [], "message": "The property, 'to', in the request body is invalid (line: -, column: -)"}, headers={'cache-control': 'no-cache, no-store, max-age=0, must-revalidate', 'content-type': 'application/json', 'date': 'Tue, 28 Feb 2023 07:15:16 GMT', 'expires': '0', 'pragma': 'no-cache', 'server': 'envoy', 'x-content-type-options': 'nosniff', 'x-frame-options': 'DENY', 'x-line-request-id': '44c21f36-1fd9-4984-940a-762be5161157', 'x-xss-protection': '1; mode=block', 'content-length': '85'}

ソースコード

#インポート
from linebot.models import TextSendMessage
from linebot import LineBotApi
from tkinter import filedialog
from tkinter import messagebox
import tkinter.ttk as ttk
import requests
import tkinter
import json
import sys
import os

#Tikinterの基本設定
root = tkinter.Tk()
root.title(u"LINE送信パネル")
root.geometry("310x210")
root.resizable(0,0)

#ファンクションプログラム
def main(event): #ここがLINEを送信するプログラムになっています。
    accesstoken = LineBotApi(EditBox3.get()) #ここで3番目のボックスの値をアクセストークンに代入しています。
    user_id = EditBox2.get() #ユーザーIDは2番目のボックスです。
    messages = TextSendMessage(text=EditBox1.get()) #1番目はメッセージ内容になっています。
    accesstoken.push_message(user_id, messages) #ここでLINEを送信するはずなんです。

def File(event): #これは同じディレクトリにある"Deta.json"を読み込んでボックスに文字を書き込みます。
        json_open = open('Deta.json', 'r') #Deta.jsonを読み込みます。
    json_load = json.load(json_open) #Jsonとして読み込みます。
    Token = json_load['Token']['key'] #"Token"にJsonの値を代入します。
    UserID =  json_load['UserID']['key'] #"UserID"もJsonの値を代入します。
    EditBox2.delete(0) #リセットします。
    EditBox3.delete(0) #リセットします。
    EditBox2.insert(0,UserID) #ユーザーIDを書き込みます
    EditBox3.insert(0,Token) #トークンを書き込みます
    messagebox.showinfo("LINE送信パネル","ユーザーID、アクセストークンを読み込みました。") #ダイアログボックスを表示させます。

def Save(event): #これはボックスにある値を"Deta.json"に保存するコードです。
    Token = EditBox3.get() #トークンをゲットします。
    UserID = EditBox2.get() #ユーザーIDをゲットします。
    with open('Deta.json', 'w') as SaveFile: #"Deta.json"を読み込みます。
        print('', file=SaveFile)
        print('{"Token":{"key":"' + Token + '"},"UserID":{"key":"' + UserID + '"}}', file=SaveFile) #これでユーザーIDとトークンを保存します。
    messagebox.showinfo("LINE送信パネル","ユーザーID、アクセストークンを保存しました。") #ダイアログボックスを表示させます。

#UI
Static1 = tkinter.Label(text=u'メッセージ内容')
Static1.pack()

EditBox1 = tkinter.Entry(width=50)
EditBox1.pack()

border1=ttk.Separator(root,orient="horizontal")
border1.pack(fill="both")

Static2 = tkinter.Label(text=u'宛先(ユーザーID経由)')
Static2.pack()

EditBox2 = tkinter.Entry(width=50)
EditBox2.pack()

border2=ttk.Separator(root,orient="horizontal")
border2.pack(fill="both")

Static1 = tkinter.Label(text=u'チャネルアクセストークン')
Static1.pack()

EditBox3 = tkinter.Entry(width=50)
EditBox3.pack()

border3=ttk.Separator(root,orient="horizontal")
border3.pack(fill="both")

Button = tkinter.Button(text=u'LINEを送る。',width=40)
Button.bind("<Button-1>",main) 
Button.pack()

Button2 = tkinter.Button(text=u'ファイルを開く',width=40)
Button2.bind("<Button-1>",File) 
Button2.pack()

Button2 = tkinter.Button(text=u'保存する',width=40)
Button2.bind("<Button-1>",Save) 
Button2.pack()

root.mainloop()

Deta.jsonの内容

{
    "Token":{
        "key":"ここにチャネルアクセストークンが入ります。"
    },

    "UserID":{
        "key":"ここにユーザーIDが入ります。"
    }
}

実行したときの画面

1677569555396.jpg

自分で試したこと

多分LINE-BOT-SDKライブラリが原因だと考えて、再インストールしましたが、うまくいかない状況です。もし何かわかったら是非教えてください。

1 likes

4Answer

user_idをそのまま見せてもらうわけにはいかないので、自分ならこうする、という切り分け方法だけ書きます。既にやってることも含まれてると思いますがご容赦ください。

1 mainにprintを仕込んでuser_idが正しく取得できているか確認する。(Deta.jsonに記載した値をそのまま<to>に入れてpush_messageすれば動くと仮定する)

def main(event): #ここがLINEを送信するプログラムになっています。
    accesstoken = LineBotApi(EditBox3.get()) #ここで3番目のボックスの値をアクセストークンに代入しています。
    user_id = EditBox2.get() #ユーザーIDは2番目のボックスです。
+   print(user_id)
    messages = TextSendMessage(text=EditBox1.get()) #1番目はメッセージ内容になっています。
    accesstoken.push_message(user_id, messages) #ここでLINEを送信するはずなんです。

printの結果を見て、Dete.jsonと同じ値が出力されていない場合
--> SDKの問題ではない。jsonからEditBox2にデータを入力あるいはEditBox2から取得する処理のどこかでうまくいっていないのでそちらを中心に調査する。

取得できている場合
--> 最初に置いた仮定が正しくない可能性がある。次へ進む。
2 Dete.jsonに記載したUserIDを使って、公式のドキュメントにあるサンプル通りのミニマムなコードでメッセージを送信する。
https://developers.line.biz/en/reference/messaging-api/#send-push-message

送信できる場合
--> 送信に成功した際に使っていたUserIDをそのままコピペしてDete.jsonに記載して再度動かしてみる(目に見えない制御文字などが紛れ込んでいる可能性もあるので)

送信できない場合
--> UserIDは<to>の値として不適切なので何を入れるべきなのか改めてドキュメントを確認する。再取得する、等。

1Like

Comments

  1. @0113arata2

    Questioner

    コメントありがとうございます!やってみて確かに出力されていました。ですが肝心の送信までがうまくいかなかったです。やはりpipやpythonが関係しているのでしょうか?今はpythonの再インストール、キャッシュの削除などをしています。でもここまで調べてくれてその上にいろいろな対処法を教えてくれてありがとうございます!!!
  2. https://developers.line.biz/ja/reference/messaging-api/#send-push-message
    push_messageのドキュメントを読むと以下のように書かれていますが、toに指定しているユーザはその条件を満たしていますか?
    ---
    プッシュメッセージは、以下のいずれかの条件に当てはまる場合に送信できます。
    LINE公式アカウントを友だち追加しているユーザー
    LINE公式アカウントが参加しているグループトーク、または複数人トーク
    1対1のトークで、7日以内にLINE公式アカウントへメッセージを送ったユーザー(※)
    ---

    また、curlを使ったサンプルも上記のページにあるのでpythonで送信しているのと同じリクエストをターミナルから送信してみることをお勧めします。コピーしてアクセストークンとtoを書き換えるだけになっていそうなので簡単に試せると思います。
  3. ちなみに私も自分のアカウントでbotを作成してみましたが、難なくメッセージ送信できました。
    Python 3.9.13
    line-bot-sdk-python v2.4.1

可能な限りソースコードはエラーが発生したものをそのままアップしてください。回答しやすくなります。

記載されたエラーメッセージを素直に読むと、main関数には引数が定義されていないけど実際の呼び出し時には引数が渡されてしまってエラーになってるようです。

↑エラーログが修正されたので消しました

0Like

Comments

  1. @0113arata2

    Questioner

    回答ありがとうございます!エラー内容をすべてコピーしたので回答してくれればとてもうれしいです!

試しに、main関数にダミーの引数を定義したらどうなりますか?

- def main():
+ def main(dummy):
    accesstoken = LineBotApi(EditBox3.get())
    :   :
0Like

Comments

  1. @0113arata2

    Questioner

    ありがとうございます!!!やってみましたが、うまくいきませんでした。エラー内容も全くいっしょでした。
    また何かあればぜひ回答お願いします!
  2. > File "C:\Users\ユーザー名\Desktop\file\API\Line\Send\main.py", line 24, in main
    accesstoken.push_message(user_id, messages)

    > linebot.exceptions.LineBotApiError: LineBotApiError: status_code=400, request_id=44c21f36-1fd9-4984-940a-762be5161157, error_response={"details": [], "message": "The property, 'to', in the request body is invalid (line: -, column: -)"}, headers={'cache-control': 'no-cache, no-store, max-age=0, must-revalidate', 'content-type': 'application/json', 'date': 'Tue, 28 Feb 2023 07:15:16 GMT', 'expires': '0', 'pragma': 'no-cache', 'server': 'envoy', 'x-content-type-options': 'nosniff', 'x-frame-options': 'DENY', 'x-line-request-id': '44c21f36-1fd9-4984-940a-762be5161157', 'x-xss-protection': '1; mode=block', 'content-length': '85'}

    これが真のエラーですね。「宛先(to)」が不正?
  3. @0113arata2

    Questioner

    多分違うと思います。print関数で調べると正しく表示されており正しく代入されているため多分大丈夫なはずです。でも考えてくださりとても感謝しています。

LineAPIに明るくないのですが、ネットで調べてみるとtoは、自分のIDみたいですね。

line_bot_api = LineBotApi('<channel access token>')
line_bot_api.push_message('<to>', TextSendMessage(text='Hello World!'))

スクリーンショット 2023-02-28 17.29.41.png

0Like

Comments

  1. @0113arata2

    Questioner

    回答ありがとうございます!私もその方法で送れていたのですが、突然できなくなってしましました。やはりpipのほうにエラーが起きているのかもしれません。とはいえわざわざここまで調べてくださり誠にありがとうございます!!!また何かわかったら是非コメントしてください!!!

Your answer might help someone💌