Beispiel #1
0
class Kik_Helper:
    def __init__(self, username, api_key):
        self.engine = Engine()
        self.username = username
        self.api_key = api_key
        self.kik = KikApi(username, api_key)

    def set_config(self, end_point, manually_send_read_receipts,
                   receive_read_receipts, receive_delivery_receipts,
                   receive_is_typing):
        requests.post('https://api.kik.com/v1/config',
                      auth=(self.username, self.api_key),
                      headers={'Content-Type': 'application/json'},
                      data=json.dumps({
                          "webhook": end_point,
                          "features": {
                              "manuallySendReadReceipts":
                              manually_send_read_receipts,
                              "receiveReadReceipts": receive_read_receipts,
                              "receiveDeliveryReceipts":
                              receive_delivery_receipts,
                              "receiveIsTyping": receive_is_typing
                          }
                      }))
        return Response(status=200)

    def check_config(self):
        config = self.kik.get_configuration()
        return config.webhook

    def send_messages(self, request):

        if not self.kik.verify_signature(
                request.headers.get('X-Kik-Signature'), request.get_data()):
            return Response(status=403)

        messages = messages_from_json(request.json['messages'])
        for message in messages:
            if isinstance(message, TextMessage):
                self.kik.send_messages(self.__choose_response(message))

        return Response(status=200)

    def __choose_response(self, message):
        messages = []
        response = self.engine.computeResponse(message.body)

        message = TextMessage(to=message.from_user,
                              chat_id=message.chat_id,
                              body=response)

        message.keyboards.append(
            SuggestedResponseKeyboard(hidden=False,
                                      responses=[TextResponse('OK')]))

        messages.append(message)

        return messages
Beispiel #2
0
class KikBotClient(FlaskRestBotClient):
    def __init__(self, argument_parser=None):
        FlaskRestBotClient.__init__(self, "kik", argument_parser)

        self.create_kik_bot()

        YLogger.debug(self, "Kik Client is running....")

    def get_client_configuration(self):
        return KikConfiguration()

    def get_license_keys(self):
        self._bot_api_key = self.license_keys.get_key("KIK_BOT_API_KEY")

    def create_kik_bot(self):
        self._kik_bot = KikApi(
            self.configuration.client_configuration.bot_name,
            self._bot_api_key)
        self._kik_bot.set_configuration(
            Configuration(
                webhook=self.configuration.client_configuration.webhook))

    def handle_text_message(self, message):
        question = message.body
        userid = message.from_user

        answer = self.ask_question(userid, question)

        self._kik_bot.send_messages([
            TextMessage(to=message.from_user,
                        chat_id=message.chat_id,
                        body=answer)
        ])

    def get_unknown_response(self, userid):
        if self.configuration.client_configuration.unknown_command_srai is None:
            unknown_response = self.configuration.client_configuration.unknown_command
        else:
            unknown_response = self.ask_question(
                userid,
                self.configuration.client_configuration.unknown_command_srai)
            if unknown_response is None or unknown_response == "":
                unknown_response = self.configuration.client_configuration.unknown_command
        return unknown_response

    def handle_unknown_message(self, message):
        userid = message.from_user

        unknown_response = self.get_unknown_response(userid)

        self._kik_bot.send_messages([
            TextMessage(to=message.from_user,
                        chat_id=message.chat_id,
                        body=unknown_response)
        ])

    def handle_message_request(self, request):

        messages = messages_from_json(request.json['messages'])

        for message in messages:
            if isinstance(message, TextMessage):
                self.handle_text_message(message)
            else:
                self.handle_unknown_message(message)

    def receive_message(self, request):

        if self.configuration.client_configuration.debug is True:
            self.dump_request(request)

        if not self._kik_bot.verify_signature(
                request.headers.get('X-Kik-Signature'), request.get_data()):
            return Response(status=403)

        self.handle_message_request(request)
        return Response(status=200)
