[Zendesk] ๋ฌธ์„œ API ์—ฐ๋™(export csv /json)
๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๋””์ง€ํ„ธ ๊ฟ€ํŒ

[Zendesk] ๋ฌธ์„œ API ์—ฐ๋™(export csv /json)

by ์ผ์ƒ์„ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค 2022. 2. 3.

์—…๋ฌด ์ค‘ Helpdesk ์ฝ˜ํ…์ธ ๋ผ๊ณ  ํ•˜์—ฌ FAQ ๊ด€๋ จํ•˜์—ฌ ์ž‘์„ฑํ•˜๋Š” ์ฝ˜ํ…์ธ ๊ฐ€ ์žˆ๋‹ค
์™ธ๊ตญ ํ”Œ๋žซํผ Zendesk๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ํ—ฌํ”„๋ฐ์Šคํฌ ์ฝ˜ํ…์ธ ๋ฅผ Articles ์ด๋ผ๊ณ  ๋ถ€๋ฅด๋ฉฐ
์ œํ’ˆ ๋ณ„๋กœ ๋ธŒ๋žœ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๊ฐ๊ฐ์˜ ์ฝ˜ํ…์ธ ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

์ข‹์€ ํ”Œ๋žซํผ์ด ์žˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ์ˆ˜๋ฐฑ ๊ฐœ์˜ ์ฝ˜ํ…์ธ  ๋ฆฌ์ŠคํŠธ๋ฅผ
๊ด€๋ฆฌํ•˜๊ธฐ๊ฐ€ ๋ถˆํŽธํ•œ ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•˜์˜€๊ณ  ๊ฒฐ๋ก ์ ์œผ๋กœ ๋ฌธ์„œ๋กœ ๋ณด๊ด€ํ•˜๋ ค๋ฉด Export๊ฐ€ ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค
์‰ฝ๊ฒŒ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•์„ ๊ตฌํ˜„ํ•˜๊ธฐ๋กœ ๋ง˜ ๋จน์—ˆ๋‹ค

์ดˆ์•ˆ์€ ๊ธ‰ํ•œ ๋ง˜์— ๋ˆˆ์— ๋ณด์ด๋Š” Python์œผ๋กœ ๊ตฌํ˜„ ํ•˜์˜€๊ณ  ํ•ด๋‹น ๋ฐฉ๋ฒ•์„ ๊ณต์œ ํ•˜๋ คํ•œ๋‹ค.
๊ฐ ๋ธŒ๋žœ๋“œ๋ณ„ Articles์„ ์–ด๋–ป๊ฒŒ ๋ถˆ๋Ÿฌ์˜ค๋Š”์ง€ ๋ชฐ๋ผ 3์‹œ๊ฐ„์„ ๊ณ ๋ฏผํ–ˆ๋Š”๋ฐ
๊ฒ€์ƒ‰ํ•ด์„œ ์ฐพ๊ธด ์–ด๋ ค์› ์ง€๋งŒ ์•Œ๊ณ  ๋ณด๋ฉด ์‰ฌ์šด ๋ถ€๋ถ„์ด๋ผ ํ•ด๋‹น ๋‚ด์šฉ์„ ๊ณต์œ ํ•˜๊ณ ์ž ํ•œ๋‹ค

(*2๋ฒˆ ์ฐธ์กฐ ํ›„ 1๋ฒˆ)


0. ์‹œ์ž‘ํ•˜๊ธฐ ์ „

Zendesk API ๊ฐ€์ด๋“œ (Help center) : https://developer.zendesk.com/rest_api/docs/help_center/articles
๊ฐœ๋ฐœ ํˆด : vs code
์‚ฌ์šฉ ์–ธ์–ด : python , json

 

1. ํŠน์ • ๋ธŒ๋žœ๋“œ Articles ์ถ”์ถœํ•˜๊ธฐ ( .csv )

import requests
import sys
import io
import os
import datetime
import csv

sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding = 'euc-kr')
sys.stderr = io.TextIOWrapper(sys.stderr.detach(), encoding = 'euc-kr')

# Credentials, please set to correct username and password
credentials = 'ID์ •๋ณด', '๋น„๋ฐ€๋ฒˆํ˜ธ'

# Your Zendesk URL
# ๋ธŒ๋žœ๋“œ domain ๊ธฐ์žฌ : ๋ธŒ๋žœ๋“œ๋ณ„ ์ฃผ์†Œ๋ฅผ ์•Œ์•„์•ผ ํ•ด๋‹น articles์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Œ
zendesk = 'https://{site-domain}.zendesk.com' 

#index ์ฒ˜๋ฆฌ
idx = 1
language = 'ko'

# Makes backup path
date = datetime.date.today()
backup_path = os.path.join(str(date), language)
if not os.path.exists(backup_path):
    os.makedirs(backup_path)

# For CSV logging
log = []

