mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-04-09 12:10:31 -07:00
Changelog fragment
This commit is contained in:
parent
d71a6e8fd4
commit
c0d8ffc444
2 changed files with 68 additions and 74 deletions
2
changelogs/fragments/slack.yml
Normal file
2
changelogs/fragments/slack.yml
Normal file
|
@ -0,0 +1,2 @@
|
|||
minor_changes:
|
||||
- Slack upload file - feature added support for uploading files to Slack (https://github.com/ansible-collections/community.general/pull/9472).
|
|
@ -148,7 +148,8 @@ options:
|
|||
type: dict
|
||||
description:
|
||||
- Specify details to upload a file to Slack. The file can include metadata such as an initial comment, alt text, snipped and title.
|
||||
- See Slack's file upload API for details at U(https://api.slack.com/methods/files.getUploadURLExternal) and U(https://api.slack.com/methods/files.completeUploadExternal).
|
||||
- See Slack's file upload API for details at U(https://api.slack.com/methods/files.getUploadURLExternal).
|
||||
- See Slack's file upload API for details at U(https://api.slack.com/methods/files.completeUploadExternal).
|
||||
suboptions:
|
||||
path:
|
||||
type: str
|
||||
|
@ -171,6 +172,10 @@ options:
|
|||
type: str
|
||||
description:
|
||||
- Optional title for the uploaded file.
|
||||
thread_ts:
|
||||
type: str
|
||||
description:
|
||||
- Optional timestamp of parent message to thread this message, see U(https://api.slack.com/docs/message-threading).
|
||||
"""
|
||||
|
||||
EXAMPLES = r"""
|
||||
|
@ -293,6 +298,7 @@ EXAMPLES = r"""
|
|||
alt_text: ''
|
||||
snippet_type: ''
|
||||
title: ''
|
||||
thread_ts: ''
|
||||
"""
|
||||
|
||||
import re
|
||||
|
@ -474,9 +480,10 @@ def do_notify_slack(module, domain, token, payload):
|
|||
else:
|
||||
return {'webhook': 'ok'}
|
||||
|
||||
|
||||
def get_channel_id(module, token, channel_name):
|
||||
url = SLACK_CONVERSATIONS_LIST_WEBAPI
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
headers = {"Authorization": "Bearer " + token}
|
||||
params = {
|
||||
"types": "public_channel,private_channel,mpim,im",
|
||||
"limit": 1000,
|
||||
|
@ -487,22 +494,22 @@ def get_channel_id(module, token, channel_name):
|
|||
if cursor:
|
||||
params["cursor"] = cursor
|
||||
query = urlencode(params)
|
||||
full_url = f"{url}?{query}"
|
||||
full_url = "%s?%s" % (url, query)
|
||||
response, info = fetch_url(module, full_url, headers=headers, method="GET")
|
||||
status = info.get("status")
|
||||
if status != 200:
|
||||
error_msg = info.get("msg", "Unknown error")
|
||||
module.fail_json(
|
||||
msg=f"Failed to retrieve channels: {error_msg} (HTTP {status})"
|
||||
msg="Failed to retrieve channels: %s (HTTP %s)" % (error_msg, status)
|
||||
)
|
||||
try:
|
||||
response_body = response.read().decode("utf-8") if response else ""
|
||||
data = json.loads(response_body)
|
||||
except json.JSONDecodeError as e:
|
||||
module.fail_json(msg=f"JSON decode error: {e}")
|
||||
except ValueError as e:
|
||||
module.fail_json(msg="JSON decode error: %s" % str(e))
|
||||
if not data.get("ok"):
|
||||
error = data.get("error", "Unknown error")
|
||||
module.fail_json(msg=f"Slack API error: {error}")
|
||||
module.fail_json(msg="Slack API error: %s" % error)
|
||||
channels = data.get("channels", [])
|
||||
for channel in channels:
|
||||
if channel.get("name") == channel_name:
|
||||
|
@ -511,52 +518,45 @@ def get_channel_id(module, token, channel_name):
|
|||
cursor = data.get("response_metadata", {}).get("next_cursor")
|
||||
if not cursor:
|
||||
break
|
||||
module.fail_json(msg=f"Channel named '{channel_name}' not found.")
|
||||
module.fail_json(msg="Channel named '%s' not found." % channel_name)
|
||||
|
||||
|
||||
def upload_file_to_slack(module, token, channel, file_upload):
|
||||
try:
|
||||
file_path = file_upload["path"]
|
||||
if not os.path.exists(file_path):
|
||||
module.fail_json(msg=f"File not found: {file_path}")
|
||||
module.fail_json(msg="File not found: %s" % file_path)
|
||||
# Step 1: Get upload URL
|
||||
url = SLACK_GET_UPLOAD_URL_EXTERNAL
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Authorization": "Bearer " + token,
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
}
|
||||
params = urlencode(
|
||||
{
|
||||
"filename": file_upload.get("filename", os.path.basename(file_path)),
|
||||
"length": os.path.getsize(file_path),
|
||||
**(
|
||||
{"alt_text": file_upload.get("alt_text")}
|
||||
if file_upload.get("alt_text")
|
||||
else {}
|
||||
),
|
||||
**(
|
||||
{"snippet_type": file_upload.get("snippet_type")}
|
||||
if file_upload.get("snippet_type")
|
||||
else {}
|
||||
),
|
||||
}
|
||||
)
|
||||
params = {
|
||||
"filename": file_upload.get("filename", os.path.basename(file_path)),
|
||||
"length": os.path.getsize(file_path),
|
||||
}
|
||||
if file_upload.get("alt_text"):
|
||||
params["alt_text"] = file_upload.get("alt_text")
|
||||
if file_upload.get("snippet_type"):
|
||||
params["snippet_type"] = file_upload.get("snippet_type")
|
||||
params = urlencode(params)
|
||||
response, info = fetch_url(
|
||||
module, f"{url}?{params}", headers=headers, method="GET"
|
||||
module, "%s?%s" % (url, params), headers=headers, method="GET"
|
||||
)
|
||||
if info["status"] != 200:
|
||||
module.fail_json(
|
||||
msg=f"Error retrieving upload URL: {info['msg']} (HTTP {info['status']})"
|
||||
msg="Error retrieving upload URL: %s (HTTP %s)" % (info['msg'], info['status'])
|
||||
)
|
||||
try:
|
||||
upload_url_data = json.load(response)
|
||||
except json.JSONDecodeError:
|
||||
except ValueError:
|
||||
module.fail_json(
|
||||
msg=f"The Slack API response is not valid JSON: {response.read()}"
|
||||
msg="The Slack API response is not valid JSON: %s" % response.read()
|
||||
)
|
||||
if not upload_url_data.get("ok"):
|
||||
module.fail_json(
|
||||
msg=f"Failed to retrieve upload URL: {upload_url_data.get('error')}"
|
||||
msg="Failed to retrieve upload URL: %s" % upload_url_data.get('error')
|
||||
)
|
||||
upload_url = upload_url_data["upload_url"]
|
||||
file_id = upload_url_data["file_id"]
|
||||
|
@ -573,39 +573,29 @@ def upload_file_to_slack(module, token, channel, file_upload):
|
|||
)
|
||||
if info["status"] != 200:
|
||||
module.fail_json(
|
||||
msg=f"Error during file upload: {info['msg']} (HTTP {info['status']})"
|
||||
msg="Error during file upload: %s (HTTP %s)" % (info['msg'], info['status'])
|
||||
)
|
||||
except FileNotFoundError:
|
||||
module.fail_json(msg=f"The file {file_path} is not found.")
|
||||
except IOError:
|
||||
module.fail_json(msg="The file %s is not found." % file_path)
|
||||
# Step 3: Complete upload
|
||||
complete_url = SLACK_COMPLETE_UPLOAD_EXTERNAL
|
||||
files_data = json.dumps(
|
||||
{
|
||||
"files": [
|
||||
{
|
||||
"id": file_id,
|
||||
**(
|
||||
{"title": file_upload.get("title")}
|
||||
if file_upload.get("title")
|
||||
else {}
|
||||
),
|
||||
}
|
||||
],
|
||||
**(
|
||||
{"initial_comment": file_upload.get("initial_comment")}
|
||||
if file_upload.get("initial_comment")
|
||||
else {}
|
||||
),
|
||||
**(
|
||||
{"thread_ts": file_upload.get("thread_ts")}
|
||||
if file_upload.get("thread_ts")
|
||||
else {}
|
||||
),
|
||||
"channel_id": get_channel_id(module, token, channel),
|
||||
}
|
||||
)
|
||||
files_dict = {
|
||||
"files": [
|
||||
{
|
||||
"id": file_id,
|
||||
}
|
||||
],
|
||||
"channel_id": get_channel_id(module, token, channel),
|
||||
}
|
||||
if file_upload.get("title"):
|
||||
files_dict["files"][0]["title"] = file_upload.get("title")
|
||||
if file_upload.get("initial_comment"):
|
||||
files_dict["initial_comment"] = file_upload.get("initial_comment")
|
||||
if file_upload.get("thread_ts"):
|
||||
files_dict["thread_ts"] = file_upload.get("thread_ts")
|
||||
files_data = json.dumps(files_dict)
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Authorization": "Bearer " + token,
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
try:
|
||||
|
@ -614,18 +604,18 @@ def upload_file_to_slack(module, token, channel, file_upload):
|
|||
)
|
||||
if info["status"] != 200:
|
||||
module.fail_json(
|
||||
msg=f"Error during upload completion: {info['msg']} (HTTP {info['status']})"
|
||||
msg="Error during upload completion: %s (HTTP %s)" % (info['msg'], info['status'])
|
||||
)
|
||||
upload_url_data = json.load(response)
|
||||
except json.JSONDecodeError:
|
||||
except ValueError:
|
||||
module.fail_json(
|
||||
msg=f"The Slack API response is not valid JSON: {response.read()}"
|
||||
msg="The Slack API response is not valid JSON: %s" % response.read()
|
||||
)
|
||||
if not upload_url_data.get("ok"):
|
||||
module.fail_json(msg=f"Failed to complete the upload: {upload_url_data}")
|
||||
module.fail_json(msg="Failed to complete the upload: %s" % upload_url_data)
|
||||
return upload_url_data
|
||||
except Exception as e:
|
||||
module.fail_json(msg=f"Error uploading file: {str(e)}")
|
||||
module.fail_json(msg="Error uploading file: %s" % str(e))
|
||||
|
||||
|
||||
def main():
|
||||
|
@ -647,14 +637,16 @@ def main():
|
|||
blocks=dict(type='list', elements='dict'),
|
||||
message_id=dict(type='str'),
|
||||
prepend_hash=dict(type='str', choices=['always', 'never', 'auto']),
|
||||
upload_file=dict(type="dict", options=dict(
|
||||
path=dict(type="str", required=True),
|
||||
alt_text=dict(type="str"),
|
||||
snippet_type=dict(type="str"),
|
||||
initial_comment=dict(type="str"),
|
||||
thread_ts=dict(type="str"),
|
||||
title=dict(type="str")
|
||||
)
|
||||
upload_file=dict(
|
||||
type="dict",
|
||||
options=dict(
|
||||
path=dict(type="str", required=True),
|
||||
alt_text=dict(type="str"),
|
||||
snippet_type=dict(type="str"),
|
||||
initial_comment=dict(type="str"),
|
||||
thread_ts=dict(type="str"),
|
||||
title=dict(type="str"),
|
||||
)
|
||||
),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
|
@ -688,7 +680,7 @@ def main():
|
|||
upload_response=upload_response,
|
||||
)
|
||||
except Exception as e:
|
||||
module.fail_json(msg=f"Failed to upload file: {str(e)}")
|
||||
module.fail_json(msg="Failed to upload file: %s" % str(e))
|
||||
|
||||
if prepend_hash is None:
|
||||
module.deprecate(
|
||||
|
|
Loading…
Add table
Reference in a new issue