-
Notifications
You must be signed in to change notification settings - Fork 77
/
interactive_client.py
executable file
·123 lines (94 loc) · 4.12 KB
/
interactive_client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/usr/bin/env python3
import argparse
import logging
import sys
import time
import threading
import yaml
from kik_unofficial.client import KikClient
from kik_unofficial.callbacks import KikClientCallback
from kik_unofficial.datatypes.xmpp.chatting import IncomingChatMessage, IncomingGroupChatMessage, IncomingStatusResponse, IncomingGroupStatus
from kik_unofficial.datatypes.xmpp.roster import FetchRosterResponse
from kik_unofficial.datatypes.xmpp.login import ConnectionFailedResponse
friends = {}
# Global client variable might not be the best solution, but it works for this example
client = None
class InteractiveChatClient(KikClientCallback):
client = None
def __init__(self, client) -> None:
super().__init__()
client = client
def on_authenticated(self):
cli_thread = threading.Thread(target=chat)
cli_thread.start()
def on_roster_received(self, response: FetchRosterResponse):
for peer in response.peers:
friends[peer.jid] = peer
print("-Peers-\n{}".format("\n".join([str(m) for m in response.peers])))
def on_chat_message_received(self, chat_message: IncomingChatMessage):
print(f"{jid_to_username(chat_message.from_jid)}: {chat_message.body}")
if chat_message.from_jid not in friends:
print(f"New friend: {jid_to_username(chat_message.from_jid)}")
client.send_chat_message(chat_message.from_jid, "Hi!")
time.sleep(1)
client.add_friend(chat_message.from_jid)
client.request_roster()
def on_group_message_received(self, chat_message: IncomingGroupChatMessage):
print(f"{friends[chat_message.group_jid].name} - {jid_to_username(chat_message.from_jid)}: {chat_message.body}")
def on_connection_failed(self, response: ConnectionFailedResponse):
print("Connection failed")
def on_status_message_received(self, response: IncomingStatusResponse):
print(response.status)
client.add_friend(response.from_jid)
def on_group_status_received(self, response: IncomingGroupStatus):
client.request_info_of_users(response.status_jid)
def jid_to_username(jid):
return jid.split("@")[0][:-4]
def chat():
# fmt: off
print("-Usage-\n\n"
"/c [first letters of username] - Chat with peer\n"
"/f - List peers\n\n"
"Type a line to send a message.\n")
# fmt: on
peer_jid = None
while True:
message = input()
if message.startswith("/"):
action = message[1]
if action == "c" and len(message) > 3:
for jid in friends:
if jid.startswith(message[3:]):
print(f"Chatting with {jid_to_username(jid)}")
peer_jid = jid
break
elif action == "f":
client.request_roster()
elif peer_jid and message:
client.send_chat_message(peer_jid, message)
def main():
global client # with client being global, we can write to it and see the changes outside of the main() scope
parser = argparse.ArgumentParser()
parser.add_argument("-c", "--credentials", default="creds.yaml", help="Credentials file containing at least username, device_id and android_id.")
args = parser.parse_args()
with open(args.credentials) as f:
creds = yaml.safe_load(f)
device_id = creds["device_id"]
android_id = creds["android_id"]
username = creds["username"]
node = creds.get("node")
password = creds.get("password")
if not password:
password = input("Password: ")
# set up logging # aint this obsolete?
logger = logging.getLogger()
logger.setLevel(logging.INFO)
stream_handler = logging.StreamHandler(sys.stdout)
stream_handler.setFormatter(logging.Formatter(KikClient.log_format()))
logger.addHandler(stream_handler)
# create the client
callback = InteractiveChatClient()
client = KikClient(callback=callback, kik_username=username, kik_password=password, kik_node=node, device_id=device_id, android_id=android_id)
client.wait_for_messages()
if __name__ == "__main__":
main()