├── .gitignore ├── README.md └── wechat-cli.py /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | itchat.pkl 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wechat-cli 2 | 微信 命令行版(简陋) 3 | 4 | - 只支持 python3 5 | - 支持 Windows (cmd&PowerShell) / Linux / cygwin / Mac 6 | 7 | ## 功能: 8 | 9 | - 和别人聊天 10 | - 接收消息(文字) 11 | - 按照名字和微信号搜索好友(支持模糊搜索) 12 | 13 | ## 依赖 14 | 15 | ``` 16 | pip3 install itchat 17 | ``` 18 | 19 | ## 展示 20 | 21 | ➜ wechat-cli git:(master) ✗ python3 wechat-cli.py 22 | Getting uuid of QR code. 23 | Downloading QR code. 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 | Please scan the QR code to log in. 64 | Please press confirm on your phone. 65 | Loading the contact, this may take a little while. 66 | Login successfully as 三哥,小池 67 | Start auto replying. 68 | Type help to get help 69 | $ help 70 | Usage: 71 | ls List recent users 72 | s Search User 73 | t Talk to someone 74 | logout LogOut 75 | $ t olly 76 | > olly $ 😊 77 | > olly $ olly Text: 就是我们不是通过微信的聊天框喵 78 | 我在cli里面olly Text: 为什么会是这个。。。界面 79 | 跟你聊天的呀 80 | -------------------------------------------------------------------------------- /wechat-cli.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | import itchat 4 | import threading 5 | import sys 6 | import os 7 | import copy 8 | from itchat.content import * 9 | 10 | # print("os: "+os.name) 11 | # print(os.sep) 12 | if os.name == 'nt': 13 | # enableCmdQR = 1 14 | pass 15 | else: 16 | # enableCmdQR = 2 17 | import readline # 强哥说,windows下面不需要 18 | 19 | enableCmdQR = 1 20 | qr = input("请选择控制台列宽,默认1,某些平台需要2,如果二维码不能正确显示,请重新设置此项数值:") 21 | if qr == "2": 22 | enableCmdQR = 2 23 | 24 | # 最近交谈 25 | recent = set() 26 | # UserName => NickName(RemarkName) 27 | user_table = dict() 28 | last_talk = None # 最后一个交谈的人 29 | 30 | 31 | def get_name(info): 32 | if len(info['RemarkName']) == 0: 33 | return info['NickName'] 34 | else: 35 | return info['RemarkName'] 36 | 37 | 38 | def get_cmd_args(s): 39 | args = s.split(' ') 40 | cmd = args[0] 41 | if len(args) >= 1: 42 | args.pop(0) 43 | return cmd, [a.strip() for a in args if len(a.strip()) > 0] 44 | 45 | 46 | @itchat.msg_register(TEXT, isGroupChat=True) 47 | def text_reply(msg): 48 | global last_talk 49 | FromUserName = msg['FromUserName'] 50 | last_talk = FromUserName 51 | recent.add(FromUserName) 52 | if FromUserName in user_table: 53 | name = user_table[FromUserName] 54 | else: 55 | uf = itchat.search_friends(userName=FromUserName) 56 | ur = itchat.search_chatrooms(userName=FromUserName) 57 | if uf == None: 58 | u = ur 59 | else: 60 | u = uf 61 | user_table[u['UserName']] = get_name(u) 62 | name = get_name(u) 63 | print(name, '%s: %s' % (msg['Type'], msg['Text'])) 64 | 65 | 66 | class Search(): 67 | def __init__(self): 68 | c = itchat.instanceList[-1] 69 | self.updateLock = c.storageClass.updateLock 70 | self.memberList = c.memberList 71 | self.chatroomList = c.chatroomList 72 | 73 | def search_friends_w(self, name): 74 | with self.updateLock: 75 | contact = [] 76 | print("name ",name) 77 | for m in self.memberList: 78 | if any([name.lower() in m.get(k).lower() for k in ('RemarkName', 'NickName', 'Alias')]): 79 | print([m.get(k) 80 | for k in ('RemarkName', 'NickName', 'Alias')]) 81 | contact.append(m) 82 | 83 | return copy.deepcopy(contact) 84 | 85 | def search_chatrooms_w(self, name): 86 | with self.updateLock: 87 | matchList = [] 88 | for m in self.chatroomList: 89 | if name in m['NickName']: 90 | matchList.append(copy.deepcopy(m)) 91 | return matchList 92 | 93 | def search_all(self, name): 94 | contact = [] 95 | kws = [x for x in name.split(" ") if x != ""] 96 | for c in kws: 97 | contact += self.search_friends_w(c) 98 | for c in kws: 99 | contact += self.search_chatrooms_w(c) 100 | d = {} 101 | for c in contact: 102 | d[c['UserName']] = c 103 | return d 104 | 105 | 106 | running = True 107 | 108 | 109 | def logout_callback(): 110 | global running 111 | running = False 112 | print("Logout\n") 113 | 114 | 115 | itchat.auto_login(enableCmdQR=enableCmdQR, hotReload=True, 116 | exitCallback=logout_callback) 117 | 118 | # 开启记录消息 119 | 120 | 121 | def run_itchat(): 122 | itchat.run() 123 | 124 | 125 | # 用另一个线程收取消息 126 | recv_thread = threading.Thread(target=run_itchat, args=()) 127 | recv_thread.start() 128 | 129 | me = itchat.search_friends() 130 | user_table[me['UserName']] = '@me' 131 | 132 | talking_to = None 133 | promot = "$ " 134 | 135 | print("Type 'help' to get help") 136 | 137 | # cmd loop 138 | while running: 139 | s = input(promot) 140 | s = s.strip() 141 | if s == "": 142 | continue 143 | cmd, args = get_cmd_args(s) 144 | 145 | if cmd == "help": 146 | print("Usage:") 147 | print("ls\tList recent users") 148 | print("s\tSearch User") 149 | print("t\tTalk to someone") 150 | print("r\tChange to reply last message") 151 | print("logout\tLogOut") 152 | elif cmd == "ls": # list 153 | for u in recent: 154 | print(u, user_table[u]) 155 | elif cmd == 's': # search 156 | if len(args) > 0: 157 | k = args[0] 158 | # print("k ", k) 159 | 160 | s = Search() 161 | d = s.search_all(k) 162 | for k, r in d.items(): 163 | print(r['UserName'], r['RemarkName'], 164 | r['NickName'], r['Alias']) 165 | user_table[r['UserName']] = get_name(r) 166 | else: 167 | print("Usage: s name") 168 | elif cmd == "t": # talk 169 | if len(args) > 0: 170 | 171 | if args[0] in user_table: 172 | talking_to = args[0] 173 | else: 174 | k = args[0] 175 | 176 | ul = itchat.search_chatrooms(name=k) 177 | if len(ul) > 0: 178 | u = ul[0] 179 | talking_to = u['UserName'] 180 | user_table[talking_to] = get_name(u) 181 | 182 | ul = itchat.search_friends(name=k) 183 | if len(ul) == 0: 184 | pass 185 | else: 186 | u = ul[0] 187 | talking_to = u['UserName'] 188 | user_table[talking_to] = get_name(u) 189 | 190 | if talking_to != None: 191 | promot = "> "+user_table[talking_to]+" $ " 192 | recent.add(talking_to) 193 | else: 194 | print("Usage: t @id") 195 | elif cmd == "r": # reply 196 | if last_talk != None: 197 | talking_to = last_talk 198 | promot = "> "+user_table[talking_to]+" $ " 199 | elif cmd == "logout": 200 | itchat.logout() 201 | sys.exit() 202 | else: 203 | if talking_to != None: 204 | itchat.send(s, toUserName=talking_to) 205 | 206 | recv_thread.join() 207 | --------------------------------------------------------------------------------