Esempio n. 1
0
def message_resend(request, message_id):
    """
    Re-sends the given message
    """
    message = get_object_or_404(Message, pk=message_id)
    contact = message.contact

    if request.method == 'POST':
        form = ResendForm(request.POST)

        if form.is_valid():
            text = form.cleaned_data['text']
            number = contact.contactprofile.get_phone_number()

            connection = lookup_connections(settings.MODERATOR_BACKEND,
                                            [number])[0]
            receive(text, connection)

            messages.success(
                request,
                _("The message %(text)s was successfully resent") %
                {'text': unicode(text)})

            return HttpResponseRedirect(
                reverse("moderation.views.contact", args=(contact.pk, )))
    else:
        form = ResendForm(initial={'text': message.text})

    return render_to_response("message_resend.html", {
        'contact': contact,
        'message': message,
        'form': form,
    },
                              context_instance=RequestContext(request))
Esempio n. 2
0
def message_received(request, backend_name):
    """Handle HTTP requests from TextIt.
    """
    try:
        backend = settings.INSTALLED_BACKENDS[backend_name]
    except KeyError:
        logger.error('Name "{}" not found in settings INSTALLED_BACKENDS.'.format(backend_name))
        return HttpResponseBadRequest('Name "{}" not found in settings INSTALLED_BACKENDS.'.format(backend_name))
    try:
        if request.META['QUERY_STRING'] != backend['config']['query_key']:
            r = 'query_key "{}" does not match configured value from django settings "{}"'.format(
                    request.META['QUERY_STRING'], backend['config']['query_key'])
            logger.error(r)
            return HttpResponseBadRequest(r)
    except KeyError:
        logger.error("No query_key set up in settings INSTALLED_BACKENDS[backend_name]")
        return  HttpResponseBadRequest("No query_key set up in settings INSTALLED_BACKENDS[backend_name]")

    post = request.POST
    logger.debug("@@ request from TextIt - Decoded data: %r" % post)
    try:
        post_event = post['event']
    except KeyError:
        logger.error('No "Event" key in POST request')
        return HttpResponseBadRequest("No Event key in POST request")
    if post_event == 'mo_sms':
        # Must have received a message
        logger.debug("@@Got a text message")
        try:
            fa = post['phone']
            from_address = fa[1:] if fa.startswith('+') else fa  # strip off the plus sign
            text = post['text']
            logger.debug("@@Received message from %s: %s" % (from_address, text))
        except KeyError:
            logger.exception('Malformed POST message')
            return HttpResponseBadRequest("Malformed POST message")
        try:
            # get (or create) a connections object for this backend and from_address
            connections = lookup_connections(backend_name, [from_address])
        except Exception as e:
            r = "Error finding connection for backend_name={}, from={}, err={}".format(
                backend_name, from_address, e)
            logger.error(r)
            return HttpResponseServerError(r)
        try:
            # pass the message to RapidSMS
            receive(text, connections[0])
        except Exception as e:
            r = "Error receiving message. backend_name={}, from={}, err={}".format(
                backend_name, from_address, e)
            logger.error(r)
            return HttpResponseServerError(r)
        # Respond nicely to TextIt
        return HttpResponse("OK")
    # elif:
    if post_event in ['mt_sent', 'mt_dlvd']:
        return HttpResponse("thanks")  # confirmation messages are ignored
    # else:
    logger.error("@@No recognized command in request from TextIt")
    return HttpResponseBadRequest("Unexpected event code='{}'".format(post_event))
Esempio n. 3
0
    def test_outgoing(self):
        """Eager backends should call rapidsms_handle_message directly"""

        with patch('rapidsms.router.celery.tasks.rapidsms_handle_message') as mock_method:
            connections = self.lookup_connections(identities=['1112223333'])
            receive("test", connections[0])
        mock_method.assert_called_once()