Beispiel #3
0
class KikBotApiTest(TestCase):
    def setUp(self):
        super(KikBotApiTest, self).setUp()

        self.requests_mock = mock.patch('requests.api.request',
                                        wraps=requests_raise_func)
        self.requests_mock.start()

        self.api = KikApi('mybotusername', 'mybotapikey')

    def tearDown(self):
        super(KikBotApiTest, self).tearDown()

        self.requests_mock.stop()

    @mock.patch('requests.post',
                return_value=_response(200,
                                       json.dumps({}).encode('utf-8')))
    def test_send_messages(self, post):
        msgs = [TextMessage(to='aleem', body='Sometext')]

        response = self.api.send_messages(msgs)

        post_call = post.call_args
        self.assertEqual(post_call[0][0], 'https://api.kik.com/v1/message')
        self.assertEqual(post_call[1]['auth'],
                         ('mybotusername', 'mybotapikey'))
        self.assertEqual(post_call[1]['timeout'], 60)
        self.assertEqual(post_call[1]['headers'],
                         {'Content-Type': 'application/json'})
        self.assertEqual(json.loads(post_call[1]['data']), {
            'messages': [{
                'type': 'text',
                'to': 'aleem',
                'body': 'Sometext',
            }]
        })
        self.assertEqual(response, {})

    @mock.patch('requests.post',
                return_value=_response(200,
                                       json.dumps({}).encode('utf-8')))
    def test_broadcast_messages(self, post):
        msgs = [TextMessage(to='aleem', body='Sometext')]

        response = self.api.send_broadcast(msgs)

        post_call = post.call_args
        self.assertEqual(post_call[0][0], 'https://api.kik.com/v1/broadcast')
        self.assertEqual(post_call[1]['auth'],
                         ('mybotusername', 'mybotapikey'))
        self.assertEqual(post_call[1]['timeout'], 60)
        self.assertEqual(post_call[1]['headers'],
                         {'Content-Type': 'application/json'})
        self.assertEqual(json.loads(post_call[1]['data']), {
            'messages': [{
                'type': 'text',
                'to': 'aleem',
                'body': 'Sometext'
            }]
        })
        self.assertEqual(response, {})

    @mock.patch('requests.post',
                return_value=_response(
                    400,
                    json.dumps({
                        'error': 'BadRequest'
                    }).encode('utf-8')))
    def test_send_messages_failure(self, post):
        msgs = [TextMessage(to='aleem', body='Sometext')]

        self.assertRaises(KikError, self.api.send_messages, msgs)

    @mock.patch('requests.post',
                return_value=_response(
                    400,
                    json.dumps({
                        'error': 'BadRequest'
                    }).encode('utf-8')))
    def test_send_broadcast_failure(self, post):
        msgs = [TextMessage(to='aleem', body='Sometext')]

        self.assertRaises(KikError, self.api.send_broadcast, msgs)

    @mock.patch('requests.get',
                return_value=_response(
                    200,
                    json.dumps({
                        'firstName': 'First',
                        'lastName': 'Last',
                        'profilePicUrl': 'http://foo.bar/profile',
                        'profilePicLastModified': 1458657367
                    }).encode('utf-8')))
    def test_get_user_profile(self, get):
        user = self.api.get_user('aleem')

        get.assert_called_once_with('https://api.kik.com/v1/user/aleem',
                                    auth=('mybotusername', 'mybotapikey'),
                                    timeout=60)

        self.assertIsInstance(user, User)
        self.assertEqual(user.first_name, 'First')
        self.assertEqual(user.last_name, 'Last')
        self.assertEqual(user.profile_pic_url, 'http://foo.bar/profile')
        self.assertEqual(user.profile_pic_last_modified, 1458657367)

    @mock.patch('requests.get',
                return_value=_response(
                    400,
                    json.dumps({
                        'error': 'BadRequest'
                    }).encode('utf-8')))
    def test_get_user_profile_failure(self, get):
        self.assertRaises(KikError, self.api.get_user, 'aleem')

    @mock.patch('requests.post',
                return_value=_response(
                    200,
                    json.dumps({
                        'id': 'ba7a319394f912ccad1ac42770529bd5cb0e9783'
                    }).encode('utf-8')))
    def test_create_kik_code(self, post):
        code = self.api.create_code({'akey': 'avalue'})

        post.assert_called_once_with(
            'https://api.kik.com/v1/code',
            timeout=60,
            auth=('mybotusername', 'mybotapikey'),
            headers={'Content-Type': 'application/json'},
            data=json.dumps({'data': '{"akey": "avalue"}'}))

        self.assertIsInstance(code, Code)
        self.assertEqual(code.id, 'ba7a319394f912ccad1ac42770529bd5cb0e9783')

    @mock.patch('requests.post',
                return_value=_response(
                    200,
                    json.dumps({
                        'id': 'ba7a319394f912ccad1ac42770529bd5cb0e9783'
                    }).encode('utf-8')))
    def test_create_kik_code_no_data(self, post):
        code = self.api.create_code()

        post.assert_called_once_with(
            'https://api.kik.com/v1/code',
            timeout=60,
            auth=('mybotusername', 'mybotapikey'),
            headers={'Content-Type': 'application/json'},
            data='{}')

        self.assertIsInstance(code, Code)
        self.assertEqual(code.id, 'ba7a319394f912ccad1ac42770529bd5cb0e9783')

    @mock.patch('requests.post',
                return_value=_response(
                    400,
                    json.dumps({
                        'error': 'BadRequest'
                    }).encode('utf-8')))
    def test_create_kik_code_failure(self, post):
        self.assertRaises(KikError, self.api.create_code, {'akey': 'avalue'})

    @mock.patch('requests.get',
                return_value=_response(
                    200,
                    json.dumps({
                        'webhook': 'https://example.com/incoming',
                        'features': {
                            'manuallySendReadReceipts': True
                        }
                    }).encode('utf-8')))
    def test_get_configuration(self, get):
        config = self.api.get_configuration()

        get.assert_called_once_with('https://api.kik.com/v1/config',
                                    timeout=60,
                                    auth=('mybotusername', 'mybotapikey'))

        self.assertEqual(config.webhook, 'https://example.com/incoming')
        self.assertEqual(config.features, {'manuallySendReadReceipts': True})

    @mock.patch('requests.post',
                return_value=_response(200,
                                       json.dumps({}).encode('utf-8')))
    def test_set_configuration(self, post):
        config = Configuration(webhook='https://example.com/incoming',
                               features={'manuallySendReadReceipts': True})

        response = self.api.set_configuration(config)

        self.assertEqual(post.call_count, 1)
        self.assertEqual(post.call_args[0][0], 'https://api.kik.com/v1/config')
        self.assertEqual(post.call_args[1]['timeout'], 60)
        self.assertEqual(post.call_args[1]['auth'],
                         ('mybotusername', 'mybotapikey'))
        self.assertEqual(post.call_args[1]['headers'],
                         {'Content-Type': 'application/json'})
        self.assertEqual(
            json.loads(post.call_args[1]['data']), {
                'webhook': 'https://example.com/incoming',
                'features': {
                    'manuallySendReadReceipts': True
                }
            })

        self.assertEqual(response, {})
