In [ ]:
import IPython.display
IPython.display.YouTubeVideo('TBD')

Intelligent Process Automation / Intelligent Agent

zhan.gu@nus.edu.sg

A workshop to develop & use an intelligent and interactive chat-bot in WeChat

For Automated Parcel Status Enquiry

Imports / 导入需要用到的一些功能程序库:


In [1]:
# from __future__ import unicode_literals, division
import time, datetime, requests, itchat
from itchat.content import *



In [2]:
import tagui as t
from time import localtime, strftime
# import pandas as pd

Function: Enquire_Parcel


In [3]:
# Function
# input : Parcel ID, type: string
# Return: File name of screenshot png image containing parcel status results, type: string

def Enquire_Parcel(str_parcel_id):
#     print('str_parcel_id   : ', str_parcel_id)

    result_filename = 'results/' + str(str_parcel_id).lstrip() + strftime("-%Y-%m-%d-%Hm%Mm%Ss", localtime()) + '.png'
#     print('result_filename : ', result_filename)
    
    t.init(visual_automation = True)
    t.url('http://qexpress.co.nz/tracking.aspx?orderNumber=' + str(str_parcel_id).lstrip())
    t.wait(0.5)
    t.keyboard('[end]')
    t.wait(0.5)
    t.snap('page.png', result_filename)
    t.wait(0.5)
    t.close()
    print('[ Enquie Parcel ] ID : {} | File Name : {}'.format(str_parcel_id, result_filename)) 
    return result_filename;


In [4]:
#######################################################################
### Optional Adhoc Test
### Function: Enquire_Parcel
#######################################################################

msg_parcel_id = 'DZ140053181NZ'
msg_filename = Enquire_Parcel(msg_parcel_id)


[ Enquie Parcel ] ID : DZ140053181NZ | File Name : results/DZ140053181NZ-2019-07-25-12m25m35s.png

* Log in web WeChat using QR code image / 用微信App扫QR码图片来自动登录


In [5]:
# itchat.auto_login(hotReload=True) # hotReload=True: 退出程序后暂存登陆状态。即使程序关闭,一定时间内重新开启也可以不用重新扫码。
itchat.auto_login(enableCmdQR=-2) # enableCmdQR=-2: 命令行显示QR图片


Getting uuid of QR code.
Downloading QR code.
                                                                              
  ██████████████    ██  ██  ████      ██    ██    ██  ██      ██████████████  
  ██          ██    ██    ██████        ██  ██      ██        ██          ██  
  ██  ██████  ██  ████████████  ████  ██    ██      ██  ████  ██  ██████  ██  
  ██  ██████  ██  ██  ██████  ████  ██  ████████    ████████  ██  ██████  ██  
  ██  ██████  ██    ██  ██        ██  ████  ██████  ████      ██  ██████  ██  
  ██          ██      ██  ██    ██  ██  ██████████    ██      ██          ██  
  ██████████████  ██  ██  ██  ██  ██  ██  ██  ██  ██  ██  ██  ██████████████  
                    ██  ████    ████    ████  ██  ████  ████                  
        ████  ████  ██████  ██          ██    ████                  ████      
        ██████  ████                      ████  ██  ██  ████████████  ████    
    ██      ████  ██████████  ██████        ████  ████  ██████████        ██  
    ██  ██      ██  ██  ██  ██      ██████  ██  ██    ██  ██████    ████  ██  
  ██  ██      ██████    ██      ██    ██████            ████  ████  ████████  
      ██    ██  ██████████████  ████  ██████  ██████  ████████    ██  ██      
        ██████████      ██    ██  ██████  ████  ██████  ██  ████  ██████████  
  ██    ██  ██    ██      ██    ████████  ██  ██        ██  ██    ████████    
      ████████████  ████  ████████  ██    ████████  ██    ██  ████    ██  ██  
  ████████  ██  ██  ████    ██████    ████  ██  ██████  ██  ██  ██      ██    
      ██  ██  ██  ████  ██    ████  ████    ████  ██    ██      ██    ██  ██  
        ██      ██████      ██████  ████████      ████      ██      ██        
  ██    ██  ████    ██████      ████      ██    ████████  ██████  ████        
  ████              ██████      ████          ██  ██████████    ████  ██████  
      ██  ██  ████  ██  ██    ████      ████  ██  ██    ██    ██  ██      ██  
  ██  ████████  ██  ██  ████    ████    ██    ██████  ██████    ██    ██      
    ████    ████          ██  ██      ██  ██████    ████      ██    ██  ████  
  ██  ██          ████████      ████    ██████    ██  ██  ██████  ████████    
  ████    ██  ████  ████    ██    ████  ████  ██    ████████  ██  ████  ████  
  ██  ██    ██        ██  ██    ██  ██      ████  ██  ████████    ██████      
  ██    ████████████  ████    ████    ██████  ████  ██    ██████████████      
                  ██  ██████          ██    ██      ██    ██      ████████    
  ██████████████  ██████████  ██  ██  ██        ████      ██  ██  ██████  ██  
  ██          ██    ████    ██████████      ██  ████████  ██      ████  ██    
  ██  ██████  ██  ████    ██████████  ██  ██    ████    ████████████    ██    
  ██  ██████  ██  ██  ██  ██        ██  ████        ████████  ██    ██        
  ██  ██████  ██    ██  ████  ██  ████  ██  ██    ██  ██  ██    ████████████  
  ██          ██      ████  ██        ██    ██        ██      ██  ██  ██████  
  ██████████████    ██        ██  ████    ████      ██    ██  ██    ██    ██  
                                                                              
