2016-08-12 47 views
2

我试图批量编辑ZenDesk上个人宏的签名,唯一的方法就是通过API。所以我写了这个快速的Python脚本来尝试做到这一点:为什么我的ZenDesk宏正在更新,但实际上没有改变?

import sys 
import time 
import logging 
import requests 
import re 

start_time = time.time() 

# Set up logging 
logger = logging.getLogger() 
log_handler = logging.StreamHandler(sys.stdout) 
log_handler.setFormatter(logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s - %(funcName)s - line %(lineno)d")) 
log_handler.setLevel(logging.DEBUG) 
logger.addHandler(log_handler) 
logger.setLevel(logging.DEBUG) 

def doTheGet(url, user, pwd): 
     response = requests.get(url, auth=(user + "/token", pwd)) 

     if response.status_code != 200: 
       logger.error("Status: %s (%s) Problem with the request. Exiting. %f seconds elapsed" % (response.status_code, response.reason, time.time() - start_time)) 
       exit() 

     data = response.json() 
     return data 

def doThePut(url, updated_data, user, pwd): 
     response = requests.put(url, json="{'macro': {'actions': %r}}" % updated_data, headers={"Content-Type": "application/json"}, auth=(user + "/token", pwd)) 

     if response.status_code != 200: 
       logger.error("Status: %s (%s) Problem with the request. Exiting. %f seconds elapsed" % (response.status_code, response.reason, time.time() - start_time)) 
       exit() 

     data = response.json() 
     return data 

def getMacros(): 
     macros = {} 

     data = doTheGet("https://mydomain.zendesk.com/api/v2/macros.json", "[email protected]", "111tokenZZZ") 

     def getMacros(macro_list, page, page_count): 
       if not page: 
         for macro in macro_list: 
           if macro["restriction"] and macro["active"]: 
             if macro["restriction"]["type"] == "User": 
               macros[macro["id"]] = macro["actions"] 
       else: 
         for macro in macro_list: 
           if macro["restriction"] and macro["active"]: 
             if macro["restriction"]["type"] == "User": 
               macros[macro["id"]] = macro["actions"] 

         page_count += 1 
         new_data = doTheGet(page, "[email protected]", "111tokenZZZ") 
         new_macs = new_data["macros"] 
         new_next_page = new_data["next_page"] 
         getMacros(new_macs, new_next_page, page_count) 


     macs = data["macros"] 
     current_page = 1 
     next_page = data["next_page"] 
     getMacros(macs, next_page, current_page) 
     return macros 

def updateMacros(): 
     macros = getMacros() 

     regular = "RegEx to match signature to be replaced$" #since some macros already have the updated signature 

     for macro in macros: 
       for action in macros[macro]: 
         if action["field"] == "comment_value": 
           if re.search(regular, action["value"][1]): 
             ind = action["value"][1].rfind("\n") 
             action["value"][1] = action["value"][1][:ind] + "\nNew signature" 

     return macros 

macs = updateMacros() 

for mac in macs: 
     doThePut("https://mydomain.zendesk.com/api/v2/macros/%d.json" % (mac), macs[mac], "[email protected]", "111tokenZZZ") 

现在,一切都正在按预期运行,并且我没有得到任何错误。当我在ZenDesk上查看宏并按上次更新对其进行排序时,我确实看到脚本做了某些事情,因为它们显示为今天的最后更新。但是,他们没有任何变化。我确定我发送的数据是,编辑的是updateMacros正在完成其工作)。我确保请求发回OK响应。所以我发送更新的数据,回复200响应,但the response sent back显示了我之前的宏,没有任何变化。

发生在我身上的唯一可能是在某种程度上是错误的是我发送的数据格式或类似的东西。但即使如此,我期望的反应不是200,然后...

我在这里错过什么?

回答

4

看起来你双重编码JSON数据在PUT请求等:

response = requests.put(url, json="{'macro': {'actions': %r}}" % updated_data, headers={"Content-Type": "application/json"}, auth=(user + "/token", pwd)) 

JSON的参数期望的对象,它然后忠实地编码为JSON,并发送作为所述请求的主体;这仅仅是一种方便;落实是根本,

if not data and json is not None: 
     # urllib3 requires a bytes-like body. Python 2's json.dumps 
     # provides this natively, but Python 3 gives a Unicode string. 
     content_type = 'application/json' 
     body = complexjson.dumps(json) 
     if not isinstance(body, bytes): 
      body = body.encode('utf-8') 

(来源:https://github.com/kennethreitz/requests/blob/master/requests/models.py#L424

由于该值总是通过json.dumps()过去了,如果你通过代表已编码的JSON字符串,将自身编码:

"{\'macro\': {\'actions\': [{\'field\': \'comment_value\', \'value\': [\'channel:all\', \'Spiffy New Sig that will Never Be Saved\']}]}}" 

ZenDesk,在被给予JSON的时候并没有期待,更新了updated_at这个字段,并且......没有别的。你可以通过传递一个空字符串来验证它 - 相同的结果。

请注意,您还依赖于Python的repr格式来填充您的JSON;这可能也是一个坏主意。取而代之的是,我们只是重建我们的宏观目标,并让请求对其进行编码:

response = requests.put(url, json={'macro': {'actions': updated_data}}, headers={"Content-Type": "application/json"}, auth=(user + "/token", pwd)) 

这应该做你的期望。

相关问题