コンテンツダウンロードAPIのアクセス時に認証失敗が出てしまう。
概要
LINE WORKSのコンテンツダウンロード(GET /bots/{botId}/attachments/{fileId})で認証エラーが発生する。
詳細
LINE WORKSのAPIを用いてBotのトークから送信されたファイルを他のサービスに展開するために
上記APIアクセス時に認証失敗が返ってきております。
確認済みの内容で複数の原因について調査しているのですが、原因が特定できていない状況です。
他に考えられる原因及びその対処方法についてご教授いただけないでしょうか。
実行構成
- 上記ソースをAWS Lambdaに配置しAPI GatewayのHTTPリクエストをトリガに実行する
- API GatewayのエンドポイントはCallback URLとして設定
- 必要な機密情報(秘密鍵等)はSecretManagerに配置
処理フロー
- Botからファイルを送信する
- API Gateway経由で受信したBodyからfileIdを抽出する。
- Service Accountでアクセストークンを発行する。
- 取得したアクセストークンを使用し、Bot経由でユーザにメールを送る(アクセストークンが使えるかどうかの判定向け)
- 取得したfileIdとアクセストークンを使用し、コンテンツダウンロードAPIを実行する。
エラー発生点
5. の処理でHTTP Status Code 401が返却される。
レスポンスBodyは以下の通り。
{
"code":"UNAUTHORIZED",
"description":"Authentication failed."
}
確認済みの内容
- コンテンツダウンロードで使用しているのと同じアクセストークンを用いたメッセージ送信は成功しており、トークン発行に使用するパラメータが間違っていることは考えにくい。
- コンテンツダウンロードAPI使用時のヘッダは以下となっており、ドキュメントと比較しても問題ないように見える。
info_api_url = f"https://www.worksapis.com/v1.0/bots/{bot_id}/attachments/{file_id}"
headers = {'Authorization': f'Bearer {access_token}'}
try:
# まずファイル情報を取得
info_response = session.get(info_api_url, headers=headers, timeout=30)
- トークンのscopeについてもドキュメント通り設定されているように見える。
token_url = 'https://auth.worksmobile.com/oauth2/v2.0/token'
data = {
'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion': assertion,
'client_id': secrets['LINEWORKS_CLIENT_ID'],
'client_secret': secrets['LINEWORKS_CLIENT_SECRET'],
'scope': 'bot bot.message'
}
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
投稿に新しいコメントが追加されましたら通知を送信します。
コメント5
업데이트 된 답글입니다.
Ping
Scopes are correct as well.
Anyone here has found the solution?
Thanks
2025.07.09
업데이트 된 답글입니다.
Miya3838
【発生事象】
私も同様に、GET /bots/{botId}/attachments/{fileId} の呼び出しで 401 Unauthorized を受け取っています。
トークンのスコープに bot bot.message や他のすべてを付与しているため、
認証周りの設定ミスとは考えにくい状態です。
ただし、レスポンス(401)の中に含まれていた response.RequestMessage.RequestUri.AbsoluteUri には、
ファイルURLが含まれており、
こちらのURLに対してはそのまま HttpClient での GETによってファイルのダウンロードが可能でした。
【試したこと】
・bot bot.message を含むすべてのスコープを検証
・同一トークンによるメッセージ送信は正常に成功
・GET /bots/{botId}/attachments/{fileId} に対しては常に 401
ただし、レスポンスの中に https://apis-storage.worksmobile.com/k/emsg/r/・・・ のようなURLがあり、
それを使えば直接ダウンロード可能
【現時点での仮説】
このAPIに対する 401は、ファイルそのものではなく、APIそのものへの認可エラーだと解釈しています
サポートにも問い合わせ済みですが、APIはサポート対象外との回答を受けました
【現在の回避策】
C#ですとこんな感じ
var client = new HttpClient();
var stream = await client.GetStreamAsync(limitedPublicUrl); // response.RequestMessage.RequestUri.AbsoluteUri
には、ファイルへのURLが入っていました。
そして、このURLからファイルを落とすことは可能でした。
Pythonにはこのプロパティがないので
info_response.text の中に https:// 形式のURLが含まれていないかを確認し、それを使ってアクセスするのが有効かもしれません。
I have encountered the same issue and was able to implement a temporary workaround.
[Issue Observed]
I also receive a 401 Unauthorized response when calling GET /bots/{botId}/attachments/{fileId}.
Since I've included bot bot.message and all other scopes, I believe it's unlikely that the error is due to incorrect authentication setup.
However, I noticed that the 401 response included a URL in response.RequestMessage.RequestUri.AbsoluteUri,
and this URL (e.g., https://apis-storage.worksmobile.com/k/emsg/r/...) could be used directly to download the file via a simple HTTP GET using HttpClient.
[What I’ve Tried]
Verified all possible scopes, including bot bot.message
Confirmed that sending messages with the same token works successfully
Still receiving 401 for GET /bots/{botId}/attachments/{fileId}
But found a file URL embedded in the response which allows direct download
[Current Hypothesis]
My assumption is that the 401 is not about access to the file itself,
but rather an authorization error specific to the API endpoint.
I contacted LINE WORKS support, but was told that this API is outside of their support scope.
[Current Workaround]
In C#, I was able to download the file like this:
var client = new HttpClient();
var stream = await client.GetStreamAsync(limitedPublicUrl); // From response.RequestMessage.RequestUri.AbsoluteUri
Since Python does not expose RequestMessage.RequestUri.AbsoluteUri,
you may want to check whether info_response.text contains a downloadable https://... style URL,
and then use that URL directly.
2025.07.15
업데이트 된 답글입니다.
tetsu_636582 投稿者
ご回答ありがとうございます。
> Pythonにはこのプロパティがないので
> info_response.text の中に https:// 形式のURLが含まれていないかを確認し、それを使ってアクセスするのが有効かもしれません
こちらはPythonでは取得できませんでした。
ですが、頂いた回答内容 と ファイルアップロードのレスポンスで定義されている
uploadUrl(https://developers.worksmobile.com/jp/docs/bot-attachment-create#Response-Example)を参考に、
ファイルIDからダウンロードURIを生成し、ファイルダウンロードができるようになりました。
ありがとうございます。
例)
ファイルID : foo.bar.baz.qux.quux.quuux.quuuux.quuuux
ダウンロードURI:https://apis-storage.worksmobile.com/k/emsg/r/{foo}/{bar.baz.qux.quux.quuux.quuuux.quuuux}/
@Ping
I was able to download the file by generating the following download URI from the file ID.
Please give it a try.
ex.)
FileID : foo.bar.baz.qux.quux.quuux.quuuux.quuuux
DownloadURI:https://apis-storage.worksmobile.com/k/emsg/r/{foo}/{bar.baz.qux.quux.quuux.quuuux.quuuux}/
2025.07.16
업데이트 된 답글입니다.
Miya3838
ご返信ありがとうございます!
無事にダウンロードできたとのことで安心しました!
401の原因は結局ナゾのままですね…。APIの仕様を変えないでほしいです・・・
2025.07.16
업데이트 된 답글입니다.
Ping
[
{
"body": {
"code": "UNAUTHORIZED",
"description": "Authentication failed."
},
"headers": {
"date": "Wed, 16 Jul 2025 08:21:35 GMT",
"content-type": "application/json;charset=UTF-8",
"content-length": "67",
"connection": "close",
"server": "FileCloud",
"vary": "Origin"
},
"statusCode": 401,
"statusMessage": "Unauthorized"
}
]
Nothing else. :(
2025.07.16
まだ、解決できませんか?
今すぐ実際に使用しているLINE WORKSユーザーに質問してみましょう。