Please scan the QR code to log in.
Please press confirm on your phone.
Loading the contact, this may take a little while.
Login successfully as IPA-Bot

In [6]:
# If click Kernel -> Interupt, then hot re-login is possible:
# itchat.auto_login(hotReload=True)


In [7]:
#######################################################################
### Optional Adhoc Test
### Send Enquire_Parcel status through WeChat
#######################################################################

# Locate User / 获取分别对应相应键值的用户。

# friend = itchat.search_friends(name=u'IPA-Bot')
friend = itchat.search_friends(name=u'白黑')

for i in range(0, len(friend)):
    print('NickName  : %s' % friend[i]['NickName'])
    print('Alias A-ID: %s' % friend[i]['Alias'])
    print('RemarkName: %s' % friend[i]['RemarkName'])
    print('UserName  : %s' % friend[i]['UserName'])

# Picture / 图片
reply = itchat.send_image(msg_filename, friend[0]['UserName']) 
print(reply['BaseResponse']['ErrMsg'])


NickName  : 白黑
Alias A-ID: 
RemarkName: 
UserName  : @f9f491d00285c688e41e618b45c0f05a
请求成功

* Interactive Conversation : Auto Mode / 自定义复杂消息处理,例如:信息存档、回复群组中被@的消息

Parcel Enquiry module


In [8]:
# 如果收到[TEXT, MAP, CARD, NOTE, SHARING]类的信息,会自动回复:
@itchat.msg_register([TEXT, MAP, CARD, NOTE, SHARING]) # 文字、位置、名片、通知、分享
def text_reply(msg):
    print(u'[ Terminal Info ] Thank you! 谢谢亲[嘴唇]我已收到 I received: [ %s ] %s From: %s' 
          % (msg['Type'], msg['Text'], msg['FromUserName']))
    itchat.send(u'Thank you! 谢谢亲[嘴唇]我已收到\nI received:\n[ %s ]\n%s' % (msg['Type'], msg['Text']), msg['FromUserName'])
    
    ######################################################################################################
    # Parcel Enquiry module
    ######################################################################################################
    if "Parcel" in msg['Text'] or "parcel" in msg['Text']: # Check parcel enquiry command keyword: Parcel
        msg_filename = Enquire_Parcel(msg['Text'].replace('Parcel ','').replace('parcel ','')) # Extract Parcel ID from message
        itchat.send_image(msg_filename, msg['FromUserName']) 
    ######################################################################################################

        
