見出し画像

PythonでZendesk情報を取得する

Pythonでチケット情報を取得してSlackへ通知する方法です。メモ備忘録枠です。

GASはライブラリなど使用せず、ZendeskのAPIから取得可能です。

一方でPythonの場合は、Googleスプレッドシートへ転記する場合は、gspreadというライブラリを使います。

Zendeskへのアクセスは Zenpyというクライアントライブラリが有名です。今回はこちらを使用しています。

Slackへの投稿はSlack Web Clientを使用します(Python用SDKらしい)。

ローカルのディレクトリ

├── config
│   ├── config.json
│   └── service_account.json
├── modules
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── lib.cpython-38.pyc
│   │   └── modules.cpython-38.pyc
│   ├── lib.py
└── get_ticket_info.py

各種ライブラリを使用するためのおまじない

# Zenpyを利用するおまじない
creds = {
    "token": ZENDESK_TOKEN,
    "email": ZENDESK_EMAIL,
    "subdomain": SUB_DOMAIN
}
zenpy_client = Zenpy(**creds)
return zenpy_client


# gspreadを利用するおまじない
gc = gspread.service_account(filename="./config/service_account.json")
wb = gc.open_by_key(SHEET_KEY) 
ws = wb.worksheet('sheet_name')
return ws


# SlackClientを利用するおまじない
client = WebClient(token=SLACK_API_TOKEN)
return {
    "client": client,
    "channel_id": SLACK_CHANNEL_ID
}

各種必要な設定値は別ファイルから読み込み

PATH = os.getcwd()
CONFIG = PATH + "/config/config.json"
with open(CONFIG, "r", encoding="utf-8") as f:
    json_load = json.load(f)

SLACK_API_TOKEN = json_load["client"]["slackToken"]
SLACK_CHANNEL_ID = json_load["client"]["slackChannelId"]
ZENDESK_TOKEN = json_load["client"]["zendeskToken"]
ZENDESK_EMAIL = json_load["client"]["zendeskEmail"]
SUB_DOMAIN = json_load["client"]["zendeskSubdomain"]
SHEET_KEY = json_load["client"]["sheetKey"]

上記をlib.pyというモジュールで切り出し

lib.py

import os
import datetime
import json

import gspread
from zenpy import Zenpy
from slack import WebClient
from slack.errors import SlackApiError


PATH = os.getcwd()
CONFIG = PATH + "/config/config.json"
with open(CONFIG, "r", encoding="utf-8") as f:
    json_load = json.load(f)

SLACK_API_TOKEN = json_load["client"]["slackToken"]
SLACK_CHANNEL_ID = json_load["client"]["slackChannelId"]
ZENDESK_TOKEN = json_load["client"]["zendeskToken"]
ZENDESK_EMAIL = json_load["client"]["zendeskEmail"]
SUB_DOMAIN = json_load["client"]["zendeskSubdomain"]
SHEET_KEY = json_load["client"]["sheetKey"]



def slack_lib():
    client = WebClient(token=SLACK_API_TOKEN)
    return {
        "client": client,
        "channel_id": SLACK_CHANNEL_ID
    }


def zendesk_lib():
    creds = {
        "token": ZENDESK_TOKEN,
        "email": ZENDESK_EMAIL,
        "subdomain": SUB_DOMAIN
    }
    zenpy_client = Zenpy(**creds)
    return zenpy_client


def gspread_lib():
    gc = gspread.service_account(filename="./config/service_account.json")
    wb = gc.open_by_key(SHEET_KEY) 
    ws = wb.worksheet('sheet_name')
    return ws


Searching the API

Zenpyでは Searching the API を使うとZendesk上の検索演算子がそのまま使えるようです。

チケットの作成日を期間指定したり、ステータスの指定が可能です。

yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
today = datetime.datetime.now()
for ticket in zenpy_client.search("zenpy", created_between=[yesterday, today], type='ticket', minus='negated'):
    print ticket

あとはGASと同じように取得したチケットをGoogleスプレッドシートへ転記したりSlackへ投稿したりできます。

import os
import datetime
import json
import pandas as pd
from slack.errors import SlackApiError

import sys
sys.path.append('modules')
import lib


DAYS = 60
START_DAY = datetime.datetime.now() - datetime.timedelta(DAYS)
TODAY = datetime.datetime.now()
TICKET_STATUS = "closed"


def main():
    list = get_ticket_list()
    print("\nlistの中身\n--------\n{}".format(list))
    set_values(list)
    post_to_slack(list)
    

def get_ticket_list():
    zenpy_client = lib.zendesk_lib()
    ticket_list = list() 
    for ticket in zenpy_client.search("test", created_between=[START_DAY, TODAY], type="ticket", status=TICKET_STATUS):
        ticket_list.append([ticket.url, ticket.id, ticket.status, ticket.created_at])
    return ticket_list


def set_values(list):
    ws = lib.gspread_lib()
    for value in list:
        ws.append_row(value)


def post_to_slack(values):
    client = lib.slack_lib()
    try:
        res = client["client"].chat_postMessage(
            channel=client["channel_id"],
            text="通知テスト"
        )
        if res["ok"] == True :
            ts_id = res["ts"]
            for value in values:
                maped_list = map(str, value)  
                strings = ",".join(maped_list).replace(",", "\n")
                res = client["client"].chat_postMessage(
                    channel=client["channel_id"],
                    thread_ts=ts_id, text=strings
                )
    except SlackApiError as e:
        print(e.response["error"])


if __name__=='__main__':
    main()


※Slackへの投稿は特に意味はなく、デモの一環です。



この記事が気に入ったらサポートをしてみませんか?