Beispiel #4
0
class KikBot(IntegrationBot):
    """
    Kik integration.
    
    Permabots sets webhook. Only requires api_key and username from Kik provider.
    
    Follow Kik instructons to create a bot and obtain username and api_key `<https://dev.kik.com/>`_.
    """
    api_key = models.CharField(_('Kik Bot API key'),
                               max_length=200,
                               db_index=True)
    username = models.CharField(_("Kik Bot User name"), max_length=200)

    class Meta:
        verbose_name = _('Kik Bot')
        verbose_name_plural = _('Kik Bots')

    def __init__(self, *args, **kwargs):
        super(KikBot, self).__init__(*args, **kwargs)
        self._bot = None
        if self.api_key and self.username:
            self.init_bot()

    def __str__(self):
        return "%s" % self.username

    def __repr__(self):
        return "(%s, %s)" % (self.username, self.api_key)

    def init_bot(self):
        self._bot = KikApi(self.username, self.api_key)

    def set_webhook(self, url):
        self._bot.set_configuration(Configuration(webhook=url))

    @property
    def hook_url(self):
        return 'permabots:kikbot'

    @property
    def hook_id(self):
        return str(self.id)

    @property
    def null_url(self):
        return "https://example.com"

    @property
    def identity(self):
        return 'kik'

    def message_text(self, message):
        return message.body

    def get_chat_state(self, message):
        try:
            return KikChatState.objects.select_related(
                'state', 'chat', 'user').get(chat=message.chat,
                                             user=message.from_user,
                                             state__bot=self.bot)
        except KikChatState.DoesNotExist:
            return None

    def build_keyboard(self, keyboard):
        def traverse(o, tree_types=(list, tuple)):
            if isinstance(o, tree_types):
                for value in o:
                    for subvalue in traverse(value, tree_types):
                        yield subvalue
            else:
                yield o

        built_keyboard = []
        if keyboard:
            built_keyboard = [
                TextResponse(element)
                for element in traverse(ast.literal_eval(keyboard))
            ][:20]
        return built_keyboard

    def create_chat_state(self, message, target_state, context):
        KikChatState.objects.create(chat=message.chat,
                                    user=message.from_user,
                                    state=target_state,
                                    ctx=context)

    def get_chat_id(self, message):
        return message.chat.id

    def send_message(self,
                     chat_id,
                     text,
                     keyboard,
                     reply_message=None,
                     user=None):
        if reply_message:
            to = reply_message.from_user.username
        if user:
            to = user
        texts = text.strip().split('\\n')
        msgs = []
        for txt in texts:
            for chunk in textwrap.wrap(txt, 100):
                msg = TextMessage(to=to, chat_id=chat_id, body=chunk)
                msgs.append(msg)
        if keyboard:
            msgs[-1].keyboards.append(
                SuggestedResponseKeyboard(to=to, responses=keyboard))
        try:
            logger.debug("Messages to send:(%s)" %
                         str([m.to_json() for m in msgs]))
            self._bot.send_messages(msgs)
            logger.debug("Message sent OK:(%s)" %
                         str([m.to_json() for m in msgs]))
        except:
            exctype, value = sys.exc_info()[:2]
            logger.error("Error trying to send message:(%s): %s:%s" %
                         (str([m.to_json() for m in msgs]), exctype, value))
