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}")
示例#2
0
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
示例#3
0
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
示例#4
0
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))
示例#5
0
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'}
示例#6
0
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 ""
示例#7
0
    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()
示例#8
0
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)
示例#9
0
 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')
示例#11
0
    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
                }
            }],
        )
示例#12
0
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
示例#13
0
    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']}")
示例#14
0
    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')
示例#15
0
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.',
    )
示例#16
0
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
示例#19
0
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()
示例#20
0
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
示例#21
0
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'
示例#22
0
文件: app.py 项目: lkellar/website
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