From 1ec0a530bf17fcd253acd64acdfeef5adf2148a0 Mon Sep 17 00:00:00 2001 From: zhayujie <yjzha1996@163.com> Date: Wed, 10 Aug 2022 00:04:10 +0800 Subject: [PATCH] init: build minimum viable version --- .gitignore | 2 + app.py | 10 +++++ bot/__pycache__/bot.cpython-36.pyc | Bin 0 -> 574 bytes bot/__pycache__/bot_factory.cpython-36.pyc | Bin 0 -> 491 bytes .../__pycache__/baidu_unit_bot.cpython-36.pyc | Bin 0 -> 1537 bytes bot/baidu/baidu_unit_bot.py | 26 ++++++++++++ bot/bot.py | 13 ++++++ bot/bot_factory.py | 16 +++++++ bridge/__pycache__/bridge.cpython-36.pyc | Bin 0 -> 616 bytes bridge/bridge.py | 9 ++++ channel/__pycache__/channel.cpython-36.pyc | Bin 0 -> 1200 bytes .../channel_factory.cpython-36.pyc | Bin 0 -> 510 bytes channel/channel.py | 31 ++++++++++++++ channel/channel_factory.py | 15 +++++++ .../__pycache__/wechat_channel.cpython-36.pyc | Bin 0 -> 1552 bytes channel/wechat/wechat_channel.py | 39 ++++++++++++++++++ 16 files changed, 161 insertions(+) create mode 100644 .gitignore create mode 100644 app.py create mode 100644 bot/__pycache__/bot.cpython-36.pyc create mode 100644 bot/__pycache__/bot_factory.cpython-36.pyc create mode 100644 bot/baidu/__pycache__/baidu_unit_bot.cpython-36.pyc create mode 100644 bot/baidu/baidu_unit_bot.py create mode 100644 bot/bot.py create mode 100644 bot/bot_factory.py create mode 100644 bridge/__pycache__/bridge.cpython-36.pyc create mode 100644 bridge/bridge.py create mode 100644 channel/__pycache__/channel.cpython-36.pyc create mode 100644 channel/__pycache__/channel_factory.cpython-36.pyc create mode 100644 channel/channel.py create mode 100644 channel/channel_factory.py create mode 100644 channel/wechat/__pycache__/wechat_channel.cpython-36.pyc create mode 100644 channel/wechat/wechat_channel.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d2d9075 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea/ +venv diff --git a/app.py b/app.py new file mode 100644 index 0000000..78e6c4e --- /dev/null +++ b/app.py @@ -0,0 +1,10 @@ +from channel import channel_factory + +if __name__ == '__main__': + # create channel + channel = channel_factory.create_channel("wx") + + # startup channel + channel.startup() + + print("Hello bot") \ No newline at end of file diff --git a/bot/__pycache__/bot.cpython-36.pyc b/bot/__pycache__/bot.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a006b4219279b4c5140baccecf890864dda4fb8b GIT binary patch literal 574 zcmZWly-ve05O#k0LqsPS7_*@uwHeqdgbD~DmM(~;i{-=zZI#5S?I0y1@G?9MFW{92 zU`Gs`(;tvH>APHfci(q+r-MPD-#?RYLdXYVXFf&~ggQdU$&B0(?r`^&a2K2xZ{~9E zjzoTQ99&dd3?-BqtHX58bSOn4bjT8=B};XfW=yFdMVg(t7)=oB5FL=2g97fFe&(%- zjdv+@Y74E|uY<Tks6IMPo*nMs1a6ZB;l^6o?KC)yC^Qs$mmZf)vOJWq8ly{L@dP}~ zK`HhKzeN&sB@0_oX8$>+kz)>~Lf__P205|=zm`(S$Thx#?7?(a70CLH$PP~VbrRnz zkScEKW!%hJT`d<7+anFxVu<6$8;r`@bXvup-LPG|+w9>9M(yh~@=c%8g5^M|2`J44 zuQD6&Q@W~Hw$4b~-75caUHfK_XM>iy@3jBZ$TK}kxk!<xE0QIox=s9Pwp&QsX!>Vs K&2w){<9k2Bs*NN7 literal 0 HcmV?d00001 diff --git a/bot/__pycache__/bot_factory.cpython-36.pyc b/bot/__pycache__/bot_factory.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..68002af308cf84209367eeecb85f7cad0b4d40c5 GIT binary patch literal 491 zcmY*VJx{|h5Vf5&L{W>xf*2UGW@sb9Rw0CnSUXU4$zr*-QB(3!InI!X3HUSorASN+ zh>4wvv)hPr(mnfh@7_K8ax@A)-@jKAjL-)<2m<#T$m$$GpacmlNQQHg5R8N)+*g!1 zVz5Aw*PaA?&5A;1;REBkR88;&Lny-CaK=(mFN;*qO3h)14Rad(Tgd7Z;0e?pi8|Kk z1uc-q&#()Woi+<X2(Bd4GGt-DCM_z>3NCGTx@C&xeUIv9E2n)GnkwX_*i)6%wJQGF z|Admk%DA0JL>YJ8@V+i|n#((-N)_S6UzOU*zaixU;pZY=R#H`Q+ic=?&6;|X${0NA zF-yllj`vCT-!j=YU9fu$g_dug?*Sms#~xPZI*;7$h*D8<N|Q4nO{}LK(i%R}Oj>`I aZ;c$l05m%PDlbKy$!iCy%2;*D(D?=YD1Wp7 literal 0 HcmV?d00001 diff --git a/bot/baidu/__pycache__/baidu_unit_bot.cpython-36.pyc b/bot/baidu/__pycache__/baidu_unit_bot.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9a1fff91fc1d8789e0cc130ecc9e5c53a58aaa33 GIT binary patch literal 1537 zcmZ`(&2QsG6rb@&l4i5C!0whx9EuM}k(zkhvNS4mchzl0ksx$Q!-oMG*E4CHI<`AA zZW}j|kkZ2*;Ep(P;lK%TL}>pJ-w=h>p15=3&A7Xi0~5XHH_vZ=@6CHZXZ8B^D*x@T z{aF*C-_ez2fPEi??|>qR;1D^*6FV68TBr?mN5|+LM08@DBVtf}syhZXiFv58En1?+ z6b;IxG{sYl0ilEH<)?s#+I5`ko3Zfa=GoG~xDUc#1x1le;%EdD?HoCJk-{;E2_U7s zw&?{V?M8u+DDtFSWe~UqdH}+|1T{tjG({6Y8Ef-sq7!Y5=b>D%4S~moDhn_JJTZkf z(8v1N7(mfula#*EC#7+TeLgM?%qb$}1w<+!Ga%Ik)PYt&CD+>7gT4?6U$<>9NSgby ztbLz0{dj1z#J5+Px9t?lv^izRfluw@Rom}-;-2UGlyg_ahcw#AzCN>#DdRyLS?ktn z^R~5QT^?`)0<O;5>hju}@^TqfcwryL2Zg=1cBge`Wm$$C24M(JZmoZ2Ew8LBw_0yn zUo2US9;K8EYyHd;lnsN(lTiTPk_!&PYc_&?wrVXcTK!Q%nVWdb8v@eenI+41{gjJ% z=<dhDO<3FuLJIGeCzDB5^W#X+NHhc-%wF@7Bn*5{K(Y2|<K*O|(Tmxzk+P6ReoQE- zYq>!@;pOE%^$1)(FEPr~P~>HWbSj(|JD+yk-4C}r-S@Y*+?{tjdrvV;73M#4Kt<8J z+)P*yiM(=oJ)Rp$%tc-*(&WZ~$5FkU8=Qu{+*EhWP1W{XhiaS|8SctTnB<NG;z=BF z`XgdD!14E6b{A&B?QAr#v%WV<2LV+xY<NKf8euDugSXZAT{&;rp=L75O-7S&Gy^z% z4iv%__|=rYfeoC!bd|_W73|A9$|cK@)K+xf1cTrSd=5ZoUD4Q>M+L0~8sM=$#S>#} zu)9J766;eW$z52)d`{R>+j-@Lv`>=btp7%DleJE>y>yrEe(-U>>nv_}#e1KOSbWgi zd-zc+iUyG%9ksW6bQJGwb&opP!~Z3F?4_cw=&pKu?|^v`j0m`};fDe6!u1&?@C>|= zzkcZo$VN8%Y{Mx;hz+N9_0y;u>>AuW*J0qS3Kn|-RNZ8=@NlY^p@($jREzU2*tyY% znX;E<xEx`jZc0l|Li)LcK`;RW&*3WQ8qRM0XBN*H)~=g*#dRZZNL@Fty6!M0X(;WQ z>mH?ESiE7k08rsy$*Hod#5%mKfN=T03M8m9>5;%gFNj<>l~EUuzkl-G`IARK|MA1) zKfnFy;@7V(etA@{s5`4ZIAzHz5GIMCAlQPmRBKcP|6cfc^1SkPQS)7ylgn5|Lw)XM G1^)vox}_=r literal 0 HcmV?d00001 diff --git a/bot/baidu/baidu_unit_bot.py b/bot/baidu/baidu_unit_bot.py new file mode 100644 index 0000000..284eff5 --- /dev/null +++ b/bot/baidu/baidu_unit_bot.py @@ -0,0 +1,26 @@ +# encoding:utf-8 + +import json +import requests +from bot.bot import Bot + + +class BaiduUnitBot(Bot): + def reply(self, query): + token = self.get_token() + url = 'https://aip.baidubce.com/rpc/2.0/unit/service/v3/chat?access_token=' + token + post_data = "{\"version\":\"3.0\",\"service_id\":\"S73177\",\"session_id\":\"\",\"log_id\":\"7758521\",\"skill_ids\":[\"1221886\"],\"request\":{\"terminal_id\":\"88888\",\"query\":\"" + query + "\", \"hyper_params\": {\"chat_custom_bot_profile\": 1}}}" + print(post_data) + headers = {'content-type': 'application/x-www-form-urlencoded'} + response = requests.post(url, data=post_data.encode(), headers=headers) + if response: + return response.json()['result']['context']['SYS_PRESUMED_HIST'][1] + + def get_token(self): + access_key = '${YOUR_ACCESS_KEY}' + secret_key = '${YOUR_SECRET_KEY}' + host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=' + access_key + '&client_secret=' + secret_key + response = requests.get(host) + if response: + print(response.json()) + return response.json()['access_token'] diff --git a/bot/bot.py b/bot/bot.py new file mode 100644 index 0000000..8b441e9 --- /dev/null +++ b/bot/bot.py @@ -0,0 +1,13 @@ +""" +Auto-replay chat robot abstract class +""" + + +class Bot(object): + def reply(self, query): + """ + bot auto-reply content + :param req: received message + :return: reply content + """ + raise NotImplementedError diff --git a/bot/bot_factory.py b/bot/bot_factory.py new file mode 100644 index 0000000..919215f --- /dev/null +++ b/bot/bot_factory.py @@ -0,0 +1,16 @@ +""" +channel factory +""" + +from bot.baidu.baidu_unit_bot import BaiduUnitBot + + +def create_bot(bot_type): + """ + create a channel instance + :param channel_type: channel type code + :return: channel instance + """ + if bot_type == 'baidu': + return BaiduUnitBot() + raise RuntimeError \ No newline at end of file diff --git a/bridge/__pycache__/bridge.cpython-36.pyc b/bridge/__pycache__/bridge.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d25ba0cae902ab5786e64c1df1d148c19feaf39a GIT binary patch literal 616 zcmZuuJx{|h5Ix692~c2QLrAb@XoJLxP*n!DE{G+ImBcPhlqTRfLn^lR&+r@gCmC3n znAn-Pb0{pFbRW8VdiQ+3JUG}pd;3gY0pK0|*IcY7==C`U36d4CWD#R<3(}E%1ClFe z%_A<|I|#fFL_xs1{iHHt9;c?#ZA!hZIao~4>r)I0A|@enB$LhtkONsTyV66hK{uG{ zOg^ZTA(V_V`3-ta!XzM$&0c7uTdQKOscXa6MR;E;U5BeS4_Ax0ZSqWo=^{3xI2)n5 zFtOx6Y5drBz7ScN86iC4C!xSrN4<vec9z;cjwq8`F^5<f$k`fl=b5dUl@)MJfM__4 zGuhlD^|UgPr`2Q829BmJo%hrz-Tuke1L_{nl}Q)EB1Kx2MwQ0L!B*7CkEnlOv%sT= zl<`st(d`MbtYlMAJrv@piHm-scaTo+QusYtUy%UKF;L%L*=Ihtomt>U98YJT)eWj7 VSE;d+|42Ijs^5K0e`ci*`8RpPhUWkP literal 0 HcmV?d00001 diff --git a/bridge/bridge.py b/bridge/bridge.py new file mode 100644 index 0000000..3e5af00 --- /dev/null +++ b/bridge/bridge.py @@ -0,0 +1,9 @@ +from bot import bot_factory + + +class Bridge(object): + def __init__(self): + pass + + def fetch_reply_content(self, query): + return bot_factory.BaiduUnitBot().reply(query) diff --git a/channel/__pycache__/channel.cpython-36.pyc b/channel/__pycache__/channel.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d38f44b04d40435678ee4a8b80d7eb709a800702 GIT binary patch literal 1200 zcmZ`&J8#rL5Z<+YwqspF5m6yUE+{xbauReWgb)!zDYypFxLNJ(ZZ1CgaqO;<&Y~iz z`58$3B^NYQRP<EL_(c*WEA7sBXLjcMX2vh}_oJsj|E#_{g#04cmIwN4*yb@Dk|ab@ z>0~r_5{Hs^M7q+uBGOatrJHzi@`23!`bqR&8N=5qHmZ<mv5v(BFA9~#d}XZW!p0)w z#zem%CYjO3f1^{mRsuhV1wgvQ&p=Tmp^)6c<X0qdyR?{4`tUuGfeb<Vat{DRO>o-f z6SR+p689-=6T)H1S1KtuJM~c%_bV+@K-N7SFPDJta9P^3e4D9U6;{c&T9+EGJ)^So zA4K~Q@bB~aN29cv*SpQUzTmrRld3rcv&TF=UX>Pgtid2pw!0=UmTOyW5s^W{#H%0l z*iU+!Xz#&<@;(k{BiyYn1r$HlN~rX+l5uX<qj9n2n&)`6i1WTh<!YmZ9bJH~#-7g{ zJps|U;M@}IjsWj`U?MYh0D6adQXdScJCkt1h709=pudetaZE-)wu~#N<Y>GLv?!qu z#edYjPfuDe2KstvXUv5ttLrbcvXw3t@t9|1?zYVJ9zbuxA>{2EK<^9r5L~(n1od>N z02*#I4I9@E-V_u|F3E;|p_e#(bO~ifb8>jDthiuWZL=Ng*$pk2e5#b*-3D;Ds?to} zd~r15q4lEy&mDftS<r-x6+BmrH4$TZDXR?iDPx~1o^=+DbEzXd5W2>OUxR^TuW=wW zb{UoS*9vLqhe5d4-Y#d8CSXjKg0W<O)&AxuooI<Sem8%u^Ifr<@MQ<?6(%t_nw~Rt F{sBmc7$^V$ literal 0 HcmV?d00001 diff --git a/channel/__pycache__/channel_factory.cpython-36.pyc b/channel/__pycache__/channel_factory.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d4c4ddc787f41d191ad4ebd030355765207241c4 GIT binary patch literal 510 zcmY*VO-sW-5Z&FRX$ft?izkI#b7*t$R#b%IwFip`xh&i4N>lSuHXCY!AgDjUzu{lX z)srXho}Aq#SO@ma3~%Pm?3|58?(_Ti>H;J5i4KfFd<CyK0pKV^9CMQ3l!OE$ZgKk! zg%<BEk?+(;ZnS1uCKB(SMJkt-`vpzN$Ia+Y0Hx-8I)Wj_wATaX@QP!ACy;+2a;(rR zS|WvCU>HbSb>ezpkrYe`k9pmkI4cy(B4OCsmPwX&997j;%(~3enHS}}EtNu*GW(<d z2{mN*xbTV8t2M)$GE;FXuBFVSkHcX*+vtBF*@L2=S#VnjSp;>p3F<Yg%1tZ+{o@IX zC#ziPSRbbIv^~&tTQ%eTuV`D+*SBy0kTbvzmO5YfcGIVn=MkmhX<InmnVYt*Yd1@q aCbQWAXw7DDp60wv#H9sUVFTD?NPYpN)rUd= literal 0 HcmV?d00001 diff --git a/channel/channel.py b/channel/channel.py new file mode 100644 index 0000000..94f7b8b --- /dev/null +++ b/channel/channel.py @@ -0,0 +1,31 @@ +""" +Message sending channel abstract class +""" + +from bridge.bridge import Bridge + +class Channel(object): + def startup(self): + """ + init channel + """ + raise NotImplementedError + + def handle(self, msg): + """ + process received msg + :param msg: message object + """ + raise NotImplementedError + + def send(self, msg, receiver): + """ + send message to user + :param msg: message content + :param receiver: receiver channel account + :return: + """ + raise NotImplementedError + + def build_reply_content(self, query): + return Bridge().fetch_reply_content(query) diff --git a/channel/channel_factory.py b/channel/channel_factory.py new file mode 100644 index 0000000..5ecdbeb --- /dev/null +++ b/channel/channel_factory.py @@ -0,0 +1,15 @@ +""" +channel factory +""" + +from channel.wechat.wechat_channel import WechatChannel + +def create_channel(channel_type): + """ + create a channel instance + :param channel_type: channel type code + :return: channel instance + """ + if channel_type == 'wx': + return WechatChannel() + raise RuntimeError \ No newline at end of file diff --git a/channel/wechat/__pycache__/wechat_channel.cpython-36.pyc b/channel/wechat/__pycache__/wechat_channel.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1efc97cdabf7425e83637443f128f9fddcef2f65 GIT binary patch literal 1552 zcmZvc&5zwQ5WwwxZ<^PS-EFItIP3{2NZls^rwXA;73KDX#6ut>WU{e$H)&q-upMBd zaC$5C)IWrODc7Es3pWm&m~j$yUqzzK*v@!7^YhrBEf(=V@BTjj%O&I;x$}6?egU8U z8H6B=2r8V4GHSKM9IIXCTJ13pv|IUWwDYQ96S9yJNy|tcT+$sCz6fr}j<Wb`B0>?} z5E036=dydk`Ie*y-NX1dnO|k*6hvLiD!zqv$ttA-{RBk#avaVn4#R`mf$t@J`XLBI zcBG^|tU)1O@JUyxGc3NhUZ>eZ0A55T!J)g+mwyr!!pwhPEWguI>1B6aF1xGjx-AR2 z#9*Ff#k2FqU>jpvjv-EpPorns>)~khtGJT6EPj<7yeAkLhDaQB05Zqs`~YtI=+8k( z0$9n2^o9UZS9qYkH{@aj7cqZ?#)3D*BP>K@3b$yF2Qsld@Xy4+W(fIuT2>dfGl~dI zhKTc`E)3^~&>Lf=-IG0JXS2!wuXGF(4RGJVhJbcZ&-C3PC=6m`an_oKSIuQnGgq~B zN>vOKKMW_-CR3)}KE`M;2jWC-_jo^^$tJgC!36Dm_>ibxgD_BnJ>5ANkfEj1L*WYd zt%HRDZSREqfn)v&5dpN_-s#=fj{2r2rE5GWA|L*SCs0VegI;Vp(W;BaJ$`=rDy1xu zwQiN<na+!XC9hPo!5Ug+8_7IuvFLq&Eq^y@F!)<l)MoHX-PD6G+Rawuw$x(qb-RTr zN9S!(38<lMb<OjpHnKLUH=+t4GnQPyI=lt<ybx^Bm@8;aUD)FT&hskMn)CO2tdPw| z$Oh|?(3l?5$Vq5KyW@SZV|w{qnW&MiEvQeSf!l1H(jNGorD?o=Vr2X>0BY`2(mTR? zJ5%#lw^)<6=&K7(e}uF26Tpj2Gs8*4!7~Lw^K~WVb_f(4&}PFz)Idw!hp7rfSC2rX z?j0J@blB7fb!06+25XJb2qYZS?r=X@#GXcY0BYDW&WD)uO(WV0+X?5tv{^O&QTM=y zTA)Cb*7>lQNawPuX4-g_Kw%%D5uPr4J~3#Gy@*C`6eh79O_L$yTr@e%wYfb(`==-# zfMEB>b8|M;0DCZBHIr5dlqGP<K(SmF+CcGm>#u%T+l$67afb;8W+NJ+FUB0d#QFBt N^q>&tH*t^s{{Z#1VUqv= literal 0 HcmV?d00001 diff --git a/channel/wechat/wechat_channel.py b/channel/wechat/wechat_channel.py new file mode 100644 index 0000000..bcae08e --- /dev/null +++ b/channel/wechat/wechat_channel.py @@ -0,0 +1,39 @@ +""" +wechat channel +""" +import itchat +import time +import random +import json +from itchat.content import * +from channel.channel import Channel + + +@itchat.msg_register([TEXT]) +def handler_receive_msg(msg): + WechatChannel().handle(msg) + + +class WechatChannel(Channel): + def __init__(self): + pass + + def startup(self): + # login by scan QRCode + itchat.auto_login() + + # start message listener + itchat.run() + + def handle(self, msg): + print("handle: ", msg) + print(json.dumps(msg, ensure_ascii=False)) + from_user_id = msg['FromUserName'] + other_user_id = msg['User']['UserName'] + if from_user_id == other_user_id: + self.send(super().build_reply_content(msg['Text']), from_user_id) + + def send(self, msg, receiver): + time.sleep(random.randint(1, 3)) + print(msg, receiver) + itchat.send(msg + " [bot]", toUserName=receiver)