-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsend_to_slack.py
More file actions
executable file
·137 lines (111 loc) · 4.85 KB
/
send_to_slack.py
File metadata and controls
executable file
·137 lines (111 loc) · 4.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/env python3
import argparse
import os
import re
import sys
import logging
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
from dotenv import load_dotenv
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def convert_markdown_to_slack(content):
logger.debug("Converting markdown to Slack format")
# Convert headers
content = re.sub(r'^# (.*)$', r'*:large_blue_diamond: \1*', content, flags=re.MULTILINE)
content = re.sub(r'^## (.*)$', r'*\1*', content, flags=re.MULTILINE)
content = re.sub(r'^### (.*)$', r'*\1*', content, flags=re.MULTILINE)
# Convert links [text](url) to <url|text>
content = re.sub(r'\[([^\]]+)\]\(([^)]+)\)', r'<\2|\1>', content)
# Convert bold **text** to *text*
content = re.sub(r'\*\*([^*]+)\*\*', r'*\1*', content)
# Convert italic *text* to _text_
content = re.sub(r'(?<!\*)\*([^*]+)\*(?!\*)', r'_\1_', content)
# Convert code blocks
content = re.sub(r'```([^`]+)```', r'```\1```', content)
# Convert inline code
content = re.sub(r'`([^`]+)`', r'`\1`', content)
# Convert lists - preserve indentation for multi-level lists
content = re.sub(r'^(\s*)[-*] ', r'\1- ', content, flags=re.MULTILINE)
return content
def read_file(file_path):
logger.info(f"Reading file: {file_path}")
try:
with open(file_path, 'r') as file:
content = file.read()
logger.debug(f"Successfully read {len(content)} characters from file")
return content
except FileNotFoundError:
logger.error(f"File '{file_path}' not found")
raise
except Exception as e:
logger.error(f"Error reading file: {e}")
raise
def extract_title_and_content(content):
"""Extract the title (first line starting with #) and the rest of the content"""
lines = content.split('\n')
title = None
rest_content = []
for line in lines:
if line.startswith('# ') and title is None:
title = line[2:].strip() # Remove the # and space
else:
rest_content.append(line)
return title, '\n'.join(rest_content)
def send_to_slack(client, content, channel, thread_ts=None):
logger.info("Preparing to send message to Slack")
try:
# Convert markdown to Slack formatting
logger.debug("Converting markdown to Slack format")
slack_content = convert_markdown_to_slack(content)
# Send message using Web API
response = client.chat_postMessage(
channel=channel,
text=slack_content,
thread_ts=thread_ts
)
logger.info("Successfully sent message to Slack!")
return response["ts"] # Return the message timestamp
except SlackApiError as e:
logger.error(f"Error sending message to Slack: {e.response['error']}")
raise
def main():
parser = argparse.ArgumentParser(description='Send team updates to Slack')
parser.add_argument('--input_file', required=True, help='Path to the input markdown file')
parser.add_argument('--channel', required=True, help='Slack channel to send message to')
parser.add_argument('--thread_ts', help='Thread timestamp to reply to an existing message')
parser.add_argument('--use_thread', action='store_true', help='Send title first, then rest in thread')
parser.add_argument('--debug', action='store_true', help='Enable debug logging')
args = parser.parse_args()
if args.debug:
logger.setLevel(logging.DEBUG)
logger.debug("Debug logging enabled")
# Initialize Slack client
slack_token = os.getenv('SLACK_BOT_TOKEN')
if not slack_token:
logger.error("SLACK_BOT_TOKEN environment variable is not set")
raise ValueError("SLACK_BOT_TOKEN environment variable is not set")
client = WebClient(token=slack_token)
content = read_file(args.input_file)
if args.use_thread:
# Extract title and rest of content
title, rest_content = extract_title_and_content(content)
if not title:
logger.error("No title found in markdown file (first line should start with #)")
raise ValueError("No title found in markdown file (first line should start with #)")
# Send title first
logger.info("Sending title message...")
thread_ts = send_to_slack(client, title, args.channel)
# Send rest of content in thread
logger.info("Sending rest of content in thread...")
send_to_slack(client, rest_content, args.channel, thread_ts)
else:
# Send entire content as one message
send_to_slack(client, content, args.channel, args.thread_ts)
if __name__ == '__main__':
load_dotenv() # Load .env file when script is run directly
main()