articles = zendesk + '/api/v2/help_center/{locale}/articles.json'.format(locale=language.lower())
sections = zendesk + '/api/v2/help_center/{locale}/sections.json'.format(locale=language.lower())
categories = zendesk + '/api/v2/help_center/{locale}/categories.json'.format(locale=language.lower())

# First retrive the sections and categories JSON data
response = requests.get(sections, auth=credentials)
if response.status_code != 200:
    print('Failed to retrieve sections with error {}'.format(response.status_code))
    exit()

sections = response.json()

response = requests.get(categories, auth=credentials)
if response.status_code != 200:
    print('Failed to retrieve categories with error {}'.format(response.status_code))
    exit()

categories = response.json()

# Begin the article process
while articles:
    response = requests.get(articles, auth=credentials)
    if response.status_code != 200:
        print('Failed to retrieve articles with error {}'.format(response.status_code))
        exit()

    data = response.json()

    for article in data['articles']:
        if article['body'] is None:
            continue
		
        #ํ™œ์„ฑํ™”๋œ ๊ฒŒ์‹œ๋ฌผ๋งŒ ๋ณด๊ธฐ
        if article['draft'] == True:
            continue
            
        for section in sections['sections']:
            if section['id'] == article['section_id']:
                sectionsname = section['name']
                categoriesid = section['category_id']

        for category in categories['categories']:
            if category['id'] == categoriesid:
                categoriesname = category['name']

        print('{id} copied!'.format(id=article['id']))
        #ํ•„์š”ํ•œ ์ •๋ณด (์„ค์ •)
        log.append((idx, categoriesname, sectionsname, article['title'], article['body'], article['html_url'], article['created_at'], article['edited_at']))
        idx = idx + 1
    articles = data['next_page']

# Write to CSV
filename = 'zendesk.csv'

with open(os.path.join(backup_path, filename), mode='w', encoding='utf-8') as f:
    writer = csv.writer(f)
    
    #์‹ค์ œ ํŒŒ์ผ์— ์“ธ๋•Œ ๊ฐ ํ•„๋“œ title
    writer.writerow( ('idx', 'Category', 'Section', 'Title', 'Body', 'Url', 'Create_date', 'Update_date') )
    
    for article in log:
        writer.writerow(article)

 

2. ๋ธŒ๋žœ๋“œ ๋ณ„ ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ

#brands ๋„๋ฉ”์ธ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ 
zendesk = 'https://{root-domain}.zendesk.com' #์  ๋ฐ์Šคํฌ ๋ธŒ๋žœ๋“œ ๋„๋ฉ”์ธ ์ž…๋ ฅ

#brand๋ณ„ ๋„๋ฉ”์ธ์„ ์ฐพ์•„์•ผ ๊ฐ ์ œํ’ˆ articles์— ๋Œ€ํ•œ request๋ฅผ ๋ฐ›์•„ ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.
brands = zendesk + '/api/v2/brands.json'.format(locale=language.lower())

response = requests.get(brands, auth=credentials)
if response.status_code != 200:
    print('Failed to retrieve sections with error {}'.format(response.status_code))
    exit()
#๋ธŒ๋žœ๋“œ ์ •๋ณด ํ™•์ธํ•˜๋Š” json
brands = response.json()

 

3. HTML ํ˜•ํƒœ๋กœ ์ €์žฅํ•˜๊ธฐ

# Reserved for HTML processing
title = '<h1>' + article['title'] + '</h1>'
filename = '{id}.html'.format(id=article['id'])

with open(os.path.join(backup_path, filename), mode='w', encoding='utf-8') as f:
     f.write(title + '\n' + article['body'])
        

 

! ์ตœ์ข… ์ฃผ์˜์ 

1. brands๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ์ผ ๊ฒฝ์šฐ ๊ฐ ๋ธŒ๋žœ๋“œ๋ณ„ domain์œผ๋กœ ๋“ฑ๋กํ•ด์•ผํ•œ๋‹ค. ๋‹จ, ์ •ํ™•ํ•œ domain ์ •๋ณด๋Š” json์„ ํ†ตํ•ด ๋ฐ›์•„์™€์•ผ ํ•œ๋‹ค
2. ๋‚˜๋Š” mac์—์„œ ๊ตฌํ˜„ํ•˜์˜€๋Š”๋ฐ windows์—์„œ csv๋ฅผ excel๋กœ ์—ด ๊ฒฝ์šฐ ์ธ์ฝ”๋”ฉ ์˜ค๋ฅ˜๊ฐ€ ์กด์žฌํ•œ๋‹ค

๋‚˜์˜ ์ตœ์ข… ๋ชฉ์ ์€ dbํ™” ์‹œ์ผœ์„œ ์ถ”๊ฐ€/์‚ญ์ œ๊นŒ์ง€ ๊ด€๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ณ , CS ํˆด์— ์ž˜ ๋…น์—ฌ ์‚ฌ์šฉ ๋˜์—ˆ์œผ๋ฉด ์ข‹๊ฒ ๋‹ค

 

๋Œ“๊ธ€