diff --git a/openpype/modules/slack/manifest.yml b/openpype/modules/slack/manifest.yml index 37d4669903..7a65cc5915 100644 --- a/openpype/modules/slack/manifest.yml +++ b/openpype/modules/slack/manifest.yml @@ -15,8 +15,10 @@ oauth_config: scopes: bot: - chat:write + - chat:write.customize - chat:write.public - files:write + - channels:read settings: org_deploy_enabled: false socket_mode_enabled: false diff --git a/openpype/modules/slack/plugins/publish/integrate_slack_api.py b/openpype/modules/slack/plugins/publish/integrate_slack_api.py index cdc90a7a28..5d014382a3 100644 --- a/openpype/modules/slack/plugins/publish/integrate_slack_api.py +++ b/openpype/modules/slack/plugins/publish/integrate_slack_api.py @@ -2,8 +2,10 @@ import os import six import pyblish.api import copy +from datetime import datetime from openpype.lib.plugin_tools import prepare_template_data +from openpype.lib import OpenPypeMongoConnection class IntegrateSlackAPI(pyblish.api.InstancePlugin): @@ -33,6 +35,7 @@ class IntegrateSlackAPI(pyblish.api.InstancePlugin): message = self._get_filled_message(message_profile["message"], instance, review_path) + self.log.info("message:: {}".format(message)) if not message: return @@ -42,17 +45,32 @@ class IntegrateSlackAPI(pyblish.api.InstancePlugin): if message_profile["upload_review"] and review_path: publish_files.add(review_path) + project = instance.context.data["anatomyData"]["project"]["code"] for channel in message_profile["channels"]: if six.PY2: - self._python2_call(instance.data["slack_token"], - channel, - message, - publish_files) + msg_id, file_ids = \ + self._python2_call(instance.data["slack_token"], + channel, + message, + publish_files) else: - self._python3_call(instance.data["slack_token"], - channel, - message, - publish_files) + msg_id, file_ids = \ + self._python3_call(instance.data["slack_token"], + channel, + message, + publish_files) + + msg = { + "type": "slack", + "msg_id": msg_id, + "file_ids": file_ids, + "project": project, + "created_dt": datetime.now() + } + mongo_client = OpenPypeMongoConnection.get_mongo_client() + database_name = os.environ["OPENPYPE_DATABASE_NAME"] + dbcon = mongo_client[database_name]["notification_messages"] + dbcon.insert_one(msg) def _get_filled_message(self, message_templ, instance, review_path=None): """Use message_templ and data from instance to get message content. @@ -80,7 +98,7 @@ class IntegrateSlackAPI(pyblish.api.InstancePlugin): task_data = fill_data.get("task") for key, value in task_data.items(): fill_key = "task[{}]".format(key) - fill_pairs.append((fill_key , value)) + fill_pairs.append((fill_key, value)) fill_pairs.append(("task", task_data["name"])) self.log.debug("fill_pairs ::{}".format(fill_pairs)) @@ -121,23 +139,24 @@ class IntegrateSlackAPI(pyblish.api.InstancePlugin): break return published_path - def _python2_call(self, token, channel, message, - publish_files): + def _python2_call(self, token, channel, message, publish_files): from slackclient import SlackClient try: client = SlackClient(token) + attachment_str = "\n\n Attachment links: \n" + file_ids = [] for p_file in publish_files: - attachment_str = "\n\n Attachment links: \n" with open(p_file, 'rb') as pf: response = client.api_call( "files.upload", - channels=channel, file=pf, - title=os.path.basename(p_file), + channel=channel, + title=os.path.basename(p_file) ) attachment_str += "\n<{}|{}>".format( response["file"]["permalink"], os.path.basename(p_file)) + file_ids.append(response["file"]["id"]) if publish_files: message += attachment_str @@ -147,23 +166,24 @@ class IntegrateSlackAPI(pyblish.api.InstancePlugin): channel=channel, text=message ) - if response.get("error"): error_str = self._enrich_error(str(response.get("error")), channel) self.log.warning("Error happened: {}".format(error_str)) + else: + return response["ts"], file_ids except Exception as e: # You will get a SlackApiError if "ok" is False error_str = self._enrich_error(str(e), channel) self.log.warning("Error happened: {}".format(error_str)) - def _python3_call(self, token, channel, message, - publish_files): + def _python3_call(self, token, channel, message, publish_files): from slack_sdk import WebClient from slack_sdk.errors import SlackApiError try: client = WebClient(token=token) attachment_str = "\n\n Attachment links: \n" + file_ids = [] for published_file in publish_files: response = client.files_upload( file=published_file, @@ -171,14 +191,16 @@ class IntegrateSlackAPI(pyblish.api.InstancePlugin): attachment_str += "\n<{}|{}>".format( response["file"]["permalink"], os.path.basename(published_file)) + file_ids.append(response["file"]["id"]) if publish_files: message += attachment_str - _ = client.chat_postMessage( + response = client.chat_postMessage( channel=channel, text=message ) + return response.data["ts"], file_ids except SlackApiError as e: # You will get a SlackApiError if "ok" is False error_str = self._enrich_error(str(e.response["error"]), channel) diff --git a/openpype/modules/slack/resources/openpype_icon.png b/openpype/modules/slack/resources/openpype_icon.png new file mode 100644 index 0000000000..bb38dcf577 Binary files /dev/null and b/openpype/modules/slack/resources/openpype_icon.png differ diff --git a/website/docs/module_slack.md b/website/docs/module_slack.md index d74ff3a290..02676d68a8 100644 --- a/website/docs/module_slack.md +++ b/website/docs/module_slack.md @@ -20,6 +20,12 @@ Slack application must be installed to company's Slack first. Please locate `openpype/modules/slack/manifest.yml` file in deployed OpenPype installation and follow instruction at https://api.slack.com/reference/manifests#using and follow "Creating apps with manifests". +### App icon + +If you would like to enrich bot with an icon, Slack admin must add the icon after app installation. + +Go to your Slack app home (something like https://api.slack.com/apps/XXXXXXXX/general?) > Basic information > Display Information. +You can upload any image you want, or for your convenience locate prepared OpenPype icon in your installed Openpype installation in `openpype\modules\slac\resources`. ## System Settings