Esempio n. 4
0
    def test_outgoing(self):
        """Eager backends should call rapidsms_handle_message directly"""

        with patch('rapidsms.router.celery.tasks.rapidsms_handle_message'
                   ) as mock_method:
            connections = self.lookup_connections(identities=['1112223333'])
            receive("test", connections[0])
        mock_method.assert_called_once()
Esempio n. 5
0
 def form_valid(self, form):
     """
     If the form validated successfully, passes the message on to the
     router for processing.
     """
     data = form.get_incoming_data()
     receive(**data)
     return HttpResponse('OK')
Esempio n. 6
0
def store_and_queue(identity, text):
    """Store a message in our log and send it into RapidSMS.

    :param identity: Phone number the message will appear to come from
    :param text: The message text
    """
    store_message(INCOMING, identity, text)
    connection = lookup_connections(BACKEND_NAME, [identity])[0]
    receive(text, connection)
Esempio n. 7
0
def store_and_queue(identity, text, to_addr=None):
    """Store a message in our log and send it into RapidSMS.

    :param identity: Phone number the message will appear to come from
    :param text: The message text
    :param to_addr: Phone number that the message is sent to
    """
    store_message(INCOMING, identity, text)
    connection = lookup_connections(BACKEND_NAME, [identity])[0]
    receive(text, connection, fields={"to_addr": to_addr, "from_addr": identity})
Esempio n. 8
0
def store_and_queue(backend_name, identity, text):
    """Store a message in our log and send it into RapidSMS.

    :param backend_name:
    :param identity: Phone number the message will appear to come from
    :param text: The message
    """
    from rapidsms.router import receive, lookup_connections
    store_message(HttpTesterMessage.INCOMING, identity, text)
    connection = lookup_connections(backend_name, [identity])[0]
    receive(text, connection)
Esempio n. 9
0
def send_message(request):
    form = forms.MessageForm(request.POST)

    if form.is_valid():
        cd = form.cleaned_data
        identity = cd["identity"]
        connection = lookup_connections("message_tester", [identity])[0]
        receive(cd["text"], connection)
        return {"success": True}
    else:
        return {"error": u"Parâmetros obrigatórios não encontrados"}
Esempio n. 10
0
def store_and_queue(identity, text, to_addr=None):
    """Store a message in our log and send it into RapidSMS.

    :param identity: Phone number the message will appear to come from
    :param text: The message text
    :param to_addr: Phone number that the message is sent to
    """
    store_message(INCOMING, identity, text)
    connection = lookup_connections(BACKEND_NAME, [identity])[0]
    receive(text,
            connection,
            fields={
                'to_addr': to_addr,
                'from_addr': identity
            })
Esempio n. 11
0
    def test_incoming(self):
        """Received messages should call _queue_message with incoming=True"""

        with patch.object(CeleryRouter, '_queue_message') as mock_method:
            connections = self.lookup_connections(identities=['1112223333'])
            message = receive("test", connections[0])
        mock_method.assert_called_once_with(message, incoming=True)
Esempio n. 12
0
    def test_incoming(self):
        """Received messages should call _queue_message with incoming=True"""

        with patch.object(CeleryRouter, '_queue_message') as mock_method:
            connections = self.lookup_connections(identities=['1112223333'])
            message = receive("test", connections[0])
        mock_method.assert_called_once_with(message, incoming=True)
Esempio n. 13
0
	def handle_message(self):
		event_kwargs = self.get_model_kwargs('from','message','timestamp')
		#fix variables for model 
		event_kwargs['sender'] = event_kwargs.pop('from')
		connection = lookup_connections('envaya', [event_kwargs['sender']])[0]
		msg_in = receive(event_kwargs['message'],connection)		
		return EnvayaOutgoingResponse()