Beispiel #5
0
class KikBotApiTest(TestCase):
    def setUp(self):
        super(KikBotApiTest, self).setUp()

        self.requests_mock = mock.patch('requests.api.request', wraps=requests_raise_func)
        self.requests_mock.start()

        self.api = KikApi('mybotusername', 'mybotapikey')

    def tearDown(self):
        super(KikBotApiTest, self).tearDown()

        self.requests_mock.stop()

    @mock.patch('requests.post', return_value=_response(200, json.dumps({}).encode('utf-8')))
    def test_send_messages(self, post):
        msgs = [TextMessage(to='aleem', body='Sometext')]

        response = self.api.send_messages(msgs)

        post_call = post.call_args
        self.assertEqual(post_call[0][0], 'https://api.kik.com/v1/message')
        self.assertEqual(post_call[1]['auth'], ('mybotusername', 'mybotapikey'))
        self.assertEqual(post_call[1]['timeout'], 60)
        self.assertEqual(post_call[1]['headers'], {'Content-Type': 'application/json'})
        self.assertEqual(json.loads(post_call[1]['data']), {
            'messages': [{
                'type': 'text',
                'to': 'aleem',
                'body': 'Sometext',
            }]
        })
        self.assertEqual(response, {})

    @mock.patch('requests.post', return_value=_response(200, json.dumps({}).encode('utf-8')))
    def test_broadcast_messages(self, post):
        msgs = [TextMessage(to='aleem', body='Sometext')]

        response = self.api.send_broadcast(msgs)

        post_call = post.call_args
        self.assertEqual(post_call[0][0], 'https://api.kik.com/v1/broadcast')
        self.assertEqual(post_call[1]['auth'], ('mybotusername', 'mybotapikey'))
        self.assertEqual(post_call[1]['timeout'], 60)
        self.assertEqual(post_call[1]['headers'], {'Content-Type': 'application/json'})
        self.assertEqual(json.loads(post_call[1]['data']), {
            'messages': [{
                'type': 'text',
                'to': 'aleem',
                'body': 'Sometext'
            }]
        })
        self.assertEqual(response, {})

    @mock.patch('requests.post', return_value=_response(400, json.dumps({'error': 'BadRequest'}).encode('utf-8')))
    def test_send_messages_failure(self, post):
        msgs = [TextMessage(to='aleem', body='Sometext')]

        self.assertRaises(KikError, self.api.send_messages, msgs)

    @mock.patch('requests.post', return_value=_response(400, json.dumps({'error': 'BadRequest'}).encode('utf-8')))
    def test_send_broadcast_failure(self, post):
        msgs = [TextMessage(to='aleem', body='Sometext')]

        self.assertRaises(KikError, self.api.send_broadcast, msgs)

    @mock.patch('requests.get', return_value=_response(200, json.dumps({
        'firstName': 'First',
        'lastName': 'Last',
        'profilePicUrl': 'http://foo.bar/profile',
        'profilePicLastModified': 1458657367
    }).encode('utf-8')))
    def test_get_user_profile(self, get):
        user = self.api.get_user('aleem')

        get.assert_called_once_with(
            'https://api.kik.com/v1/user/aleem',
            auth=('mybotusername', 'mybotapikey'),
            timeout=60
        )

        self.assertIsInstance(user, User)
        self.assertEqual(user.first_name, 'First')
        self.assertEqual(user.last_name, 'Last')
        self.assertEqual(user.profile_pic_url, 'http://foo.bar/profile')
        self.assertEqual(user.profile_pic_last_modified, 1458657367)

    @mock.patch('requests.get', return_value=_response(400, json.dumps({'error': 'BadRequest'}).encode('utf-8')))
    def test_get_user_profile_failure(self, get):
        self.assertRaises(KikError, self.api.get_user, 'aleem')

    @mock.patch('requests.post', return_value=_response(
        200, json.dumps({'id': 'ba7a319394f912ccad1ac42770529bd5cb0e9783'}).encode('utf-8')
    ))
    def test_create_kik_code(self, post):
        code = self.api.create_code({'akey': 'avalue'})

        post.assert_called_once_with(
            'https://api.kik.com/v1/code',
            timeout=60,
            auth=('mybotusername', 'mybotapikey'),
            headers={
                'Content-Type': 'application/json'
            },
            data=json.dumps({'data': '{"akey": "avalue"}'})
        )

        self.assertIsInstance(code, Code)
        self.assertEqual(code.id, 'ba7a319394f912ccad1ac42770529bd5cb0e9783')

    @mock.patch('requests.post', return_value=_response(
        200, json.dumps({'id': 'ba7a319394f912ccad1ac42770529bd5cb0e9783'}).encode('utf-8')
    ))
    def test_create_kik_code_no_data(self, post):
        code = self.api.create_code()

        post.assert_called_once_with(
            'https://api.kik.com/v1/code',
            timeout=60,
            auth=('mybotusername', 'mybotapikey'),
            headers={
                'Content-Type': 'application/json'
            },
            data='{}'
        )

        self.assertIsInstance(code, Code)
        self.assertEqual(code.id, 'ba7a319394f912ccad1ac42770529bd5cb0e9783')

    @mock.patch('requests.post', return_value=_response(400, json.dumps({'error': 'BadRequest'}).encode('utf-8')))
    def test_create_kik_code_failure(self, post):
        self.assertRaises(KikError, self.api.create_code, {'akey': 'avalue'})

    @mock.patch('requests.get', return_value=_response(200, json.dumps({
        'webhook': 'https://example.com/incoming',
        'features': {
            'manuallySendReadReceipts': True
        }
    }).encode('utf-8')))
    def test_get_configuration(self, get):
        config = self.api.get_configuration()

        get.assert_called_once_with(
            'https://api.kik.com/v1/config',
            timeout=60,
            auth=('mybotusername', 'mybotapikey')
        )

        self.assertEqual(config.webhook, 'https://example.com/incoming')
        self.assertEqual(config.features, {'manuallySendReadReceipts': True})

    @mock.patch('requests.post', return_value=_response(200, json.dumps({
        'webhook': 'https://example.com/incoming',
        'features': {
            'manuallySendReadReceipts': True
        }
    }).encode('utf-8')))
    def test_set_configuration(self, post):
        config = Configuration(
            webhook='https://example.com/incoming',
            features={'manuallySendReadReceipts': True}
        )

        response = self.api.set_configuration(config)

        self.assertEqual(post.call_count, 1)
        self.assertEqual(post.call_args[0][0], 'https://api.kik.com/v1/config')
        self.assertEqual(post.call_args[1]['timeout'], 60)
        self.assertEqual(post.call_args[1]['auth'], ('mybotusername', 'mybotapikey'))
        self.assertEqual(post.call_args[1]['headers'], {'Content-Type': 'application/json'})
        self.assertEqual(json.loads(post.call_args[1]['data']), {
            'webhook': 'https://example.com/incoming',
            'features': {
                'manuallySendReadReceipts': True
            }
        })

        self.assertIsInstance(response, Configuration)
        self.assertEqual(response.webhook, 'https://example.com/incoming')
        self.assertEqual(response.features, {'manuallySendReadReceipts': True})

    def test_verify_signature(self):
        self.assertTrue(self.api.verify_signature('AC18D0105C2C257652859322B0499313342C6EB9', b'body'))
        self.assertFalse(self.api.verify_signature('fakesig', b'body'))
