def send_to_slack(token: str, channel: str, job_status: str): client = WebClient(token=token) blocks = [ { "type": "section", "text": { "type": "plain_text", "text": datetime.now( tz=timezone.utc).strftime("%a %b %d %Y %H:%M:%S %Z"), }, }, build_status_block( job_status, config.actor, config.job_id, config.branch, config.run_id, config.repository, ), ] try: result = client.chat_postMessage(channel=channel, text="Some text", blocks=blocks) # Print result, which includes information about the message (like TS) print(result) except SlackApiError as e: print(f"Error: {e}")
def load_channels(archived=False): """ Get a list of all the public channels in Slack :param archived: Boolean - Include archived channels :returns: Response object (Dictionary) """ if not settings.SLACK_TOKEN: return {'ok': False, 'error': 'config_error'} client = WebClient(token=settings.SLACK_TOKEN) try: response = client.conversations_list(exclude_archived=not archived) assert response['ok'] is True channels = [] for channel in response['channels']: channels.append((channel['id'], channel['name'])) return {'ok': True, 'channels': channels} except SlackApiError as e: assert e.response['ok'] is False return e.response
def upload(attachment, filename, title=None, message=None, channels=None): """ Upload a new file to Slack :param attachment: File path to the file :param filename: Filename with file extension (i.e. example.pdf) :param title: Title of the file to display in Slack :param message: The message text introducing the file in the specified ``channels`` :param channels: Comma-separated list of channel names or ids where the file should be posted (i.e. C1234567890) :returns: Response object (Dictionary) """ if not settings.SLACK_TOKEN: return {'ok': False, 'error': 'config_error'} client = WebClient(token=settings.SLACK_TOKEN) client.timeout = 600 try: if channels: response = client.files_upload(channels=channels, file=attachment, filename=filename, initial_comment=message, title=title) else: response = client.files_upload(file=attachment, filename=filename, title=title) assert response['ok'] is True return {'ok': True, 'file': response['file']} except SlackApiError as e: assert e.response['ok'] is False return e.response
def post_image_to_slack( slack_oath_token = '', file_name = '', channels = '#tmp-slack-webhook-testing-playground', comment = 'Here\'s my test file :smile:' ) : # Import WebClient from Python SDK (github.com/slackapi/python-slack-sdk) from slack_sdk import WebClient from slack_sdk.errors import SlackApiError # Request user password if not provided already if slack_oath_token == '' : slack_oath_token = getpass.getpass('Slack OAuth token:') # WebClient insantiates a client that can call API methods # When using Bolt, you can use either `app.client` or the `client` passed to listeners. client = WebClient(token=slack_oath_token) # The name of the file you're going to upload try: # Call the files.upload method using the WebClient # Uploading files requires the `files:write` scope client.files_upload( channels=channels, initial_comment=comment, file=file_name ) except SlackApiError as e: print("Error uploading file: {}".format(e))
def replace_message(channel, message_id, text=None, content=None): """ Replace an existing message in Slack. The message will need to have been published by the bot. The `text` parameter is not required when the `content` parameter is provided, however including it is still highly recommended. :param channel: The identifier of the Slack conversation the message was posted to :param message_id: The timestamp of the message to be updated :param text: Message text (Formatting: https://api.slack.com/reference/surfaces/formatting) :param content: List of valid blocks data (https://api.slack.com/block-kit) :return: Response object (Dictionary) """ if not settings.SLACK_TOKEN: return {'ok': False, 'error': 'config_error'} client = WebClient(token=settings.SLACK_TOKEN) if content or text: try: response = client.chat_update(channel=channel, ts=message_id, as_user=True, text=text, blocks=content, link_names=True) assert response['ok'] is True return {'ok': True, 'message': response['message']} except SlackApiError as e: assert e.response['ok'] is False return e.response else: return {'ok': False, 'error': 'no_text'}
def from_slack(request): if request.method != 'POST': return 'Only POST requests are accepted', 405 verify_signature(request) params_text = request.data.decode() params = params_text.split('&') param_dic = {} for param in params: param_tmp = param.split('=') param_dic[param_tmp[0]] = param_tmp[1] pub_dic = check_param(param_dic["text"]) if "err_msg" in pub_dic: return jsonify(format_slack_message(pub_dic["err_msg"])) res_text = "@" + param_dic["user_name"] \ + " Start your request ( " + pub_dic["command"] + " " + pub_dic["name"] + " )" client = WebClient(token=SLACK_TOKEN) response = client.chat_postMessage(link_names=1, channel=SLACK_CHANNEL, text=res_text) pub_dic["ts"] = response["ts"] pub_json = json.dumps(pub_dic) data = pub_json.encode() publisher.publish(topic_path, data=data) return ""
def __init__(self, slack_api_token, channel, message_prefix=None, filters=None): # type: (str, str, Optional[str], Optional[List[Callable[[Task], bool]]]) -> () """ Create a Slack Monitoring object. It will alert on any Task/Experiment that failed or completed :param slack_api_token: Slack bot API Token. Token should start with "xoxb-" :param channel: Name of the channel to post alerts to :param message_prefix: optional message prefix to add before any message posted For example: message_prefix="Hey <!here>," :param filters: An optional collection of callables that will be passed a Task object and return True/False if it should be filtered away """ super(SlackMonitor, self).__init__() self.channel = "{}".format(channel[1:] if channel[0] == "#" else channel) self.slack_client = WebClient(token=slack_api_token) self.min_num_iterations = 0 self.filters = filters or list() self.status_alerts = [ "failed", ] self.include_manual_experiments = False self.include_archived = False self.verbose = False self._channel_id = None self._message_prefix = "{} ".format( message_prefix) if message_prefix else "" self.check_credentials()
def img_to_slack(imagefile): token_file = os.path.join( os.path.dirname(get_ipython_module_path('BMM.functions')), 'image_uploader_token') try: with open(token_file, "r") as f: token = f.read().replace('\n', '') except: post_to_slack(f'failed to post image: {imagefile}') return () client = WebClient(token=token) #client = WebClient(token=os.environ['SLACK_API_TOKEN']) try: response = client.files_upload(channels='#beamtime', file=imagefile) assert response["file"] # the uploaded file except SlackApiError as e: post_to_slack('failed to post image: {imagefile}') # You will get a SlackApiError if "ok" is False assert e.response["ok"] is False assert e.response[ "error"] # str like 'invalid_auth', 'channel_not_found' print(f"Got an error: {e.response['error']}") except Exception as em: print("EXCEPTION: " + str(em)) report(f'failed to post image: {imagefile}', level='bold', slack=True)
def show_close_incident_modal(self, team_id, channel_id, trigger_id): """Show a slack modal with an input to add incident resolution text""" slack_access_token = DynamoUtils.get_slack_access_token(team_id) client = WebClient(token=slack_access_token) formatter = CloseIncidentFormatter() client.views_open(trigger_id=trigger_id, view=formatter.format(channel_id).get("view"))
def send_slack_report(env: str, suite: str): attachments = _generate_slack_attachments(env, suite) webhook_url = os.getenv('SLACK_TEST_REPORT_WEBHOOK_URL') slack_bot_token = os.getenv('SLACK_BOT_TOKEN') assert webhook_url, print( "SLACK_TEST_REPORT_WEBHOOK_URL env variable needs to be set") assert slack_bot_token, print( "SLACK_BOT_TOKEN env variable needs to be set") response = requests.post(url=webhook_url, data=json.dumps({"attachments": attachments}), headers={'Content-Type': 'application/json'}) assert response.status_code == 200, print( f"Response wasn't 200, it was {response}") print("Sent UI test statistics to #build") if _tests_failed(): client = WebClient(token=slack_bot_token) shutil.make_archive('UI-test-report', 'zip', PATH) try: client.files_upload( channels='#build', file='UI-test-report.zip', title='test-report.zip', ) except SlackApiError as e: print(f'Error uploading test report: {e}') os.remove('UI-test-report.zip') print('Sent UI test report to #build')
def custom_slack_on_pipeline_failure( context: PipelineFailureSensorContext): base_url = "http://localhost:3000" slack_client = WebClient( token=os.environ["SLACK_DAGSTER_ETL_BOT_TOKEN"]) run_page_url = f"{base_url}/instance/runs/{context.pipeline_run.run_id}" channel = "#yuhan-test" message = "\n".join([ f'Pipeline "{context.pipeline_run.pipeline_name}" failed.', f"error: {context.failure_event.message}", f"mode: {context.pipeline_run.mode}", f"run_page_url: {run_page_url}", ]) slack_client.chat_postMessage( channel=channel, blocks=[{ "type": "section", "text": { "type": "mrkdwn", "text": message } }], )
def main(): cfg = read_config() slack = WebClient(token=cfg['oauth_token']) plmw_channel_id = get_plmw_channel_id(slack) # set(id): Slack IDs for all members of #plmw plmw_channel_members = get_plmw_channel_members(slack, plmw_channel_id) # dict(email, id): All users on Slack all_slack_users = get_all_slack_users(slack) # set(email): People who should be on #plmw plmw_emails = set(read_plmw_emails(cfg['plmw_emails'])) # set(id): Slack IDs of people who should be on #plmw may_add_to_plmw = { all_slack_users[email] for email in plmw_emails if email in all_slack_users } # set(id): Slack IDs of people who are not on #plmw, but should be will_add_to_plmw = may_add_to_plmw - plmw_channel_members # Sanity check if len(will_add_to_plmw) > 0: print("Email addresses of people we are going to add:") all_slack_users_inv = {v: k for k, v in all_slack_users.items()} for id in will_add_to_plmw: print(all_slack_users_inv[id]) else: print("Nobody to add") return if len(sys.argv) == 2 and sys.argv[1] == "side-effect": slack.conversations_invite(channel=plmw_channel_id, users=','.join(will_add_to_plmw)) else: print("Use ./plmwbot.py side-effect to actually add these people") return
def send_slack_alert(self, metric_value): if self.condition is None: return if self.channels is None: return if self.message is None: return token = os.environ.get("WHALE_SLACK_TOKEN") if not token: LOGGER.warning("Could not find environment variable WHALE_SLACK_TOKEN.") return if not self.evaluate_condition(metric_value): return client = WebClient(token=token) for channel in self.channels: try: # TODO: Think of a better Slack message than just the message indicated. response = client.chat_postMessage(channel=channel, text=self.message) assert response["message"]["text"] == self.message except SlackApiError as e: assert e.response["ok"] is False assert e.response["error"] LOGGER.warning(f"Got an error: {e.response['error']}")
def __init__(self): if not (os.getenv('SLACK_TOKEN') and os.getenv('SLACK_CHANNEL')): sys.stderr.write( f'deco_slack needs SLACK_TOKEN and SLACK_CHANNEL env.\n') self.client = WebClient(os.getenv('SLACK_TOKEN')) self.channel = os.getenv('SLACK_CHANNEL')
def my_slack_on_run_success(context: RunStatusSensorContext): slack_client = WebClient(token=os.environ["SLACK_DAGSTER_ETL_BOT_TOKEN"]) slack_client.chat_postMessage( channel="#alert-channel", message=f'Job "{context.pipeline_run.pipeline_name}" succeeded.', )
class SlackApp: def __init__(self, token, channel): self.token = token self.client = WebClient(token=token) self.channel = channel self.queue = [] def send(self, sendable: Sendable, ts=None): if isinstance(sendable, Message): response = self.client.chat_postMessage(channel=self.channel, text=sendable.text, thread_ts=ts) elif isinstance(sendable, File): response = self.client.files_upload( channels=self.channel, initial_comment=sendable.comment, file=sendable.path, thread_ts=ts, ) else: raise RuntimeError( f'Not supported sendable type: {type(sendable)}') assert response.status_code == 200, f'Failed to send a message to {self.channel}\n{response}' return response.data.get('ts')
def create_users_table(channel_name, channel_id, DATABASE_URL): ## read all user_ids bot_token = os.environ.get("SLACK_BOT_TOKEN") client = WebClient(token=bot_token) response = client.conversations_members(channel=channel_id) user_ids = response["members"][1:] # connect to database conn = psycopg2.connect(DATABASE_URL, sslmode='require') cur = conn.cursor() ## create table cur.execute( f"CREATE TABLE if not exists users_{channel_name} (user_id VARCHAR(20) PRIMARY KEY, participate INTEGER, virtual INTEGER)" ) ## insert each user into the table for user_id in user_ids: cur.execute( f"INSERT INTO users_{channel_name}(user_id, participate, virtual) VALUES (\'{user_id}\', 0, 0)" ) conn.commit() cur.close() conn.close()
def client_conversations_history(slack_token="", channel="", retrieve_messages_from=0 ): # WebClient insantiates a client that can call API methods # When using Bolt, you can use either `app.client` or the `client` passed to listeners. client = WebClient(token=slack_token) # Store conversation history conversation_history = [] # ID of the channel you want to send the message to channel_id = channel try: # Call the conversations.history method using the WebClient # conversations.history returns the first 100 messages by default # These results are paginated, see: https://api.slack.com/methods/conversations.history$pagination result = client.conversations_history(channel=channel_id, oldest=retrieve_messages_from) # Print results logging.info("{} messages found in {}".format(len(conversation_history), id)) return result except SlackApiError as e: logging.error("Error creating conversation: {}".format(e)) pass
async def events(event: EventCallback): if event.type == 'url_verification': # AppにRequest URLを登録した際に初回だけ送信されるURLの検証 # ref: https://api.slack.com/events/url_verification return JSONResponse({'challenge': event.challenge}) try: team_conf = TeamConf.get(event.team_id) except TeamConf.DoesNotExist: return Response(status_code=HTTPStatus.BAD_REQUEST) client = WebClient(team_conf.access_token) if event.event: if event.event.type == 'reaction_added': # 投稿にemojiでリアクションがあったイベントを処理する # ref: https://api.slack.com/events/reaction_added if event.event.reaction in team_conf.emoji_set: # リアクションのemojiが設定されている場合 if event.event.item: item = event.event.item url = client.chat_getPermalink( channel=item.channel, message_ts=item.ts).get('permalink') blocks = [ SectionBlock(text=MarkdownTextObject(text=f'<{url}>')), ActionsBlock(elements=[ ButtonElement(text='読んだ', action_id='mark_as_read', value='mark_as_read') ]) ] client.chat_postMessage(text=url, channel=event.event.user, unfurl_links=True, blocks=blocks) return Response()
def post_ephemeral(channel, text, user, username=None): """ Send an ephemeral message to a user in a channel. This message will only be visible to the target user. :param channel: The identifier of the Slack conversation to post to :param text: Message text (Formatting: https://api.slack.com/reference/surfaces/formatting) :param user: The identifier of the specified user :param username: Name displayed by the bot :return: Response object (Dictionary) """ if not settings.SLACK_TOKEN: return {'ok': False, 'error': 'config_error'} client = WebClient(token=settings.SLACK_TOKEN) try: response = client.chat_postEphemeral(channel=channel, text=text, user=user, username=username) assert response['ok'] is True return response except SlackApiError as e: assert e.response['ok'] is False return e.response
def sending_a_message(slack_token="", channel="", text="", thread_ts=""): """ ref https://slack.dev/python-slack-sdk/web/index.html#messaging :return: """ # slack_token = os.environ["SLACK_BOT_TOKEN"] client = WebClient(token=slack_token) try: if thread_ts == "": response = client.chat_postMessage( channel=channel, text=text ) else: response = client.chat_postMessage( channel=channel, thread_ts=thread_ts, text=text ) return response except SlackApiError as e: # You will get a SlackApiError if "ok" is False assert e.response["error"] # str like 'invalid_auth', 'channel_not_found'
def updateStatus(): if 'secret_token' not in config: return 'No Scrape Key in config.json Ъци', 501 if request.form.get('secret_token') != config['secret_token']: return 'Incorrect/Missing Scrape Key', 401 with open(path.join(current_dir, 'schedule.json'), 'r') as f: data = json.load(f) with open(path.join(current_dir, 'tokens.json'), 'r') as f: tokens = json.load(f) if 'user_token' not in tokens: return 'User token not found. Please install slack bot', 401 current_date = datetime.now(pytz.timezone("America/Chicago")) first = None while current_date.strftime("%Y-%m-%d") in data: if not first: first = data.index(current_date.strftime('%Y-%m-%d')) if (current_date + timedelta(days=1)).strftime('%Y-%m-%d') in data: current_date += timedelta(days=1) else: break expiry_time = current_date.replace(hour=17, minute=00, second=0).timestamp() if current_date.strftime('%Y-%m-%d') in data: client = WebClient(token=tokens['user_token']) days_left = len(data) - first client.users_profile_set(profile={"status_text":f"School ┬и {days_left} day{'s' if days_left != 1 else ''} left!", "status_emoji":":school:", "status_expiration":expiry_time}) return "Status Adjusted", 200 return "Status not adjusted", 200