Esempio n. 14
0
    def form_valid(self, form):
        """
        If the form validated successfully, passes the message on to the
        router for processing.
        """
        data = form.get_incoming_data()
        self.logger.debug("data that we got is %s" % data)

        if data['action'] == 'incoming':
            receive(text = data['text'], connection = data['connection'])
            self.logger.info("Incoming message forwarded to router successfully!")

        elif data['action'] == 'outgoing':
            self.logger.info("No outgoing message to forward to EnvayaSMS Android app!")

        return HttpResponse(json.dumps({'events': data['events']}), content_type='application/json')
Esempio n. 15
0
 def test_saved_message_fields_receive(self):
     """Extra data should persist through receive."""
     connection = self.create_connection()
     fields = {'extra-field': 'extra-value'}
     message = receive('test incoming message',
                       connection=connection, fields=fields)
     self.assertTrue('extra-field' in message.fields)
     self.assertEqual(message.fields['extra-field'], fields['extra-field'])
Esempio n. 16
0
 def form_valid(self, form):
     data = form.get_incoming_data()
     message = receive(**data)
     if hasattr(message, 'responses'):
         response_body = u' '.join([r['text'] for r in message.responses])
         return HttpResponse(response_body,
                             content_type='text/plain; charset=utf-8')
     return HttpResponse('')
Esempio n. 17
0
 def test_saved_message_fields_receive(self):
     """Extra data should persist through receive."""
     connection = self.create_connection()
     fields = {'extra-field': 'extra-value'}
     message = receive('test incoming message',
                       connection=connection,
                       fields=fields)
     self.assertTrue('extra-field' in message.fields)
     self.assertEqual(message.fields['extra-field'], fields['extra-field'])
Esempio n. 18
0
def send(message,i=0):
	connection = router.lookup_connections(BACKEND,[message['identity']])[0]
	msg_in = router.receive(message['message'],connection)
	msg_in.ccem_msg.created = message['date']
	msg_in.ccem_msg.save()
	
	msg_out = msg_in.connections[0].messages.all()[0]
	msg_out.created = message['date']+datetime.timedelta(seconds=10)
	msg_out.save()
	
	print 'Sent',i,':',message['message']
	return msg_in
Esempio n. 19
0
	def handle_message(self):
		event_kwargs = self.get_model_kwargs('from','message','timestamp')
		#fix variables for model 
		event_kwargs['sender'] = event_kwargs.pop('from')
		connection = lookup_connections('envaya', [event_kwargs['sender']])[0]
		msg_in = receive(event_kwargs['message'],connection)
		#send response via http call back
		events = [{'event':'send','messages':[],},]
		msgs_out = []
		for response in msg_in.responses:
			#msgs_out.append(send(**response)) #send is called when we process the msg, no need to call it again here
			events[0]['messages'].append({
				'to':response['connections'][0].identity,
				'message':response['text']
				})
		#models.SMS(**event_kwargs).save()
		logger.debug("Send Envaya:\n%s",json.dumps({'events':events}))
		return HttpResponse(json.dumps({'events':events}),mimetype='application/json')
Esempio n. 20
0
 def handle_message(self):
     event_kwargs = self.get_model_kwargs('from', 'message', 'timestamp')
     #fix variables for model
     event_kwargs['sender'] = event_kwargs.pop('from')
     connection = lookup_connections('envaya', [event_kwargs['sender']])[0]
     msg_in = receive(event_kwargs['message'], connection)
     #send response via http call back
     events = [
         {
             'event': 'send',
             'messages': [],
         },
     ]
     msgs_out = []
     for response in msg_in.responses:
         #msgs_out.append(send(**response)) #send is called when we process the msg, no need to call it again here
         events[0]['messages'].append({
             'to': response['connections'][0].identity,
             'message': response['text']
         })
     #models.SMS(**event_kwargs).save()
     logger.debug("Send Envaya:\n%s", json.dumps({'events': events}))
     return HttpResponse(json.dumps({'events': events}),
                         mimetype='application/json')
Esempio n. 21
0
def store_and_queue(backend_name, identity, text):
    from rapidsms.router import receive, lookup_connections
    store_message('in', identity, text)
    connection = lookup_connections(backend_name, [identity])[0]
    receive(text, connection)