Beispiel #6
0
class Kik_Helper:
	def __init__(self, username, api_key):
		self.engine = Engine()
		self.username = username
		self.api_key = api_key
		self.kik = KikApi(username, api_key)

	def set_config(self, end_point, manually_send_read_receipts,
				  receive_read_receipts, receive_delivery_receipts, receive_is_typing):
		requests.post(
			'https://api.kik.com/v1/config',
			auth=(self.username, self.api_key),
			headers={
				'Content-Type': 'application/json'
			},
			data=json.dumps({
				"webhook": end_point,
				"features": {
					"manuallySendReadReceipts": manually_send_read_receipts,
					"receiveReadReceipts": receive_read_receipts,
					"receiveDeliveryReceipts": receive_delivery_receipts,
					"receiveIsTyping": receive_is_typing
				}
			})
		)
		return Response(status=200)

	def check_config(self):
		config = self.kik.get_configuration()
		return config.webhook

	def send_messages(self, request):

		if not self.kik.verify_signature(request.headers.get('X-Kik-Signature'), request.get_data()):
			return Response(status=403)

		messages = messages_from_json(request.json['messages'])
		for message in messages:
			if isinstance(message, TextMessage):
				self.kik.send_messages(self.__choose_response(message))

		return Response(status=200)

	def __choose_response(self, message):
		messages = []
		response = self.engine.computeResponse(message.body)

		message = TextMessage(
			to=message.from_user,
			chat_id=message.chat_id,
			body=response
		)

		message.keyboards.append(
			SuggestedResponseKeyboard(
				hidden = False,
				responses = [TextResponse('OK')]
			)
		)

		messages.append(message)

		return messages
