def set_announcement_channel(self, message, new_channel): """!achannel: Sets the channel announcements will be sent to. `!achannel #channel`""" if new_channel: try: new_channel = new_channel.split('|')[1] except Exception as e: print(type(e)) finally: new_channel_name = new_channel.strip('# >') print("NEW CHANNEL IS : %s" % new_channel) self.save('announcement_channel', new_channel_name) attachment = msg_attachment.SlackAttachment( fallback="Announcement channel changed to %s" % new_channel_name, text="Announcement channel changed to %s" % announcements.get_slack_channel_link( self, new_channel_name)) else: channel = self.load('announcement_channel') attachment = msg_attachment.SlackAttachment( fallback="Current announcement channel is %s" % channel, text="Current announcement channel is %s" % announcements.get_slack_channel_link(self, new_channel=channel)) self.reply("", attachments=attachment.slack())
def build(x): got_address = "" pcoaddress = "https://people.planningcenteronline.com/people/" + x.id if x.nickname: name = " ".join([x.first_name, '"' + x.nickname + '"', x.last_name]) else: name = x.name try: for address in x.rel.addresses.list(): address = { 'name': name, 'location': address.location, 'street': address.street, 'city': address.city, 'state': address.state, 'zip': address.zip } got_address = "\n".join([ got_address, address["name" ""], address["location" ""], address["street" ""], " ".join([ address["city" ""], address["state" ""], address["zip" ""] ]) ]) google_address = "+".join([ "https://www.google.com/maps/dir/?api=1&destination=", address["street" ""].replace(" ", "+"), address["city" ""].replace(" ", "+"), address["state" ""].replace(" ", "+"), address["zip" ""] ]) attachment = (msg_attachment.SlackAttachment( pco="people", text=got_address, button_text="Open in People", button_url=pcoaddress)) attachment.add_button(text="Google Maps", url=google_address) attachment_list.append(attachment) except TypeError: attachment_list.append( msg_attachment.SlackAttachment(pco="people", text="There's a problem with " + name + "'s address.", button_text="Open in People", button_url=pcoaddress)) finally: return
def get(song_title): arrangement_list = [] used_dates = [] arrangement = [] arrangement_str = "" try: for song in pco.services.songs.list(where={'title': song_title}): for arng in song.rel.arrangements.list(): if arng.sequence_short: sequence = ", ".join([x for x in arng.sequence_short]) else: sequence = "No sequence found." if arng.chord_chart_key: song_key = arng.chord_chart_key else: song_key = "No key set." arrangement_str = ("\n".join([ song.title, " ".join([arng.name + ':', song_key]), sequence ])) for used in song.rel.song_schedules.list( filter=['three_most_recent']): used_dates.append(used.plan_dates) used_dates.reverse() if used_dates: arrangement_str += "\nLast Used: \n" for rdates in used_dates: arrangement_str += rdates + "\n" else: arrangement_str += "\nNever Used." arrangement = msg_attachment.SlackAttachment( fallback="Open in Services", pco="services", text=arrangement_str) arrangement.add_button( text="Open in PCO", url=("https://services.planningcenteronline.com/songs/" + song.id)) arrangement_list.append(arrangement) arrangement = [] arrangement_str = "" used_dates = [] except UnboundLocalError: arrangement_str = " ".join([ "I couldn't find any song titled:", '"' + song_title + '"', "¯\_(ツ)_/¯" ]) arrangement = msg_attachment.SlackAttachment( fallback="Open in Services", pco="services", text=arrangement_str) finally: return arrangement_list
def get_apps(message): fl_name = { 'first_name': message.sender['source']['real_name'].split()[0], 'last_name': message.sender['source']['real_name'].split()[1] } app_list = "" pcoaddress = "" for x in pco.people.people.list(where=fl_name): pcoaddress = "https://people.planningcenteronline.com/people/" + x.id for apps in x.rel.apps.list(): app_list += "\n" + apps.name print(app_list) if app_list is "": print("else") pcoaddress = ( "https://people.planningcenteronline.com/people?q=" + "%20".join([fl_name['first_name' ''], fl_name['last_name' '']])) app_list = "Whoops! Something went wrong. I couldn't find your permissions." attachment = msg_attachment.SlackAttachment(fallback=app_list, text=app_list, button_text="Open in People", button_url=pcoaddress) return attachment
def team_is_scheduled(team_name): start_time = datetime.now() + timedelta(minutes=15) start_time = start_time.replace(second=0, microsecond=0, minute=round_to_nearest(start_time.minute)) start_time = start_time.astimezone().astimezone(pytz.utc) print(start_time) is_scheduled = False confirmed = [] for t in pco.services.teams.list(where={'name': team_name}, include='people'): for member in t.rel.people.list(): for plan_person in member.rel.plan_people.list(): for plan_time in plan_person.rel.plan_times.list(): starts_at = pytz.utc.localize( datetime.strptime(plan_time.starts_at, '%Y-%m-%dT%H:%M:%SZ')) starts_at = starts_at.replace(minute=round_to_nearest( start_time.minute), second=0) if starts_at == start_time: is_scheduled = True if plan_person.status in ('C', 'Confirmed'): confirmed.append(plan_person.name) confirmed_string = '' for name in confirmed: confirmed_string += '- {}\n'.format(name) message = 'The {} is scheduled to be on duty in 15 minutes!\nConfirmed team members:\n{}' \ .format(team_name, confirmed_string) return is_scheduled, [ msg_attachment.SlackAttachment(fallback=message, text=message) ]
def pco_address_lookup(self, message, pco_name): """!address | "address for" (name): tells you the street address of a certain user""" if authenticate.check_name(message): if authenticate.get(message, app): self.reply("I might have that address.") attachment = [] for x in address.get(pco_name): attachment += x.slack() if not attachment: attachment = msg_attachment.SlackAttachment( text="Sorry I don't have a address for " + pco_name, pco="people", button_text="Search People", button_url="https://people.planningcenteronline.com/" "people?q=" + pco_name.replace(" ", "%20")) print(attachment.slack()) self.say("", message=message, attachments=attachment.slack(), channel=wl_chan_id(self)) else: self.say("Here you go!", message=message, attachments=attachment, channel=wl_chan_id(self)) else: self.say( "Sorry but you don't have access to the People App. " "Please contact your administrator.", channel=wl_chan_id(self)) else: self.say( 'I could not authenticate you. Please make sure your "Full name" ' 'is in your Slack profile and matches your Planning Center Profile.', channel=wl_chan_id(self))
def pco_checkin_lookup(self, message, pco_name): """!checkin [name]: tells you the last time someone checked-in""" if authenticate.check_name(message): if authenticate.get(message, app): print("checkin request") self.reply("Let me check.") attachment = [] attachment_txt = "" for x in checkins.get(pco_name): attachment += x.slack() attachment_txt += x.txt() if not attachment: attachment = msg_attachment.SlackAttachment(text="Sorry I don't have a Check-in for " + pco_name, pco="check_ins", button_text="Search Check-ins", button_url="https://check-ins." "planningcenteronline.com/people?q=" + pco_name.replace(" ", "%20")) self.say("", message=message, attachments=attachment.slack(), channel=wl_chan_id(self)) else: self.say("Here you go!", message=message, attachments=attachment, channel=wl_chan_id(self)) else: self.say("Sorry but you don't have access to the Check-ins App. " "Please contact your administrator.", channel=wl_chan_id(self)) else: self.say('I could not authenticate you. Please make sure your "Full name ' 'is in your Slack profile and matches your Planning Center Profile.', channel=wl_chan_id(self))
def app_lookup(self, message, app): """!app: tells you which PCO apps you have permissions to""" print("This is what's in app: " + app) app = app.strip() if authenticate.check_name(message): if app: print("checking credentials") if authenticate.get(message, app): msg = "You have access to: " + app.title() attachment = msg_attachment.SlackAttachment(fallback=msg, pco=app, text=msg) self.reply("", message=message, attachments=attachment.slack()) else: self.reply( "Sorry but you don't have access to that Planning Center App. " "Please contact your administrator.") else: self.reply("Getting your permissions. . .", message=message) print("calling app_list") attachment = authenticate.get_apps(message) your_apps = attachment.slack() self.reply("Here are the apps you have access to: ", message=message, attachments=your_apps) else: self.reply( 'I could not authenticate you. Please make sure your "Full name"' ' is in your Slack profile and matches your Planning Center Profile.' )
def get(team): team = team.strip() print("Looking up the team: ", team) msg = "" if team: for t in pco.services.teams.list(where={'name': team}, include='people'): service = t.rel.service_type.get().id team_id = t.id msg += "*" + pco.services.service_types.get(service).name msg += " " + t.name + ":*" for id_number in t.rel.people.list(): msg += "\n" + " ".join([ pco.services.people.get(id_number.id).first_name, pco.services.people.get(id_number.id).last_name ]) attachment_list.append( msg_attachment.SlackAttachment(fallback=msg, pco='services', text=msg, button_text="Open in Services", button_url="/".join([ "https://services." "planningcenteronline.com/" "service_types", service, "teams", team_id, "positions" ]))) msg = "" else: print("else") msg = "*Planning Center Services Teams:*" for team in pco.services.teams.list(): msg += "\n" + team.name attachment_list.append( msg_attachment.SlackAttachment( fallback=msg, pco='services', text=msg, button_text="Open in Services", button_url="https://services.planning" "centeronline.com/teams")) # print("msg before assigning to attachment: ", msg) return attachment_list
def get_todays_birthdays(): msg = "*Today's Birthdays!*\n" today = datetime.datetime.today().strftime('%m-%d') for x in pco.people.people.list(): if today in str(x.birthdate): msg += "%s\n" % x.name attachment = msg_attachment.SlackAttachment(fallback=msg, text=msg) return attachment
def get_set_songs(set_date="sunday"): attachment_list = [] song_list = [] # Get the Order of Service of a date and return a formatted string ready to send back. # This only works for future dates since PCO API doesn't let us quarry plans by date. cal = parsedatetime.Calendar() set_date, parse_status = cal.parse(set_date) set_date = datetime.datetime(*set_date[:6]) # If you're running this on windows this needs to be: %#d rather than %-d set_date = set_date.strftime('%B %d, %Y') # linux set_date = strip_leading_zeros(set_date) msg = "Here's the details for this week's songs:\n" try: for site in pco.people.campuses.list(): print("Working on:", site.name) for serviceType in pco.services.service_types.list(): for plan in serviceType.rel.plans.list(filter=['future']): if set_date.lstrip('0') in plan.dates: for items in plan.rel.items.list(): if items.attributes['item_type' ''] == 'song': song_list.append(str(items.title)) for song_title in song_list: for song in pco.services.songs.list( where={'title': song_title}): for arng in song.rel.arrangements.list(): if arng.sequence_short: sequence = ", ".join( [x for x in arng.sequence_short]) else: sequence = "No sequence found." if arng.chord_chart_key: song_key = arng.chord_chart_key else: song_key = "No key set." msg = "\n".join([ "*" + song.title + "*", "Sequence: " + sequence, "Key: " + song_key, "" ]) attachment = msg_attachment.SlackAttachment( fallback=msg, pco='services', text=msg, button_text="Open in Services", button_url=( "https://services.planningcenteronline." "com/songs/" + song.id + "/arrangements/" + arng.id)) attachment_list.append(attachment) attachment = [] msg = "" print(msg) except Exception as e: print("Exception!") print(type(e)) finally: return attachment_list
def person_created(self, data): if announcements.announcement_is_enabled(self, announcement='new_person_created'): pcoaddress = "https://people.planningcenteronline.com/people/" + data['id'] attachment = msg_attachment.SlackAttachment("Lets all welcome %s!" % data['attributes']['name'], text="New Person added to Planning Center!\n" "Lets all welcome %s!" % data['attributes']['name'], button_text="Open in People", button_url=pcoaddress) self.say("", channel=announcements.announcement_channel(self), attachments=attachment.slack())
def get_team_notifications(will): watched_teams = team_notification_list(will) msg = 'Teams with schedule notifications turned on:\n' if len(watched_teams.keys()) == 0: msg = 'No teams have schedule notifications turned on.' else: for team in watched_teams: msg += '- *{}* in channel *{}*\n'.format(team, watched_teams[team]) print(msg) return [msg_attachment.SlackAttachment(fallback=msg, text=msg)]
def get_toggles(will): """Returns a string formated list of current announcement toggles""" announcement_toggles = will.load('announcement_toggles') toggle_msg = "\nCurrent Announcement Toggles:\n" for toggle, value in announcement_toggles.items(): toggle_msg += ": ".join([ toggle.replace("_", " ").title(), str(value).replace('False', 'Off').replace('True', 'On') + "\n" ]) toggle_attachment = msg_attachment.SlackAttachment(fallback=toggle_msg, text=toggle_msg) return toggle_attachment.slack()
def get(name): # Get the phone number of person(s) and return a formatted string ready to send back. phone_numbers = "" try: fl_name = {'first_name': name.split()[0], 'last_name': name.split()[1]} except IndexError: fl_name = {'first_name': name.split()[0]} finally: for x in pco.people.people.list(where=fl_name): pcoaddress = "https://people.planningcenteronline.com/people/" + x.id for pnumber in x.rel.phone_numbers.list(): if pnumber.number is None: attachment_list.append( msg_attachment.SlackAttachment( fallback=pcoaddress, text=" ".join([ "I can't find a number for ", x.name, "Maybe you could add it?" ]), button_url=pcoaddress, button_text="Open in People", pco="people")) number = {'name': x.name, 'phone': pnumber.number} attachment_list.append( msg_attachment.SlackAttachment( fallback=pcoaddress, text="\n".join([ phone_numbers, number["name" ""], number["phone" ""] ]), button_url=pcoaddress, button_text="Open in People", pco="people")) get_nickname(name) return attachment_list
def build(x): pcoaddress = "https://people.planningcenteronline.com/people/" + x.id if x.birthdate is None: return else: if x.nickname: nickname = '"' + x.nickname + '"' else: nickname = "" msg = " ".join([x.first_name, nickname, x.last_name, "\n" + x.birthdate]) attachment_list.append(msg_attachment.SlackAttachment( fallback=pcoaddress, text=msg, button_url=pcoaddress, button_text="Open in People", pco="people")) return
def acl_lookup(self, message, acl_list): """!acl: lists the users who can adminster this bot""" msg = "" attachment = [] acl_groups = get_acl_groups() for acl_grp in acl_groups: print(acl_grp) msg += "*" + acl + ":*\n" print(msg) for x in get_acl_members(acl): print(x) msg += x + ", " print(msg) msg += "\n" attachment = msg_attachment.SlackAttachment(text=msg) print(attachment.slack()) self.reply("Here are all the access control lists I have:", message=message, attachments=attachment.slack())
def get_nickname(name): fl_name = {'nickname': name} for x in pco.people.people.list(where=fl_name): pcoaddress = "https://people.planningcenteronline.com/people/" + x.id for email in x.rel.emails.list(): e_mail = { 'name': " ".join([x.first_name, '"' + x.nickname + '"', x.last_name]), 'email': email.address } attachment_list.append( msg_attachment.SlackAttachment( fallback=pcoaddress, text="\n".join([e_mail["name" ""], e_mail["email" ""]]), button_url=pcoaddress, button_text="Open in People", pco="people")) email = {} return
def pco_forms(self, message): """!forms: lists the forms available on people and provides a button to open it.""" if authenticate.check_name(message): if authenticate.get(message, app): self.reply("Looking up forms. . .") logging.info("looking up forms") attachment = [] for x in forms.get_forms(): logging.info(x.slack()) attachment += x.slack() if not attachment: attachment = msg_attachment.SlackAttachment( text="Sorry I couldn't find any forms", button_text="Search People", button_url="https://people.planningcenteronline.com/" "people/forms") print(attachment.slack()) self.say("", message=message, attachments=attachment.slack(), channel=wl_chan_id(self)) else: self.say("Here you go!", message=message, attachments=attachment, channel=wl_chan_id(self)) else: self.say( "Sorry but you don't have access to the People App. " "Please contact your administrator.", channel=wl_chan_id(self)) else: self.say( 'I could not authenticate you. Please make sure your "Full name" ' 'is in your Slack profile and matches your Planning Center Profile.', channel=wl_chan_id(self))
def get(name): # Get the phone number of person(s) and return a formatted string ready to send back. try: fl_name = {'first_name': name.split()[0], 'last_name': name.split()[1]} except IndexError: fl_name = {'first_name': name.split()[0]} finally: for x in pco.people.people.list(where=fl_name): pcoaddress = "https://people.planningcenteronline.com/people/" + x.id for email in x.rel.emails.list(): e_mail = {'name': x.name, 'email': email.address} attachment_list.append( msg_attachment.SlackAttachment( fallback=pcoaddress, text="\n".join([e_mail["name" ""], e_mail["email" ""]]), button_url=pcoaddress, button_text="Open in People", pco="people")) get_nickname(name) return attachment_list
def build(x): nickname = "" pco_id = x.id try: check_ins = pco.check_ins.people.list_by_url( 'https://api.planningcenteronline.com/check_ins/v2/people/' + pco_id + '/check_ins?order=-created_at') first_record = True for a in check_ins: while first_record: last_checkin = a.created_at last_checkin = datetime.datetime.strptime( last_checkin, '%Y-%m-%dT%H:%M:%SZ') last_checkin = last_checkin.strftime('%B %d, %Y') last_checkin = str(last_checkin) first_record = False if x.nickname: nickname = '"' + x.nickname + '"' else: nickname = "" pco_id = "AC" + pco_id if nickname: msg = " ".join([ "The last time", x.first_name, nickname, x.last_name, "checked in was:\n" + last_checkin ]) else: msg = " ".join([ "The last time", x.first_name, x.last_name, "checked in was:\n" + last_checkin ]) url = "/".join([ "https://check-ins.planningcenteronline.com/people", pco_id, "activity" ]) attachment_list.append( msg_attachment.SlackAttachment( fallback=msg, pco="check_ins", text=msg, button_text="Open in Check-ins", button_url=url)) except: pco_id = "AC" + pco_id if nickname: msg = " ".join([ "No check-ins found for:", x.first_name, nickname, x.last_name ]) else: msg = " ".join( ["No check-ins found for:", x.first_name, x.last_name]) url = "/".join([ "https://check-ins.planningcenteronline.com/people", pco_id, "activity" ]) attachment_list.append( msg_attachment.SlackAttachment(fallback=msg, pco="check_ins", text=msg, button_text="Open in Check-ins", button_url=url)) finally: return
def get(set_date="sunday"): attachment_list = [] # Get the Order of Service of a date and return a formatted string ready to send back. # This only works for future dates since PCO API doesn't let us quarry plans by date. # TODO PCO added ability to query plans by date cal = parsedatetime.Calendar() set_date, parse_status = cal.parse(set_date) set_date = datetime.datetime(*set_date[:6]) # If you're running this on windows this needs to be: %#d rather than %-d set_date = set_date.strftime('%B %d, %Y') # linux set_date = strip_leading_zeros(set_date) set_list = str(set_date) try: for site in pco.people.campuses.list(): print("Working on:", site.name) for serviceType in pco.services.service_types.list(): for plan in serviceType.rel.plans.list(filter=['future']): if set_date.lstrip('0') in plan.dates: for items in plan.rel.items.list(): # set_list = "\n".join([set_list, site.name]) if items.attributes['item_type' ''] == 'header': set_list = "\n".join( [set_list, "*" + str(items.title) + "*"]) elif items.attributes['item_type' ''] == 'song': set_list = "\n".join( [set_list, "• _" + str(items.title) + "_"]) else: set_list = "\n".join( [set_list, "• " + items.title]) if set_list == set_date: set_list = "Sorry, I couldn't find a plan for that date ¯\_(ツ)_/¯" if set_list is not set_date: attachment_list.append( msg_attachment.SlackAttachment( fallback=set_list, pco="services", text="\n".join([ site.name, serviceType.name, set_list ]), button_text="Open in Services", button_url="https://services." "planningcenteronline." "com/plans/" + plan.id)) set_list = "" except Exception as e: print(type(e)) for serviceType in pco.services.service_types.list(): for plan in serviceType.rel.plans.list(filter=['future']): if set_date.lstrip('0') in plan.dates: for items in plan.rel.items.list(): # set_list = "\n".join([set_list, site.name]) if items.attributes['item_type' ''] == 'header': set_list = "\n".join( [set_list, "*" + str(items.title) + "*"]) elif items.attributes['item_type' ''] == 'song': set_list = "\n".join( [set_list, "• _" + str(items.title) + "_"]) else: set_list = "\n".join( [set_list, "• " + items.title]) if set_list == set_date: set_list = "Sorry, I couldn't find a plan for that date ¯\_(ツ)_/¯" if set_list is not set_date: attachment_list.append( msg_attachment.SlackAttachment( fallback=set_list, pco="services", text="\n".join([serviceType.name, set_list]), button_text="Open in Services", button_url= "https://services.planningcenteronline." "com/plans/" + plan.id)) set_list = "" finally: return attachment_list
def get_for_date(team, date_expression): print('Looking up the team: ', team) cal = parsedatetime.Calendar() now = datetime.now().astimezone().astimezone(pytz.utc) now_hour, now_minute = now.hour, now.minute plan_date, parse_status = cal.parse(date_expression) plan_date = datetime(*plan_date[:6]).astimezone().astimezone(pytz.utc) is_specific = False start_time = datetime(month=plan_date.month, day=plan_date.day, year=plan_date.year) if date_expression != 'today' and (plan_date.hour != now_hour or plan_date.minute != now_minute): # parsedatetime by default creates a datetime matching the current hour and minute if not provided # is_specific is True if the parsed string contains a specific time, e.g. "Sunday at 9AM" is_specific = True start_time = datetime(month=plan_date.month, day=plan_date.day, year=plan_date.year, hour=plan_date.hour, minute=plan_date.minute) start_time = pytz.utc.localize(start_time) team_members = { 'confirmed': [], 'unconfirmed': [], } for t in pco.services.teams.list(where={'name': team}, include='people'): for member in t.rel.people.list(): for plan_person in member.rel.plan_people.list(): for plan_time in plan_person.rel.plan_times.list(): starts_at = pytz.utc.localize( datetime.strptime(plan_time.starts_at, '%Y-%m-%dT%H:%M:%SZ')) hour_format = starts_at.astimezone().strftime('%I:%M%p') if dates_match(starts_at, start_time, is_specific): if plan_person.status in ('C', 'Confirmed'): team_members['confirmed'].append( (plan_person, hour_format)) elif plan_person.status in ('U', 'Unconfirmed'): team_members['unconfirmed'].append( (plan_person, hour_format)) if is_specific: plan_date = plan_date.astimezone() # Convert to local timezone plan_date_format = plan_date.strftime('%m-%d-%Y at %I:%M%p') else: plan_date_format = plan_date.strftime('%m-%d-%Y') if len(team_members['confirmed']) + len(team_members['unconfirmed']) == 0: msg = "Could not find any team members scheduled for that date ({}).".format( plan_date_format) else: msg = '{} team members scheduled for *{}*:'.format( team.capitalize(), plan_date_format) for status in ['confirmed', 'unconfirmed']: msg += '\n\n{}:'.format(status.capitalize()) for plan_person_tuple in team_members[status]: msg += '\n- {} | {} '.format( plan_person_tuple[0].name, plan_person_tuple[0].team_position_name) if not is_specific: msg += '({})'.format(plan_person_tuple[1]) attachment_list.append( msg_attachment.SlackAttachment(fallback=msg, text=msg)) return attachment_list