-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbirthdaybot.py
executable file
·113 lines (90 loc) · 4.11 KB
/
birthdaybot.py
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
#!/usr/bin/env python3
import os
import ldap3
from ldap3 import Server, Connection, ALL_ATTRIBUTES, Tls, SASL, EXTERNAL, SUBTREE
import ssl
import requests
from icalendar import Calendar
import logging
from datetime import datetime
# Setup basic configuration for logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
def download_ics(ics_url):
logging.info(f"Downloading ICS file from {ics_url}")
response = requests.get(ics_url)
response.raise_for_status()
if 'text/calendar' not in response.headers.get('Content-Type', ''):
raise ValueError("Downloaded file is not an ICS file based on Content-Type header.")
return response.content
def get_events_for_date(ics_content, target_date):
logging.info(f"Parsing the ICS file for events on {target_date}")
calendar = Calendar.from_ical(ics_content)
target_date_events = []
for component in calendar.walk():
if component.name == "VEVENT":
event_start = component.get('dtstart').dt
event_start_date = event_start.date() if hasattr(event_start, 'date') else event_start
if event_start_date == target_date:
event_summary = component.get('summary')
if '-' in event_summary:
full_name = event_summary.split('-')[0].strip()
if verify_person_in_ldap(full_name):
message = f":birthday: Happy Birthday {full_name}! :tada:"
target_date_events.append(message)
return target_date_events
def verify_person_in_ldap(full_name):
ldap_server = os.getenv('LDAP_SERVER')
search_base = os.getenv('SEARCH_BASE')
first_last = full_name.replace(' ', '.').lower()
search_filter = f"(uid={first_last})"
# Specify the client certificates explicitly
tls_configuration = Tls(local_private_key_file='/app/certs/ldapcertificate.key',
local_certificate_file='/app/certs/ldapcertificate.crt',
validate=ssl.CERT_NONE) # Disabling certificate validation
server = Server(ldap_server, use_ssl=True, tls=tls_configuration)
try:
conn = Connection(server, authentication=SASL, sasl_mechanism=EXTERNAL, auto_bind=True)
conn.search(search_base, search_filter, search_scope=SUBTREE, attributes=ALL_ATTRIBUTES)
if conn.entries:
entry = conn.entries[0]
suspended = entry.suspended.value if 'suspended' in entry else 'unknown'
conn.unbind()
return suspended.lower() == 'false'
else:
logging.warning(f"No entries found for user {first_last}")
except Exception as e:
logging.error(f"LDAP operation failed: {e}")
finally:
if 'conn' in locals() and conn.bound:
conn.unbind()
return False
def parse_date(date_str):
try:
return datetime.strptime(date_str, "%Y-%m-%d").date()
except ValueError:
raise ValueError(f"Invalid date format: {date_str}. Please use YYYY-MM-DD format.")
def main():
target_date_str = os.getenv('TARGET_DATE')
target_date = parse_date(target_date_str) if target_date_str else datetime.now().date()
ics_url = os.getenv('ICS_URL')
if not ics_url:
raise ValueError("ICS URL not provided. Set the ICS_URL environment variable.")
webhook_url = os.getenv('WEBHOOK_URL')
if not webhook_url:
raise ValueError("Webhook URL not provided. Set the WEBHOOK_URL environment variable.")
ics_content = download_ics(ics_url)
target_date_events = get_events_for_date(ics_content, target_date)
if target_date_events:
post_to_slack(webhook_url, target_date_events)
else:
logging.info("No events found for the target date.")
def post_to_slack(webhook_url, messages):
for message in messages:
data = {"text": message}
response = requests.post(webhook_url, json=data)
response.raise_for_status()
logging.info(f"Posted message to Slack: {message}")
if __name__ == '__main__':
logging.info("Starting the script...")
main()
logging.info("Script execution completed.")