Beispiel #1
0
    def create_update(self, serializer, bot):
        try:
            user = caching.get_or_set(TelegramUser,
                                      serializer.data['message']['from']['id'])
        except TelegramUser.DoesNotExist:
            user, _ = TelegramUser.objects.get_or_create(
                **serializer.data['message']['from'])
        try:
            chat = caching.get_or_set(TelegramChat,
                                      serializer.data['message']['chat']['id'])
        except TelegramChat.DoesNotExist:
            chat, _ = TelegramChat.objects.get_or_create(
                **serializer.data['message']['chat'])

        if 'text' not in serializer.data['message']:
            raise OnlyTextMessages
        message, _ = TelegramMessage.objects.get_or_create(
            message_id=serializer.data['message']['message_id'],
            from_user=user,
            date=datetime.fromtimestamp(serializer.data['message']['date']),
            chat=chat,
            text=serializer.data['message']['text'])
        update, _ = TelegramUpdate.objects.get_or_create(
            bot=bot, update_id=serializer.data['update_id'], message=message)
        caching.set(update)
        return update
Beispiel #2
0
def handle_messenger_message(message_id, bot_id):
    try:
        message = caching.get_or_set(MessengerMessage, message_id)
        messenger_bot = caching.get_or_set(MessengerBot, bot_id)
    except MessengerMessage.DoesNotExist:
        logger.error("Message %s does not exists" % message_id)
    except MessengerBot.DoesNotExist:
        logger.error("Bot  %s does not exists or disabled" % bot_id)
    except:
        logger.error("Error handling update %s from bot %s" % (message_id, bot_id))
    else:
        try:
            messenger_bot.bot.handle_message(message, messenger_bot)
        except:           
            exc_info = sys.exc_info()
            traceback.print_exception(*exc_info)
            logger.error("Error processing %s for bot %s" % (message, messenger_bot))
        else:
            # Each update is only used once
            caching.delete(MessengerMessage, message)        
Beispiel #3
0
def handle_update(update_id, bot_id):
    try:
        update = caching.get_or_set(TelegramUpdate, update_id)
        telegram_bot = caching.get_or_set(TelegramBot, bot_id)
    except TelegramUpdate.DoesNotExist:
        logger.error("Update %s does not exists" % update_id)
    except TelegramBot.DoesNotExist:
        logger.error("Bot  %s does not exists or disabled" % bot_id)
    except:
        logger.error("Error handling update %s from bot %s" % (update_id, bot_id))
    else:
        try:
            telegram_bot.bot.handle_message(update, telegram_bot)
        except:           
            exc_info = sys.exc_info()
            traceback.print_exception(*exc_info)
            logger.error("Error processing %s for bot %s" % (update, telegram_bot))
        else:
            # Each update is only used once
            caching.delete(TelegramUpdate, update)
 def get(self, request, hook_id):
     """
     Verify token when configuring webhook from facebook dev.
     
     MessengerBot.id is used for verification
     """
     try:
         bot = caching.get_or_set(MessengerBot, hook_id)
     except MessengerBot.DoesNotExist:
         logger.warning("Hook id %s not associated to a bot" % hook_id)
         return Response(status=status.HTTP_404_NOT_FOUND)
     if request.query_params.get('hub.verify_token') == str(bot.id):
         return Response(int(request.query_params.get('hub.challenge')))
     return Response('Error, wrong validation token')
