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
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)
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, {})
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))
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'))
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
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()])
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)
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)
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))