def restart(session, topic_id, other_user_id): """ Restart a stopped conversation. """ raise UnauthorizedException() # Disable for now. if session == None or topic_id == None or other_user_id == None: raise InvalidParametersException() sessionHandler.validate(session) user = sessionHandler.get_user(session) try: topic = Topic.objects.get(id=topic_id) except Topic.DoesNotExist: raise NoSuchTopicException() try: other_user = User.objects.get(id=other_user_id) except User.DoesNotExist: raise NoSuchUserException() conversation = conversationHandler.get(user.id, other_user.id, topic.id) conversationHandler.send_to_both_parties( conversation, settings.SMS_TEXT_CONVERSATION_RESTARTING) conversation.stopped = False conversation.save()
def handle_special_message(sender, recipient, topic, message_text): """ Handle a message that needs to be dealt with specially. The parameters are as follows: 'sender' The User who sent this SMS message. 'recipient' The other User in this conversation. 'topic' The Topic this conversation is about. 'message_text' The text of the message. When receiving a message, this function is called to see if it needs to be handled specially. Certain commands can be embedded within the message text, triggering specific actions within the MessageMe core. If the given message text contains a special message, that message is processed and we return True. Otherwise, we return False. """ if message_text.lower() == "stop": # Stop the associated conversation. conversation = conversationHandler.get(sender.id, recipient.id, topic.id) conversation.stopped = True conversation.save() conversationHandler.send_to_both_parties( conversation, settings.SMS_TEXT_CONVERSATION_ENDED) return True else: return False
def send_message(sender, recipient, topic, sender_name, message_text): """ Create and send a new message. The parameters are as follows: 'sender' The User object for the message's sender. 'recipient' The User object for the message's recipient. 'topic' The Topic object that this message is about. 'sender_name' The optional name for the sender of the message. 'message_text' The text of the message. We send the given message from the given sender to the given recipient, about the given topic. Note that we'll automatically create a conversation (and send an "intro" message") if one doesn't already exist. Upon completion, we return the newly-created Message object, or None if the conversation has been stopped. If the message recipient has reached their rate limit, we raise a RateLimitReachedException. """ logger.debug('in core.lib.messageHandler.send_mesage(' + 'sender=%s, recipient=%s, topic=%s, sender_name=%s, msg=%s)' % (repr(sender), repr(recipient), repr(topic), repr(sender_name), repr(message_text))) # Find the Conversation object to use for this message, creating it if # necessary. try: conversation = conversationHandler.get(sender.id, recipient.id, topic.id) except NoSuchConversationException: conversation = conversationHandler.start_conversation(sender.id, recipient.id, topic.id, sender_name) # If the conversation has been stopped, don't send out the message. if conversation.stopped: return None # See if we can send this message via SMS. We do this if the receipient # has a verified phone number. send_via_sms = False # initially. if recipient.phone_number not in ["", None] and recipient.verified: send_via_sms = True # Create the new Message object. message = Message() message.conversation = conversation message.sender = sender message.sender_name = sender_name message.body = message_text message.sent_via_sms = send_via_sms message.created_at = datetime.datetime.utcnow() message.updated_at = datetime.datetime.utcnow() message.save() # Send the message via PubNub. pubnub_gateway.send_notification(message) pubnub_gateway.send_message_to_firehose(message) # Send the message via Twilio, if we can. Note that we append the sender's # name (if any) to the outgoing SMS message. if send_via_sms: sending_phone_number = \ twilio_gateway.calc_sending_phone_number(conversation, recipient) if sender_name not in ["", None]: message_text = message_text + " [" + sender_name + "]" twilio_gateway.send_sms(sending_phone_number, recipient.phone_number, message_text) # Finally, return the newly-created message back to the caller. return message
def test_stop_and_restart(self): """ Test conversations/stop and conversations/restart. Note that this is combined into a single unit test because most of the complexity is in setting up the conversation -- it makes sense to test both at once so we don't have to set up the conversation twice. """ # Create two random users for testing. username_1 = utils.random_username() password_1 = utils.random_password() username_2 = utils.random_username() password_2 = utils.random_password() user_1_id = users.create(username=username_1, password=password_1, phone_number=PHONE_NUMBER)['id'] user_2_id = users.create(username=username_2, password=password_2, phone_number=PHONE_NUMBER_2)['id'] # Calculate a verification code for the two users. with self.settings(ENABLE_TWILIO=False): users.send_verification_code(phone_number=PHONE_NUMBER) users.send_verification_code(phone_number=PHONE_NUMBER_2) # Get the underlying User objects. user_1 = User.objects.get(id=user_1_id) user_2 = User.objects.get(id=user_2_id) # Open up two sessions, one for each user. Note that this also # verifies the users' phone numbers. session_1 = users.login(phone_number=PHONE_NUMBER, verification_code=user_1.verification_code) session_2 = users.login(phone_number=PHONE_NUMBER_2, verification_code=user_2.verification_code) # Get the default topic for user 1. We'll use this as the topic for # our conversation. topic_id = topics.list(session_1)[0]['id'] topic = Topic.objects.get(id=topic_id) # Send a message from user_2 to user_1 about the topic. This creates a # conversation between the two users. with self.settings(ENABLE_TWILIO=False, ENABLE_PUBNUB=False): messages.send(session_2, topic_id=topic.id, message="Hello") # Find the Conversation and make sure it isn't stopped. conversation = conversationHandler.get(user_1.id, user_2.id, topic.id) self.assertFalse(conversation.stopped) # Set up a signal listener to check that the "stopped" message is being # sent out via Twilio to both users. self.twilio_messages = [] def twilio_signal_handler(sender, **kwargs): self.twilio_messages.append(kwargs.get("message")) signals.twilio_sms_sent.connect(twilio_signal_handler) # Now try stopping the conversation. This should send an SMS to each # party. with self.settings(ENABLE_TWILIO=False, ENABLE_PUBNUB=False): conversations.stop(session_1, topic_id=topic.id, other_user_id=user_2.id) # Check that the conversation was stopped. conversation = conversationHandler.get(user_1.id, user_2.id, topic.id) self.assertTrue(conversation.stopped) # Check that the two SMS messages were sent. self.assertEqual(len(self.twilio_messages), 2) # Now try restarting the conversation. Once again, this should send # out an SMS message to each party. self.twilio_messages = [] with self.settings(ENABLE_TWILIO=False, ENABLE_PUBNUB=False): conversations.restart(session_1, topic_id=topic.id, other_user_id=user_2.id) # Check that the conversation was restarted. conversation = conversationHandler.get(user_1.id, user_2.id, topic.id) self.assertFalse(conversation.stopped) # Check that the two SMS messages were sent. self.assertEqual(len(self.twilio_messages), 2) # Finally, clean up. signals.twilio_sms_sent.disconnect(twilio_signal_handler)