Esempio n. 22
0
def receive_multimodem_message(request, server_slug):
    """
    The view to handle requests from multimodem has to be custom because the server can post 1-* messages in a single
    request. The Rapid built-in class-based views only accept a single message per form/post.

    TODO:
    Add basic auth to validate against Rapid's user database. The iSMS modem only supports basic auth.

    :param request:
    :return:
    """
    xml_data = request.POST.get('XMLDATA', '')
    """
    The modem posts the data as it receives it formatted as an xml file. The xml is then URL encoded and posted as a
    form parameter called XML data.

    Decoded Example:
    <?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>
    <Response>
        <Msg_Count>2</Msg_Count>
        <MessageNotification>
            <Message_Index>1</Message_Index>
            <ModemNumber>2:111222333</ModemNumber>
            <SenderNumber>+222333333</SenderNumber>
            <Date>15/04/13</Date>
            <Time>10:55:58</Time>
            <EncodingFlag>ASCII</EncodingFlag>
            <Message>Testn2</Message>
        </MessageNotification>
            <MessageNotification>
            <Message_Index>2</Message_Index>
            <ModemNumber>2:111222333</ModemNumber>
            <SenderNumber>+222333333</SenderNumber>
            <Date>15/04/13</Date>
            <Time>10:58:39</Time>
            <EncodingFlag>Unicode</EncodingFlag>
            <Message>0429043D043F0437043D043C0433043C0436043D043C</Message>
        </MessageNotification>
    </Response>
    """

    try:
        root = ET.fromstring(xml_data)
    except ET.ParseError:
        logger.error("Failed to parse XML")
        logger.error(request)
        return HttpResponseBadRequest('Error parsing XML')

    for message in root.findall('MessageNotification'):
        raw_text = message.find('Message').text
        from_number = message.find('ModemNumber').text

        # ModemNumber is simply 1 for single-port modems and it's a string of
        # 'port_numer:phone_number' for multiport modems.
        if ':' in from_number:
            modem_number, phone_number = from_number.split(':')[0:2]
        else:
            # This is a single port modem
            modem_number = from_number

        # Search through backends looking for the single one with this
        # server_slug / modem combo
        possible_backends = getattr(settings, 'INSTALLED_BACKENDS', {}).items()
        backend_names = [name for name, config in possible_backends
                         if str(config.get('modem_port')) == str(modem_number)
                         and config.get('server_slug') == server_slug]
        if backend_names:
            if len(backend_names) > 1:
                logger.error("More than 1 backend with this server/port combo: %s / %s",
                             server_slug, modem_number)
                return HttpResponseBadRequest('Improper Configuration: multiple backends with same server / port')
            backend_name = backend_names[0]
            encoding = message.find('EncodingFlag').text
            if encoding.lower() == "unicode":
                msg_text = ismsformat_to_unicode(raw_text)
            else:
                msg_text = raw_text

            connections = lookup_connections(backend_name, [message.find('SenderNumber').text])
            data = {'text': msg_text,
                    'connection': connections[0]}
            receive(**data)
        else:
            logger.error("Can't find backend for this server/port combo: %s / %s",
                         server_slug, modem_number)
            return HttpResponseBadRequest('Unknown server or port.')

    return HttpResponse('OK')
Esempio n. 23
0
 def sendMessage(self, num, txt, date=None):
     if date is None:
         date = datetime.now()
     connection = self.lookup_connections([num])[0]
     receive(txt, connection)
