Skip to content

Commit

Permalink
Prettier logging and updated requirements.txt
Browse files Browse the repository at this point in the history
Added Ping Method and Pong response

Added method to catch temp bans
  • Loading branch information
TheGreatCodeholio committed Oct 14, 2023
1 parent c4c6f98 commit cc57b61
Show file tree
Hide file tree
Showing 12 changed files with 407 additions and 139 deletions.
2 changes: 1 addition & 1 deletion examples/echo_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def __init__(self, creds: dict):
android_id = creds['android_id']
node = creds.get('node') # If you don't know it, set it to None

self.client = KikClient(self, username, password, node, device_id=device_id, android_id=android_id, logging=True)
self.client = KikClient(self, username, str(password), node, device_id=device_id, android_id=android_id, enable_logging=True)
self.client.wait_for_messages()

# Initialization and Authentication
Expand Down
18 changes: 16 additions & 2 deletions kik_unofficial/callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
from kik_unofficial.datatypes.xmpp.account import GetMyProfileResponse
from kik_unofficial.datatypes.xmpp.chatting import *
from kik_unofficial.datatypes.xmpp.errors import LoginError, SignUpError
from kik_unofficial.datatypes.xmpp.login import LoginResponse, ConnectionFailedResponse, CaptchaElement
from kik_unofficial.datatypes.xmpp.login import LoginResponse, ConnectionFailedResponse, CaptchaElement, TempBanElement
from kik_unofficial.datatypes.xmpp.roster import FetchRosterResponse, PeersInfoResponse, GroupSearchResponse
from kik_unofficial.datatypes.xmpp.sign_up import RegisterResponse, UsernameUniquenessResponse
from kik_unofficial.datatypes.xmpp.xiphias import UsersResponse, UsersByAliasResponse
from kik_unofficial.datatypes.xmpp.history import HistoryResponse

from kik_unofficial.datatypes.xmpp.chatting import KikPongResponse