Beispiel #7
0
class Bot(object):
    def __init__(self,
                 username,
                 api_key,
                 webhook,
                 case_sensitive=False,
                 command_list="Commands"):
        self.functions = {}
        self.help = {}
        self.kik = KikApi(username, api_key)
        self.kik.set_configuration(Configuration(webhook=webhook))
        self.case_sensitive = case_sensitive
        if not isinstance(command_list, str):
            command_list = None
        if not case_sensitive:
            if command_list != None:
                command_list = command_list.lower()
        self.command_list_command = command_list
        self.keyboard_entries = [
            self.command_list_command
        ] if case_sensitive else [self.command_list_command.title()]

    def start(self, route="/incoming"):
        @app.route(route, methods=["POST", "GET"])
        def main():
            if not self.kik.verify_signature(
                    request.headers.get('X-Kik-Signature'),
                    request.get_data()):
                return Response(status=403)

            messages = messages_from_json(request.json['messages'])
            print "--Received Messages", messages
            to_send = None
            for message in messages:
                self.kik.send_messages([
                    IsTypingMessage(to=message.from_user,
                                    chat_id=message.chat_id,
                                    is_typing=True)
                ])

                if isinstance(message, TextMessage):
                    split = message.body.split(" ")
                    command = split[0]
                    if not self.case_sensitive:
                        command = command.lower()
                    text_data = " ".join(split[1:])
                    if command == self.command_list_command:
                        r = [
                            TextMessage(to=message.from_user,
                                        chat_id=message.chat_id,
                                        body=self.command_list())
                        ]
                    elif self.functions.has_key(command):
                        r = self.functions[command](text_data)

                    else:
                        r = [
                            TextMessage(to=message.from_user,
                                        chat_id=message.chat_id,
                                        body="Unknown command.")
                        ]

                    for m in r:
                        if m.to == None:
                            m.to = message.from_user
                        if m.chat_id == None:
                            m.chat_id = message.chat_id
                        if m.keyboards == []:
                            keyboard = self.make_keyboard()
                            if len(keyboard.responses) > 0:
                                m.keyboards.append(keyboard)

                    self.kik.send_messages(r)
            return Response(status=200)

    def make_keyboard(self):
        keyboard = SuggestedResponseKeyboard(
            hidden=False,
            responses=[TextResponse(x) for x in self.keyboard_entries])
        return keyboard

    def command(self, name, help_entry=None):
        if not self.case_sensitive:
            name = name.lower()

        def decorator(function):
            def wrapper():
                return function

            self.functions[name] = function
            if isinstance(help_entry, str):
                self.help[name] = help_entry
            return wrapper()

        return decorator

    def keyboard(self, entry):
        def decorator(function):
            def wrapper():
                return function

            self.keyboard_entries.append(entry)
            return wrapper()

        return decorator

    def execute(self, name, *args, **kwargs):
        return self.functions[name](*args, **kwargs)

    def command_list(self):
        return "\n".join(
            [key + " : " + val for key, val in self.help.iteritems()])