# 如果收到[PICTURE, RECORDING, ATTACHMENT, VIDEO]类的信息,会自动保存:
@itchat.msg_register([PICTURE, RECORDING, ATTACHMENT, VIDEO]) # 图片、语音、文件、视频
def download_files(msg):
    msg['Text'](msg['FileName'])
    print(u'[ Terminal Info ] Thank you! 谢谢亲[嘴唇]我已收到 I received: [ %s ] %s From: %s' 
          % ({'Picture': 'img', 'Video': 'vid'}.get(msg['Type'], 'fil'), msg['FileName'], msg['FromUserName']))
    itchat.send(u'Thank you! 谢谢亲[嘴唇]我已收到\nI received:', msg['FromUserName'])
    return '@%s@%s' % ({'Picture': 'img', 'Video': 'vid'}.get(msg['Type'], 'fil'), msg['FileName'])


# 如果收到新朋友的请求,会自动通过验证添加加好友,并主动打个招呼:幸会幸会!Nice to meet you!
@itchat.msg_register(FRIENDS)
def add_friend(msg):
    print(u'[ Terminal Info ] New Friend Request 新朋友的请求,自动通过验证添加加好友 From: %s' % msg['RecommendInfo']['UserName']) 
    itchat.add_friend(**msg['Text']) # 该操作会自动将新好友的消息录入,不需要重载通讯录
    itchat.send_msg(u'幸会幸会!Nice to meet you!', msg['RecommendInfo']['UserName'])

    
# 在群里,如果收到@自己的文字信息,会自动回复:
@itchat.msg_register(TEXT, isGroupChat=True)
def text_reply(msg):
    if msg['isAt']:
        print(u'[ Terminal Info ] Group@Info 在群里收到@自己的文字信息: %s From: %s %s' 
              % (msg['Content'], msg['ActualNickName'], msg['FromUserName']))
        itchat.send(u'@%s\u2005I received: %s' % (msg['ActualNickName'], msg['Content']), msg['FromUserName'])

In [9]:
itchat.run()


Start auto replying.
[ Terminal Info ] Thank you! 谢谢亲[嘴唇]我已收到 I received: [ Text ] Parcel DZ140053182NZ From: @f9f491d00285c688e41e618b45c0f05a
[ Enquie Parcel ] ID : DZ140053182NZ | File Name : results/DZ140053182NZ-2019-07-25-12m27m42s.png
[ Terminal Info ] New Friend Request 新朋友的请求,自动通过验证添加加好友 From: @f9f491d00285c688e41e618b45c0f05a
[ Terminal Info ] Thank you! 谢谢亲[嘴唇]我已收到 I received: [ Note ] You have added 白黑 as your WeChat contact. Start chatting! From: @f9f491d00285c688e41e618b45c0f05a
[ Terminal Info ] Thank you! 谢谢亲[嘴唇]我已收到 I received: [ Text ] Parcel DZ140053180NZ From: @f9f491d00285c688e41e618b45c0f05a
[ Enquie Parcel ] ID : DZ140053180NZ | File Name : results/DZ140053180NZ-2019-07-25-12m31m09s.png
[ Terminal Info ] Thank you! 谢谢亲[嘴唇]我已收到 I received: [ Text ] Parcel DZ140053180NZ From: @f9f491d00285c688e41e618b45c0f05a
[ Enquie Parcel ] ID : DZ140053180NZ | File Name : results/DZ140053180NZ-2019-07-25-12m31m58s.png
Bye~

Try the parcel enquiry bot by yourself

  1. Scan below QR code to add friend IPA-Bot in WeChat
  2. Send a message to IPA-Bot, e.g. Parcel DZ140053180NZ



In [10]:
# Click Kernel -> Interupt, then logout
itchat.logout() # 安全退出


Out[10]:
<ItchatReturnValue: {'BaseResponse': {'ErrMsg': '请求成功', 'Ret': 0, 'RawMsg': 'logout successfully.'}}>

Workshop Enhancements:

  • Extend the parcel enquiry function to group chat when IPA-Bot is being @ : if msg['isAt']
  • Create a database/dataframe/csv for book keeping and administration
  • Process parcel enquiry for eligible customer only, by referring to a database.