Beispiel #5
0
 def post(self, request, hook_id):
     """
     Process Kik webhook:
         1. Get an enabled Kik bot
         2. Verify Kik signature
         3. Serialize each message
         4. For each message create :class:`KikMessage <permabots.models.kik_api.KikMessage>` and :class:`KikUser <permabots.models.kik_api.KikUser>`
         5. Delay each message processing to a task      
         6. Response provider
     """
     try:
         bot = caching.get_or_set(KikBot, hook_id)
     except KikBot.DoesNotExist:
         logger.warning("Hook id %s not associated to a bot" % hook_id)
         return Response(status=status.HTTP_404_NOT_FOUND)
     signature = request.META.get('HTTP_X_KIK_SIGNATURE')
     if signature:
         signature.encode('utf-8')
     if not bot._bot.verify_signature(signature, request.stream.body):
         logger.debug("Kik Bot data %s not verified %s" % (request.data, signature))
         return Response(status=403)
     logger.debug("Kik Bot data %s verified" % (request.data))
     for kik_message in request.data['messages']:
         serializer = KikMessageSerializer(data=kik_message)   
         logger.debug("Kik message %s serialized" % (kik_message))
         if serializer.is_valid():            
             try:
                 if not self.accepted_types(serializer):
                     raise OnlyTextMessages
                 message = self.create_message(serializer, bot)
                 if bot.enabled:
                     logger.debug("Kik Bot %s attending request %s" % (bot, kik_message))
                     handle_message.delay(message.id, bot.id)
                 else:
                     logger.error("Message %s ignored by disabled bot %s" % (message, bot))
             except OnlyTextMessages:
                 logger.warning("Not text message %s for bot %s" % (kik_message, hook_id))
                 return Response(status=status.HTTP_200_OK)
             except:
                 exc_info = sys.exc_info()
                 traceback.print_exception(*exc_info)                
                 logger.error("Error processing %s for bot %s" % (kik_message, hook_id))
                 return Response(serializer.errors, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
                
         else:
             logger.error("Validation error: %s from kik message %s" % (serializer.errors, kik_message))
             return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
     return Response(serializer.data, status=status.HTTP_200_OK)
Beispiel #6
0
 def post(self, request, hook_id):
     """
     Process Telegram webhook.
         1. Serialize Telegram message
         2. Get an enabled Telegram bot
         3. Create :class:`Update <permabots.models.telegram_api.Update>`
         5. Delay processing to a task      
         6. Response provider
     """
     serializer = UpdateSerializer(data=request.data)
     if serializer.is_valid():
         try:
             bot = caching.get_or_set(TelegramBot, hook_id)
         except TelegramBot.DoesNotExist:
             logger.warning("Hook id %s not associated to an bot" % hook_id)
             return Response(serializer.errors,
                             status=status.HTTP_404_NOT_FOUND)
         try:
             update = self.create_update(serializer, bot)
             if bot.enabled:
                 logger.debug("Telegram Bot %s attending request %s" %
                              (bot.token, request.data))
                 handle_update.delay(update.id, bot.id)
             else:
                 logger.error("Update %s ignored by disabled bot %s" %
                              (update, bot.token))
         except OnlyTextMessages:
             logger.warning("Not text message %s for bot %s" %
                            (request.data, hook_id))
             return Response(status=status.HTTP_200_OK)
         except:
             exc_info = sys.exc_info()
             traceback.print_exception(*exc_info)
             logger.error("Error processing %s for bot %s" %
                          (request.data, hook_id))
             return Response(serializer.errors,
                             status=status.HTTP_500_INTERNAL_SERVER_ERROR)
         else:
             return Response(serializer.data, status=status.HTTP_200_OK)
     logger.error("Validation error: %s from message %s" %
                  (serializer.errors, request.data))
     return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
 def post(self, request, hook_id):
     """
     Process Messenger webhook.
         1. Get an enabled Messenger bot
         3. For each message serialize
         4. For each message create :class:`MessengerMessage <permabots.models.messenger_api.MessengerMessage>`
         5. Delay processing of each message to a task      
         6. Response provider
     """
     try:
         bot = caching.get_or_set(MessengerBot, hook_id)
     except MessengerBot.DoesNotExist:
         logger.warning("Hook id %s not associated to a bot" % hook_id)
         return Response(status=status.HTTP_404_NOT_FOUND)
     logger.debug("Messenger Bot %s attending request %s" %
                  (bot, request.data))
     webhook = Webhook.from_json(request.data)
     for webhook_entry in webhook.entries:
         for webhook_message in webhook_entry.messaging:
             try:
                 if webhook_message.is_delivery:
                     raise OnlyTextMessages
                 message = self.create_message(webhook_message, bot)
                 if bot.enabled:
                     logger.debug("Messenger Bot %s attending request %s" %
                                  (bot, message))
                     handle_messenger_message.delay(message.id, bot.id)
                 else:
                     logger.error("Message %s ignored by disabled bot %s" %
                                  (message, bot))
             except OnlyTextMessages:
                 logger.warning("Not text message %s for bot %s" %
                                (message, hook_id))
             except:
                 exc_info = sys.exc_info()
                 traceback.print_exception(*exc_info)
                 logger.error("Error processing %s for bot %s" %
                              (webhook_message, hook_id))
                 return Response(
                     status=status.HTTP_500_INTERNAL_SERVER_ERROR)
     return Response(status=status.HTTP_200_OK)
Beispiel #8
0
 def create_message(self, serializer, bot):
     sender = self.create_user(serializer.data['from'])
     try:
         chat = caching.get_or_set(KikChat, serializer.data['chatId'])
     except KikChat.DoesNotExist:
         chat, _ = KikChat.objects.get_or_create(id=serializer.data['chatId'])
         if 'participants' in serializer.data:
             for participant in serializer.data['participants']:
                 chat.participants.add(self.create_user(participant))                    
     if serializer.data['type'] == 'start-chatting':
         body = "/start"
     elif serializer.data['type'] == 'scan-data':
         body = "/start"
     else:
         body = serializer.data['body']
     message, _ = KikMessage.objects.get_or_create(message_id=serializer.data['id'],
                                                   from_user=sender,
                                                   timestamp=datetime.fromtimestamp(serializer.data['timestamp']),
                                                   chat=chat,
                                                   body=body)
     
     caching.set(message)
     return message
Beispiel #9
0
 def create_user(self, username):
     try:
         user = caching.get_or_set(KikUser, username)
     except KikUser.DoesNotExist:
         user, _ = KikUser.objects.get_or_create(username=username)
     return user
Beispiel #10
0
    def create_update(self, serializer, bot):
        if 'message' in serializer.data:
            try:
                user = caching.get_or_set(
                    TelegramUser, serializer.data['message']['from']['id'])
            except TelegramUser.DoesNotExist:
                user, _ = TelegramUser.objects.get_or_create(
                    **serializer.data['message']['from'])
            try:
                chat = caching.get_or_set(
                    TelegramChat, serializer.data['message']['chat']['id'])
            except TelegramChat.DoesNotExist:
                chat, _ = TelegramChat.objects.get_or_create(
                    **serializer.data['message']['chat'])

            if 'text' not in serializer.data['message']:
                raise OnlyTextMessages
            message, _ = TelegramMessage.objects.get_or_create(
                message_id=serializer.data['message']['message_id'],
                from_user=user,
                date=datetime.fromtimestamp(
                    serializer.data['message']['date']),
                chat=chat,
                text=serializer.data['message']['text'])
            update, _ = TelegramUpdate.objects.get_or_create(
                bot=bot,
                update_id=serializer.data['update_id'],
                message=message)

        elif 'callback_query' in serializer.data:
            # Message may be not present if it is very old
            if 'message' in serializer.data['callback_query']:
                try:
                    user = caching.get_or_set(
                        TelegramUser, serializer.data['callback_query']
                        ['message']['from']['id'])
                except TelegramUser.DoesNotExist:
                    user, _ = TelegramUser.objects.get_or_create(
                        **serializer.data['callback_query']['message']['from'])
                try:
                    chat = caching.get_or_set(
                        TelegramChat, serializer.data['callback_query']
                        ['message']['chat']['id'])
                except TelegramChat.DoesNotExist:
                    chat, _ = TelegramChat.objects.get_or_create(
                        **serializer.data['callback_query']['message']['chat'])

                message, _ = TelegramMessage.objects.get_or_create(
                    message_id=serializer.data['callback_query']['message']
                    ['message_id'],
                    from_user=user,
                    date=datetime.fromtimestamp(
                        serializer.data['callback_query']['message']['date']),
                    chat=chat,
                    text=serializer.data['callback_query']['message']['text'])
            else:
                message = None

            try:
                user = caching.get_or_set(
                    TelegramUser,
                    serializer.data['callback_query']['from']['id'])
            except TelegramUser.DoesNotExist:
                user, _ = TelegramUser.objects.get_or_create(
                    **serializer.data['callback_query']['from'])

            callback_query, _ = TelegramCallbackQuery.objects.get_or_create(
                callback_id=serializer.data['callback_query']['id'],
                from_user=user,
                message=message,
                data=serializer.data['callback_query']['data'])

            update, _ = TelegramUpdate.objects.get_or_create(
                bot=bot,
                update_id=serializer.data['update_id'],
                callback_query=callback_query)

        else:
            logger.error("Not valid message %s" % serializer.data)
            raise OnlyTextMessages
        caching.set(update)
        return update