def is_correct_replier(self, bot, message): question_replier = QuestionReplier.get_by_message_id( self._session, message.id) # get repliers in this level filtered_question_repliers = [ x for x in question_replier.question.question_repliers if x.replier.level_id == question_replier.replier.level_id ] # set status to replying if message is sent without clicking the buttom # (has refused or still in knowledge validation) if all(x.reply_status_id == 1 or x.reply_status_id == 2 for x in filtered_question_repliers): self.set_status_for_repliers(filtered_question_repliers, question_replier) self._session.flush() if question_replier.reply_status_id != 3: slack_user_id = question_replier.message.slack_user_id replier = Replier.get_replier_by_slack_id(self._session, slack_user_id) channel_id = replier.channel_id if question_replier.reply_status_id == 6: bot.post_message(channel_id, GAVE_UP_RESPONDING_MESSAGE, question_replier.message.slack_message_id) else: bot.post_message(channel_id, ANOTHER_REPLIER_ANSWERING_QUESTION, question_replier.message.slack_message_id) return False # if question_replier.reply_status_id == 3 return True
def start_message(self, event): """Start the app, save continuos message, and scheduled a message that will activate 'forward_message' to send the question to everyone on level 1. """ user_level = Replier.get_replier_by_slack_id(self._session, event.user) # just users in level 1 can make questions if user_level.level_id > 1: event.bot.post_message(event.channel, BLOCK_LEVEL_QUESTIONS, event.message_id) return last_message = Message.get_last_message_of_user( self._session, event.user, 0) message = self.add_message_to_db(event.user, event.message_id, event.message_text) if last_message: # 0.5: threshold in minutes time_since_last_message = datetime.now() - datetime.strptime( last_message.date, '%d/%m/%Y, %H:%M:%S') if time_since_last_message.total_seconds() / 60 < 0.5: self.update_message_text(event.message_text, last_message, message) return timeout = self.get_suitable_timeout(start_message=True) # schedule the message that will allow the beggining of the conversation [forward_message] event.bot.schedule_message(event.channel, START_MESSAGE, timeout, message.slack_message_id) self.add_question_to_db(event.message_text, message) return
def forward_first_message(self, bot, message, replier_level_id, user_id): """Send question to users on first level. :type message: Message :type replier_level_id: int :type user_id: str :rtype: list[tuple[Replier, str]] """ repliers = Replier.get_repliers_by_level(self._session, replier_level_id) question_repliers = [] for replier in repliers: try: # avoid sending to the same user if replier.slack_id == user_id: continue response = bot.post_message(replier.channel_id, message) bot.post_message(replier.channel_id, WANT_ANSWER_QUESTION, response.message_id, ATTACHMENTS_knowledge_validation) question_repliers.append((replier, response.message_id)) except BaseException as error: # generally happens when the user have not installed the app functions_log( message="\nNome: {}\nSlack id: {}\nError: {}".format( replier.name, replier.slack_id, error), file_name="send_message_error") pass return question_repliers
def add_new_user_to_db(member_dict, channel_id): email = member_dict['profile'].get("email") new_replier = Replier(slack_id=member_dict["id"], name=member_dict["name"], email=email, channel_id=channel_id) # as we do not know yet which user is, we place them in level '1' and class 'limbo' new_replier.level_id = 1 new_replier.classe = "limbo" with session_scope() as session: session.add(new_replier) try: send_email(receiver_email=email,text_message=WELCOME_EXPERIA_EMAIL_TEXT, subject="ExperIA - Acesso Autorizado",filename='helpers/docs/ExperIA.pdf', receiver_id=member_dict["id"]) except: functions_log(message="It was not possible to send the email for user {}".format(member_dict["id"]), file_name="send_emails_log")
def get_user_info_to_reply(self, message): if message.is_replier_message: question_replier = QuestionReplier.get_by_message_id( self._session, message.id) user_id = question_replier.question.message.slack_user_id message_id = question_replier.question.message.slack_message_id question_replier_id = question_replier.id else: question = Question.get_question(self._session, message.id) user_id = question.message.slack_user_id message_id = question.message.slack_message_id question_replier_id = None replier = Replier.get_replier_by_slack_id(self._session, user_id) channel_id = replier.channel_id return channel_id, message_id, question_replier_id
def handle_home_event(event_data): """ Handle events when someone makes a click on Home Tab. Automate the storage of new users in the database. """ user_new_id = event_data['event']['user'] with session_scope() as session: user_replier = Replier.get_replier_by_slack_id(session,slack_id=user_new_id) # if the user is not in the database yet, create a temporary register if user_replier == None: user_replier = Replier(channel_id="none") # or, if the user's slack_id is empty if len(user_replier.channel_id) <= 4: client = WebClient(token=SLACK_BOT_OAUTH_ACCESS_TOKEN) channels = client.conversations_list(types="im")["channels"] users = slack_client.users_list() # get info of new user from user_list and conversations_list for memb_dict in users["members"]: if memb_dict["id"] == user_new_id: channel_id = next((channel["id"] for channel in channels if channel["user"] == memb_dict["id"]), None) if user_replier.channel_id == "none": # create a new register add_new_user_to_db(memb_dict, channel_id) else: # fill channel_id if missing user_replier.channel_id = channel_id with session_scope() as session: session.add(user_replier) # create and show the Home Tab's format and Jit's link for each user HOME_message['blocks'][-6]['elements'][0]['url'] = "https://meet.jit.si/ExperIA" + user_new_id slack_client.views_publish(user_id=user_new_id, view=HOME_message)
def forward_message(self, event, replier_level_id=MIN_LEVEL_ID): """Send the question to everyone on MIN_LEVEL_ID and save the info of any threads to database""" user = Replier.get_replier_by_channel_id(self._session, event.channel) message = Message.get_last_message_of_user(self._session, slack_user_id=user.slack_id, is_replier=False) question = Question.get_question(self._session, message_id=message.id) question_repliers = self.forward_first_message(event.bot, question.message_text, replier_level_id, user.slack_id) db_question_repliers = self.add_question_repliers_to_db( question, question_repliers) timeout = self.get_suitable_timeout() self.time_to_level_up(event.bot, db_question_repliers, timeout)
def go_to_next_level(self, event): """Prepares what is necessary to go up to the next level in 3 cases: 1. All users at some level ignore the question. 2. All users at some level reject to answer. 3. A replier stop answering. """ try: # case 1 message = Message.get_message_by_thread(self._session, event.thread_id) question_replier = QuestionReplier.get_by_message_id( self._session, message.id) except: try: # just for "action" on 'handle_knowledge_validation' and 'validation_keep_answering_or_not' (case 2 & 3) message = Message.get_message(self._session, event.message_id, event.slack_user_id) question_replier = QuestionReplier.get_by_message_id( self._session, message.id) except: return level_id = question_replier.replier.level_id next_level_id = ReplierLevel.get_next_lvl_id(self._session, level_id).next_level_id print("From level {} to {}. Number of Loop: {}".format( level_id, next_level_id, question_replier.question.number_of_loops)) question_repliers = question_replier.question.question_repliers question_date = question_replier.question.message_date question_level_id = question_replier.question.level # validate if we are on the right level if level_id == question_level_id: # update question's level on db question_replier.question.level += 1 # update status of repliers as "passou" for x in [ question_replier for question_replier in question_repliers if question_replier.reply_status_id == 1 ]: x.reply_status_id = 4 # if there are not more repliers already if all(question_replier.reply_status_id != 3 for question_replier in question_repliers): original_message = question_replier.question.message history_text = self.save_message_history(event.bot, question_replier.id, next_level=True) # we are going to the next loop if next_level_id == 1: print("Going to next loop...") question_replier.question.number_of_loops += 1 question_replier.question.level = 1 # reset the level # for more than 2 loops, send a message to monitors if question_replier.question.number_of_loops > 2: message_id_user = question_replier.question.message_id message_user = Message.get_message_by_id( self._session, message_id=message_id_user) user = Replier.get_replier_by_slack_id( self._session, slack_id=message_user.slack_user_id) send_email( '*****@*****.**', 'Dúvida do aluno: \n' + question_replier.question.message_text + '\n\n' + 'Informações do aluno: \n' + 'Slack_id: ' + user.slack_id + '\n' + 'E-mail: ' + user.email + '\n' + 'Data e hora: ' + question_date + '\n', 'Dúvida não respondida - ExperIA - ' + question_date) self.save_message_history(event.bot, question_replier.id) return new_question_repliers = self.forward_first_message( event.bot, history_text, next_level_id, original_message.slack_user_id) db_question_repliers = self.add_question_repliers_to_db( question_replier.question, new_question_repliers) self.time_to_level_up(event.bot, db_question_repliers) filtered_question_repliers = [x for x in question_repliers \ if x.replier.level_id == question_replier.replier.level_id and \ x.replier.id != question_replier.replier.id] for qr in filtered_question_repliers: event.bot.post_message(qr.replier.channel_id, M_EXPIRATION_TIME + ' ', qr.message.slack_message_id) event.bot.delete_message_in_history( qr.replier.channel_id, qr.message.slack_message_id, [WANT_ANSWER_QUESTION]) self._session.add_all(question_repliers)