Beispiel #8
0
class KikBotClient(FlaskRestBotClient):

    def __init__(self, argument_parser=None):
        FlaskRestBotClient.__init__(self, "kik", argument_parser)

        self.create_kik_bot()

        YLogger.debug(self, "Kik Client is running....")

    def get_description(self):
        return 'ProgramY AIML2.0 Kik Client'

    def get_client_configuration(self):
        return KikConfiguration()

    def get_license_keys(self):
        self._bot_api_key = self.license_keys.get_key("KIK_BOT_API_KEY")

    def create_kik_bot(self):
        self._kik_bot = KikApi(self.configuration.client_configuration.bot_name, self._bot_api_key)
        self._kik_bot.set_configuration(Configuration(webhook=self.configuration.client_configuration.webhook))

    def handle_text_message(self, message):
        question = message.body
        userid = message.from_user

        answer = self.ask_question(userid, question)

        self._kik_bot.send_messages([
            TextMessage(
                to=message.from_user,
                chat_id=message.chat_id,
                body=answer
            )
        ])

    def get_unknown_response(self, userid):
        if self.configuration.client_configuration.unknown_command_srai is None:
            unknown_response = self.configuration.client_configuration.unknown_command
        else:
            unknown_response = self.ask_question(userid, self.configuration.client_configuration.unknown_command_srai)
            if unknown_response is None or unknown_response == "":
                unknown_response = self.configuration.client_configuration.unknown_command
        return unknown_response

    def handle_unknown_message(self, message):
        userid = message.from_user

        unknown_response = self.get_unknown_response(userid)

        self._kik_bot.send_messages([
            TextMessage(
                to=message.from_user,
                chat_id=message.chat_id,
                body=unknown_response
            )
        ])

    def handle_message_request(self, request):

        messages = messages_from_json(request.json['messages'])

        for message in messages:
            if isinstance(message, TextMessage):
                self.handle_text_message(message)
            else:
                self.handle_unknown_message(message)

    def receive_message(self, request):

        if self.configuration.client_configuration.debug is True:
            self.dump_request(request)

        if not self._kik_bot.verify_signature(request.headers.get('X-Kik-Signature'), request.get_data()):
            return Response(status=403)

        self.handle_message_request(request)
        return Response(status=200)