Esempio n. 24
0
def receive_multimodem_message(request, server_slug):
    """
    The view to handle requests from multimodem has to be custom because the server can post 1-* messages in a single
    request. The Rapid built-in class-based views only accept a single message per form/post.

    TODO:
    Add basic auth to validate against Rapid's user database. The iSMS modem only supports basic auth.

    :param request:
    :return:
    """
    xml_data = request.POST.get('XMLDATA', '')
    """
    The modem posts the data as it receives it formatted as an xml file. The xml is then URL encoded and posted as a
    form parameter called XML data.

    Decoded Example:
    <?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>
    <Response>
        <Msg_Count>2</Msg_Count>
        <MessageNotification>
            <Message_Index>1</Message_Index>
            <ModemNumber>2:111222333</ModemNumber>
            <SenderNumber>+222333333</SenderNumber>
            <Date>15/04/13</Date>
            <Time>10:55:58</Time>
            <EncodingFlag>ASCII</EncodingFlag>
            <Message>Testn2</Message>
        </MessageNotification>
            <MessageNotification>
            <Message_Index>2</Message_Index>
            <ModemNumber>2:111222333</ModemNumber>
            <SenderNumber>+222333333</SenderNumber>
            <Date>15/04/13</Date>
            <Time>10:58:39</Time>
            <EncodingFlag>Unicode</EncodingFlag>
            <Message>0429043D043F0437043D043C0433043C0436043D043C</Message>
        </MessageNotification>
    </Response>
    """

    try:
        root = ET.fromstring(xml_data)
    except ET.ParseError:
        logger.error("Failed to parse XML")
        logger.error(request)
        return HttpResponseBadRequest('Error parsing XML')

    for message in root.findall('MessageNotification'):
        raw_text = message.find('Message').text
        from_number = message.find('ModemNumber').text

        # ModemNumber is simply 1 for single-port modems and it's a string of
        # 'port_numer:phone_number' for multiport modems.
        if ':' in from_number:
            modem_number, phone_number = from_number.split(':')[0:2]
        else:
            # This is a single port modem
            modem_number = from_number

        # Search through backends looking for the single one with this
        # server_slug / modem combo
        possible_backends = getattr(settings, 'INSTALLED_BACKENDS', {}).items()
        backend_names = [
            name for name, config in possible_backends
            if str(config.get('modem_port')) == str(modem_number)
            and config.get('server_slug') == server_slug
        ]
        if backend_names:
            if len(backend_names) > 1:
                logger.error(
                    "More than 1 backend with this server/port combo: %s / %s",
                    server_slug, modem_number)
                return HttpResponseBadRequest(
                    'Improper Configuration: multiple backends with same server / port'
                )
            backend_name = backend_names[0]
            encoding = message.find('EncodingFlag').text
            if encoding.lower() == "unicode":
                msg_text = ismsformat_to_unicode(raw_text)
            else:
                msg_text = raw_text

            connections = lookup_connections(
                backend_name, [message.find('SenderNumber').text])
            data = {'text': msg_text, 'connection': connections[0]}
            receive(**data)
        else:
            logger.error(
                "Can't find backend for this server/port combo: %s / %s",
                server_slug, modem_number)
            return HttpResponseBadRequest('Unknown server or port.')

    return HttpResponse('OK')
Esempio n. 25
0
 def receive(self, text, connection, fields=None):
     """ A wrapper around the ``receive`` API. See :ref:`receiving-messages`."""
     return receive(text, connection, fields)
Esempio n. 26
0
 def receive(self, text, connection, fields=None):
     """receive() API wrapper."""
     return receive(text, connection, fields)
Esempio n. 27
0
def store_and_queue(backend_name, identity, text):
    from rapidsms.router import receive, lookup_connections
    store_message('in', identity, text)
    connection = lookup_connections(backend_name, [identity])[0]
    receive(text, connection)
Esempio n. 28
0
 def receive(self, text, connection, **kwargs):
     """
     A wrapper around the ``receive`` API. See :ref:`receiving-messages`.
     """
     return receive(text, connection, **kwargs)
Esempio n. 29
0
 def receive(self, text, connection, **kwargs):
     """
     A wrapper around the ``receive`` API. See :ref:`receiving-messages`.
     """
     return receive(text, connection, **kwargs)