Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
vendors:cisco:uc:ucce:finesse:bulk-create-reason-labels [2024/09/30 17:18] – removed - external edit (Unknown date) 127.0.0.1vendors:cisco:uc:ucce:finesse:bulk-create-reason-labels [2024/09/30 17:18] (current) – ↷ Page moved from vendors:cisco:uc:finesse:bulk-create-reason-labels to vendors:cisco:uc:ucce:finesse:bulk-create-reason-labels gerardorourke
Line 1: Line 1:
 +====== Bulk Create Reason Labels on CCE 12.X =====
  
 +  -Export Reason Labels from Finesse using the Finesse API - and save XML output as a XML file
 +  -Run Python script below and specify your Finesse XML files as your input file.
 +
 +<wrap hi>Note - I need to update so any System codes are skipped - but they should fail to be imported in any event!</wrap>
 +
 +
 +The script will automatically recognize if the Finesse Reason Label XML file is a Not Ready, Logout or Wrap up file.\\
 +It will then ask you to proceed and will create the reason labels in CCE.
 +
 +===== Finesse API to Export Reason Labels =====
 +====All Reason Codes====
 +https://ucce-finesse-a.lab2.purplepi.ie/finesse/api/ReasonCodes?category=NOT_READY\\
 +https://ucce-finesse-a.lab2.purplepi.ie/finesse/api/ReasonCodes?category=LOGOUT\\
 +====All Wrap Ups====
 +https://ucce-finesse-a.lab2.purplepi.ie/finesse/api/WrapUpReasons
 +
 +
 +==== Agent Retrieval of Reason Codes ====
 +Note - an Agent can also request reason codes - but by asking for ReasonCodes Within Its Team - such as below:
 +This will be a subset of all reason codes.
 +<code>
 +https://ucce-lab-finesse-a.mydomain.com/finesse/api/TeamResource/5000/ReasonCodes?category=ALL&nocache=1665676621185
 +</code>
 +===== CCE-BulkCreateReasonLabels.py Python Script =====
 +<file python CCE-BulkCreateReasonLabels.py>
 +# Copyright 2019 - Gerard O'Rourke - Purplepi.ie
 +
 +# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 +# documentation files (the "Software"), to deal in the Software without restriction, including without limitation
 +# the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
 +# permit persons to whom the Software is furnished to do so, subject to the following conditions:
 +# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
 +# Software.
 +
 +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 +# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 +
 +
 +# Import XML Parser Module
 +import xml.etree.cElementTree as ET
 +# import HTTP Module
 +import requests
 +
 +# Disable SSL warning
 +from requests.packages.urllib3.exceptions import InsecureRequestWarning
 +requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
 +
 +# Default Variables to use to import XML file and to connect to CCE API
 +CCEHost = "ucce-hds-a.lab2.purplepi.ie"
 +user = "[email protected]"
 +password = "myPa$$w0rd"
 +xmlfile = "ReasonCodes_NOT_READY_20191220.xml"
 +
 +
 +def press_y_to_continue():
 +    userinput = input("\nEnter 'y' if you want to continue?")
 +    if (userinput != "y"):
 +        print("User chose not to continue. Exiting now...")
 +        exit()
 +
 +
 +def WrapReasonLoop():
 +    category = "WRAPUP"
 +    code = ""
 +
 +    for elem in tree.findall(".//WrapUpReason/*"):
 +        if (elem.tag == "label"):
 +            label = elem.text
 +        if (elem.tag == "forAll"):
 +            forAll = elem.text
 +            CreateReasonLabel(category, code, label, forAll)
 +
 +
 +def ReasonCodeLoop():
 +    for elem in tree.findall(".//ReasonCode/*"):
 +        if (elem.tag == "category"):
 +            category = elem.text
 +            # print("category:", category)
 +        if (elem.tag == "code"):
 +            code = elem.text
 +            # print("code", code)
 +        if (elem.tag == "label"):
 +            label = elem.text
 +            # print("label", elem.text)
 +        if (elem.tag == "forAll"):
 +            forAll = elem.text
 +            # print("forAll", elem.text)
 +            CreateReasonLabel(category, code, label, forAll)
 +
 +
 +def CreateReasonLabel(category, code, label, forAll):
 +    headers = {'Content-type': 'application/xml'}
 +    wrapReasonXML = "<reasonCode><changeStamp>0</changeStamp><code>" + code + "</code><isGlobal>" + forAll + "</isGlobal><description></description><text>" + label + "</text><reasonType>" + category + "</reasonType><category>User-defined</category></reasonCode> "
 +    print("XML:", wrapReasonXML)
 +    try:
 +        response = requests.post(urlReasonLabel, auth=(user, password), verify=False, data=wrapReasonXML, headers=headers)
 +    except Exception as e:
 +        print(type(e))
 +        print(e)
 +        exit()
 +
 +    if (response.status_code != 201):
 +        print(
 +            "ERROR: Unable to create Reason Type: " + category + ", Reason Label: " + label + ". HTTP Status Code: " + str(
 +                response.status_code))
 +        print("\nError response Body:")
 +        print(response.text)
 +        if (response.status_code == 400):
 +            press_y_to_continue()
 +        if (response.status_code != 400):
 +            exit()
 +    if (response.status_code == 201):
 +        print("Successfully Created Reason Type: " + category + ", Reason Label: " + label)
 +
 +
 +# Main Application
 +print("-----------------------------------------------------------------------")
 +print("CCE Bulk Reason Label Script")
 +print("-----------------------------------------------------------------------")
 +
 +userinput = input("\nEnter the hostname of the CCE Admin Server or press enter to use the default [" + CCEHost + "]?")
 +if (userinput != ""):
 +    CCEHost = userinput
 +
 +userinput = input("Enter user of the CCE Admin API or press enter to use the default [" + user + "]?")
 +if (userinput != ""):
 +    user = userinput
 +
 +userinput = input("Enter password of the CCE Admin API or press enter to use the default [******]?")
 +if (userinput != ""):
 +    password = userinput
 +
 +userinput = input("Enter the XML input filename or press enter to use the default [" + xmlfile + "]?")
 +if (userinput != ""):
 +    xmlfile = userinput
 +
 +urlReasonLabel = "https://" + CCEHost + "/unifiedconfig/config/reasoncode"
 +
 +print("-----------------------------------------------------------------------")
 +print("CCE Hostname:", CCEHost)
 +print("CCE user:", user)
 +print("XML File:", xmlfile)
 +print("urlReasonLabel:",urlReasonLabel)
 +print("-----------------------------------------------------------------------")
 +
 +# Import Finesse 11.X Wrap Code XML file
 +# tree = ET.ElementTree(file="C:/Users/gerard/PycharmProjects/ReasonLabels/WrapUpReasons_20191220.xml")
 +try:
 +    tree = ET.ElementTree(file=xmlfile)
 +except Exception as e:
 +    print(type(e))
 +    print(e)
 +    exit()
 +
 +root = tree.getroot()
 +count_wraps = len(tree.findall(".//WrapUpReason/label"))
 +
 +# If input file is a WrapReason File
 +if (count_wraps > 0):
 +    print("Input File recognized as a Wrap-up Reasons File!!!")
 +    print("Number of Wrap-up Labels:", count_wraps)
 +    print("-----------------------------------------------------------------------")
 +    print("About to create " + str(count_wraps) + " wrapup reason labels...")
 +    press_y_to_continue()
 +    WrapReasonLoop()
 +    print("Finished!")
 +    exit()
 +
 +if (root.tag == "ReasonCodes"):
 +    count_reasoncodes = len(tree.findall(".//ReasonCode/label"))
 +    if (root.attrib.get('category') == "NOT_READY"):
 +        print("Input File recognized as a NOT_READY ReasonCode XML File!!!")
 +    if (root.attrib.get('category') == "LOGOUT"):
 +        print("Input File recognized as a LOGOUT ReasonCode XML File!!!")
 +    if (root.attrib.get('category') == "ALL"):
 +        print("Input File recognized as a ALL ReasonCode XML File!!!")
 +    if ((root.attrib.get('category') == "NOT_READY") or (root.attrib.get('category') == "LOGOUT") or (
 +            root.attrib.get('category') == "ALL")):
 +        print("Number of Reason Codes :", count_reasoncodes)
 +        print("-----------------------------------------------------------------------")
 +        print("About to create " + str(count_reasoncodes) + " reason codes...")
 +        press_y_to_continue()
 +        ReasonCodeLoop()
 +        print("Finished!")
 +        exit()
 +    print("Input File NOT recognized! Exiting...")
 +    exit()
 +
 +print("Not a valid Input file. Exiting now! ")
 +exit()
 +</file>
 +
 +
 +
 +===== Other Python Scripts ======
 +
 +Create Reason Code from a legacy system to a tech-refresh system (different Ids)
 +
 +<code python>
 +import requests # used for http requests
 +from requests.auth import HTTPBasicAuth
 +import sys # used for sys.exit
 +import urllib3 # 
 +import os #check / creating folders
 +urllib3.disable_warnings() #Surpress cert warnings
 +import xml.etree.ElementTree as ET
 +
 +url = 'http://localhost/legacy/reason-not-ready/reason-not-ready-5005.xml'
 +
 +tech_refresh_nr_codes = ["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","19","16","18","22","1","23","6","25","7","11","26","15","14","13"]
 +legacy_nr_code = ["20","36","32","18","21","77","78","16","57","42","79","63","80","40","23","26","65","58","67","68","46","70","62","81","76","82","25","66","64","59","60","71","72","73","74","83","88","92","93","94","95","102","103","96","97","98","104","99","101","100","105","106","107","108","109","110","111","112","19","86","75","22","1","87","6","90","69","11","91","15","14","13"]
 +
 +reason_code_id = []
 +
 +def get_not_ready(id):
 +    #basic = HTTPBasicAuth(finesseUsername, finessePassword)
 +    #response = requests.get(url, verify=False, auth=basic)
 +    response = requests.get(url)
 +    responseStatusCode = (response.status_code)
 +    responseText = response.text
 +    if (responseStatusCode == 200):
 +        #print(responseText)
 +        root = ET.fromstring(responseText)
 +        for uri in root.findall(".//uri"):
 +            reason_code_uri = uri.text
 +            #the component of the uri following the last forward slash.
 +            value = reason_code_uri.split('/')[-1]
 +            print (value)
 +            counter = 0
 +            for l_id,tr_id in zip(legacy_nr_code,tech_refresh_nr_codes):
 +                if l_id == value:
 +                    print (tr_id)
 +                    print (".")
 +                    reason_code_id.append(tr_id)
 +    else:
 +        print('failed')
 +    print (len(reason_code_id))
 +    if len(reason_code_id) > 0:
 +        xml='<ReasonCodes>'
 +        for id in reason_code_id:
 +            xml+='<ReasonCode><uri>/finesse/api/ReasonCode/' + id + '</uri></ReasonCode>'
 +        xml+='</ReasonCodes>'    
 +        print (xml)
 +        
 +get_not_ready(5000)
 +</code>