Beispiel #9
0
class KikBotClient(BotClient):

    def __init__(self, argument_parser=None):
        BotClient.__init__(self, "kik", argument_parser)

        self.get_tokens()

        self.create_kik_bot()

        if logging.getLogger().isEnabledFor(logging.DEBUG):
            logging.debug("Kik Client is running....")

    def set_environment(self):
        self.bot.brain.properties.add_property("env", 'kik')

    def get_client_configuration(self):
        return KikConfiguration()

    def get_tokens(self):
        self._bot_api_key = self.bot.license_keys.get_key("KIK_BOT_API_KEY")

    def ask_question(self, clientid, question):
        response = ""
        try:
            response = self.bot.ask_question(clientid, question)
        except Exception as e:
            print(e)
        return response

    def create_kik_bot(self):
        self._kik_bot = KikApi(self.configuration.client_configuration.bot_name, self._bot_api_key)
        self._kik_bot.set_configuration(Configuration(webhook=self.configuration.client_configuration.webhook))

    def handle_text_message(self, message):
        question = message.body
        clientid = message.from_user

        answer = self.ask_question(clientid, question)

        self._kik_bot.send_messages([
            TextMessage(
                to=message.from_user,
                chat_id=message.chat_id,
                body=answer
            )
        ])

    def handle_unknown_message(self, message):
        pass

    def handle_message_request(self, request):

        messages = messages_from_json(request.json['messages'])

        for message in messages:
            if isinstance(message, TextMessage):
                self.handle_text_message(message)
            else:
                self.handle_unknown_message(message)

    def handle_incoming(self, request):
        if not self._kik_bot.verify_signature(request.headers.get('X-Kik-Signature'), request.get_data()):
            return Response(status=403)

        self.handle_message_request(request)
        return Response(status=200)
Beispiel #10
0
class KikBot(IntegrationBot):
    """
    Kik integration.
    
    Permabots sets webhook. Only requires api_key and username from Kik provider.
    
    Follow Kik instructons to create a bot and obtain username and api_key `<https://dev.kik.com/>`_.
    """
    api_key = models.CharField(_('Kik Bot API key'), max_length=200, db_index=True)
    username = models.CharField(_("Kik Bot User name"), max_length=200)
   
    class Meta:
        verbose_name = _('Kik Bot')
        verbose_name_plural = _('Kik Bots')    
    
    def __init__(self, *args, **kwargs):
        super(KikBot, self).__init__(*args, **kwargs)
        self._bot = None
        if self.api_key and self.username:
            self.init_bot()
           
    def __str__(self):
        return "%s" % self.username
    
    def __repr__(self):
        return "(%s, %s)" % (self.username, self.api_key)
    
    def init_bot(self):
        self._bot = KikApi(self.username, self.api_key)
    
    def set_webhook(self, url):
        self._bot.set_configuration(Configuration(webhook=url))
    
    @property
    def hook_url(self):
        return 'permabots:kikbot'
    
    @property
    def hook_id(self):
        return str(self.id)
    
    @property
    def null_url(self):
        return "https://example.com"
    
    @property
    def identity(self):
        return 'kik'
    
    def message_text(self, message):
        return message.body
    
    def get_chat_state(self, message):
        try:
            return KikChatState.objects.select_related('state', 'chat', 'user').get(chat=message.chat, user=message.from_user, state__bot=self.bot)
        except KikChatState.DoesNotExist:
            return None
        
    def build_keyboard(self, keyboard):     
        def traverse(o, tree_types=(list, tuple)):
            if isinstance(o, tree_types):
                for value in o:
                    for subvalue in traverse(value, tree_types):
                        yield subvalue
            else:
                yield o
                
        built_keyboard = []
        if keyboard:
            built_keyboard = [TextResponse(element) for element in traverse(ast.literal_eval(keyboard))][:20]           
        return built_keyboard
    
    def create_chat_state(self, message, target_state, context):
        KikChatState.objects.create(chat=message.chat,
                                    user=message.from_user,
                                    state=target_state,
                                    ctx=context)

    def get_chat_id(self, message):
        return message.chat.id
    
    def send_message(self, chat_id, text, keyboard, reply_message=None, user=None):
        if reply_message:
            to = reply_message.from_user.username
        if user:
            to = user
        texts = text.strip().split('\\n')
        msgs = []
        for txt in texts:
            for chunk in textwrap.wrap(txt, 100):
                msg = TextMessage(to=to, chat_id=chat_id, body=chunk)
                msgs.append(msg)
        if keyboard:
            msgs[-1].keyboards.append(SuggestedResponseKeyboard(to=to, responses=keyboard))
        try:
            logger.debug("Messages to send:(%s)" % str([m.to_json() for m in msgs]))
            self._bot.send_messages(msgs)    
            logger.debug("Message sent OK:(%s)" % str([m.to_json() for m in msgs]))
        except:
            exctype, value = sys.exc_info()[:2]
            logger.error("Error trying to send message:(%s): %s:%s" % (str([m.to_json() for m in msgs]), exctype, value))