class KikClientCallback:
Expand Down Expand Up @@ -147,3 +147,17 @@ def on_xiphias_get_users_response(self, response: Union[UsersResponse, UsersByAl

def on_card_received(self, response: IncomingCardMessage):
pass

def on_pong(self, response: KikPongResponse):
"""
Gets called when the kik server sends a pong response to a ping response.
:return:
"""
pass

def on_temp_ban_received(self, response: TempBanElement):
"""
Gets called when kik servers send a temp ban message after successful authentication
When received, you will be unable to send or receive any stanzas until the current time is greater than the ban end time.
"""
pass
180 changes: 107 additions & 73 deletions kik_unofficial/client.py

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions kik_unofficial/datatypes/xmpp/account.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import datetime
import time

from bs4 import BeautifulSoup

Expand Down Expand Up @@ -124,3 +125,6 @@ def serialize(self):
f'</query>'
f'</iq>')
return data.encode()



10 changes: 5 additions & 5 deletions kik_unofficial/datatypes/xmpp/auth_stanza.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def send_stanza(self) -> None:
Send the outgoing auth stanza
"""
stanza = self.searlize()
log.info('[+] Sending authentication certificate')
log.info('Sending authentication certificate')
self.client.loop.call_soon_threadsafe(self.client.connection.send_raw_data, stanza)

def revalidate(self) -> None:
Expand All @@ -43,7 +43,7 @@ def revalidate(self) -> None:
if time.time() < self.revalidate_time:
return
stanza = self.searlize()
log.info('[+] Revalidating the authentication certificate')
log.info('Revalidating the authentication certificate')
self.client.loop.call_soon_threadsafe(self.client.connection.send_raw_data, stanza)

def searlize(self) -> bytes:
Expand Down Expand Up @@ -158,11 +158,11 @@ def handle(self, data: bs4.BeautifulSoup):
Handles the auth response (result/error) sent by Kik
"""
if data.error:
log.error('[!] kik:auth:cert [' + data.error.get('code') + '] ' + data.error.get_text())
log.error('kik:auth:cert [' + data.error.get('code') + '] ' + data.error.get_text())
log.debug(str(data))
return
if data.find_all('regenerate-key', recursive=True):
log.info('[!] Regenerating the keys for certificate authentication')
log.info('Regenerating the keys for certificate authentication')
self.teardown()
self.send_stanza()
return
Expand All @@ -171,7 +171,7 @@ def handle(self, data: bs4.BeautifulSoup):
self.cert_url = data.certificate.url.text
self.revalidate_time = current + (revalidate * 1000)
self.client.loop.call_later(revalidate, self.revalidate)
log.info('[+] Successfully validated the authentication certificate')
log.info('Successfully validated the authentication certificate')

def teardown(self):
"""
Expand Down
54 changes: 42 additions & 12 deletions kik_unofficial/datatypes/xmpp/chatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class OutgoingChatMessage(XMPPElement):
"""
Represents an outgoing text chat message to another kik entity (member or group)
"""

def __init__(self, peer_jid, body, is_group=False, bot_mention_jid=None):
super().__init__()
self.peer_jid = peer_jid
Expand Down Expand Up @@ -49,6 +50,7 @@ class OutgoingGroupChatMessage(OutgoingChatMessage):
"""
Represents an outgoing text chat message to a group
"""

def __init__(self, group_jid, body, bot_mention_jid):
super().__init__(group_jid, body, is_group=True, bot_mention_jid=bot_mention_jid)

Expand All @@ -57,6 +59,7 @@ class OutgoingChatImage(XMPPElement):
"""
Represents an outgoing image chat message to another kik entity (member or group)
"""

def __init__(self, peer_jid, file_location, is_group=False, forward=True):
super().__init__()
self.peer_jid = peer_jid
Expand Down Expand Up @@ -96,15 +99,15 @@ def serialize(self):
'</message>'
)


packets = [data[s:s+16384].encode() for s in range(0, len(data), 16384)]
packets = [data[s:s + 16384].encode() for s in range(0, len(data), 16384)]
return list(packets)


class OutgoingGroupChatImage(OutgoingChatImage):
"""
Represents an outgoing image chat message to a group
"""

def __init__(self, group_jid, file_location, forward):
super().__init__(group_jid, file_location, is_group=True, forward=forward)

Expand All @@ -113,6 +116,7 @@ class IncomingChatMessage(XMPPResponse):
"""
Represents an incoming text chat message from another user
"""

def __init__(self, data: BeautifulSoup):
super().__init__(data)
self.request_delivered_receipt = data.request['d'] == 'true' if 'd' in data.request.attrs else False
Expand All @@ -131,6 +135,7 @@ class IncomingGroupChatMessage(IncomingChatMessage):
"""
Represents an incoming text chat message from a group
"""

def __init__(self, data: BeautifulSoup):
super().__init__(data)
self.group_jid = data.g['jid']
Expand All @@ -142,6 +147,7 @@ class OutgoingReadReceipt(XMPPElement):
"""
Represents an outgoing read receipt to a specific user, for one or more messages
"""

def __init__(self, peer_jid, receipt_message_id, group_jid=None):
super().__init__()
self.peer_jid = peer_jid
Expand Down Expand Up @@ -234,7 +240,7 @@ def __init__(self, peer_jid, link, title, text, app_name):
def serialize(self):
message_type = 'type="groupchat" xmlns="kik:groups"' if 'group' in self.peer_jid else 'type="chat"'
timestamp = str(int(round(time.time() * 1000)))

data = (f'<message {message_type} to="{self.peer_jid}" id="{self.message_id}" cts="{timestamp}">'
'<pb></pb>'
f'<kik push="true" qos="true" timestamp="{timestamp}" />'
Expand All @@ -258,7 +264,7 @@ def serialize(self):
'</uris>'
'</content>'
'</message>')

return data.encode()


Expand Down Expand Up @@ -298,7 +304,8 @@ class IncomingGroupStatus(XMPPResponse):

def __init__(self, data: BeautifulSoup):
super().__init__(data)
self.request_delivered_receipt = data.request['d'] == 'true' if data.request and 'd' in data.request.attrs else False
self.request_delivered_receipt = data.request[
'd'] == 'true' if data.request and 'd' in data.request.attrs else False
self.requets_read_receipt = data.request['r'] == 'true' if data.request and 'r' in data.request.attrs else False
self.group_jid = data['from']
self.to_jid = data['to']
Expand All @@ -312,7 +319,8 @@ class IncomingGroupSysmsg(XMPPResponse):

def __init__(self, data: BeautifulSoup):
super().__init__(data)
self.request_delivered_receipt = data.request['d'] == 'true' if data.request and 'd' in data.request.attrs else False
self.request_delivered_receipt = data.request[
'd'] == 'true' if data.request and 'd' in data.request.attrs else False
self.requets_read_receipt = data.request['r'] == 'true' if data.request and 'r' in data.request.attrs else False
self.group_jid = data['from']
self.to_jid = data['to']
Expand Down Expand Up @@ -354,7 +362,8 @@ def __init__(self, data: BeautifulSoup):
class IncomingImageMessage(XMPPResponse):
def __init__(self, data: BeautifulSoup):
super().__init__(data)
self.request_delivered_receipt = data.request['d'] == 'true' if data.request and 'd' in data.request.attrs else False
self.request_delivered_receipt = data.request[
'd'] == 'true' if data.request and 'd' in data.request.attrs else False
self.requets_read_receipt = data.request['r'] == 'true' if data.request and 'r' in data.request.attrs else False
self.image_url = data.find('file-url').get_text() if data.find('file-url') else None
self.status = data.status.text if data.status else None
Expand Down Expand Up @@ -392,9 +401,11 @@ class IncomingGifMessage(XMPPResponse):
"""
Represents an incoming GIF message from another kik entity, sent as a URL
"""

def __init__(self, data: BeautifulSoup):
super().__init__(data)
self.request_delivered_receipt = data.request['d'] == 'true' if data.request and 'd' in data.request.attrs else False
self.request_delivered_receipt = data.request[
'd'] == 'true' if data.request and 'd' in data.request.attrs else False
self.requets_read_receipt = data.request['r'] == 'true' if data.request and 'r' in data.request.attrs else False
self.status = data.status.text if data.status else None
self.from_jid = data['from'] if data else None
Expand All @@ -413,6 +424,7 @@ class OutgoingGIFMessage(XMPPElement):
"""
Represents an outgoing GIF message to another kik entity (member or group)
"""

def __init__(self, peer_jid, search_term, API_key, is_group=True):
super().__init__()
self.peer_jid = peer_jid
Expand Down Expand Up @@ -454,11 +466,10 @@ def serialize(self):
'</message>'
)


packets = [data[s:s + 16384].encode() for s in range(0, len(data), 16384)]
return list(packets)

def get_gif_data(self, search_term, API_key):
def get_gif_data(self, search_term, API_key):
if not API_key:
raise Exception("A tendor.com API key is required to search for GIFs images. please get one and change it")

Expand All @@ -479,7 +490,8 @@ def get_gif_data(self, search_term, API_key):
class IncomingVideoMessage(XMPPResponse):
def __init__(self, data: BeautifulSoup):
super().__init__(data)
self.request_delivered_receipt = data.request['d'] == 'true' if data.request and 'd' in data.request.attrs else False
self.request_delivered_receipt = data.request[
'd'] == 'true' if data.request and 'd' in data.request.attrs else False
self.requets_read_receipt = data.request['r'] == 'true' if data.request and 'r' in data.request.attrs else False
self.video_url = data.find('file-url').text
self.file_content_type = data.find('file-content-type').text if data.find('file-content-type') else None
Expand All @@ -493,7 +505,8 @@ def __init__(self, data: BeautifulSoup):
class IncomingCardMessage(XMPPResponse):
def __init__(self, data: BeautifulSoup):
super().__init__(data)
self.request_delivered_receipt = data.request['d'] == 'true' if data.request and 'd' in data.request.attrs else False
self.request_delivered_receipt = data.request[
'd'] == 'true' if data.request and 'd' in data.request.attrs else False
self.request_read_receipt = data.request['r'] == 'true' if data.request and 'r' in data.request.attrs else False
self.from_jid = data['from']
self.to_jid = data['to']
Expand All @@ -508,3 +521,20 @@ def __init__(self, data: BeautifulSoup):
self.uri = data.find('uri').text if data.find('uri') else None


class KikPingRequest(XMPPElement):
def __init__(self):
super().__init__()

def serialize(self) -> bytes:
data = ('<ping/>')

return data.encode()


class KikPongResponse:
"""
Response to a <ping/> request to kik servers
"""

def __init__(self, data: BeautifulSoup):
self.recieved_time = time.time()
Loading

0 comments on commit cc57b61

Please sign in to comment.