こんにちは。RITの関です。
ZENDESKのアプリを作成したのでその方法を紹介します。
基本的には下記の公式ドキュメントと
https://developer.zendesk.com/documentation/apps/getting-started/overview/
下記のZENDESK公式ブログ
https://developerblog.zendesk.com/getting-started-zaf-next-js-4d1f83dae815
の通りにそのままやっているだけなのですが、何かの参考になれば幸いです。
完成イメージ
組織のexternal_idを画面上から更新できるアプリを作成しました
ZAF initして作られるZENDESKアプリ側のコードは殆どいじっておらず、下記の様に作っています。
①ZENDESKアプリの読み込み先をNextjsで書かれたシステムのURLに指定(例: https://test-app/test_zendesk_app )
②Nextjs側でUIを作成(例: \pages\test_zendesk_app.tsx に色々書く)
③Nextjsでボタンを押された際にZENDESK APIにpatchリクエストをしてデータを更新
zat new する
Zendesk Apps Tools (ZAT)はrubyのgemで作られているので、ご自身のPCにrubyとZAT gemを入れます Installing and using ZAT | Zendesk Developer Docs
その後に、適宜作業用のディレクトリを作って、その中でzat new --scaffoldを実行します Building your first Support app - Part 1: Laying the groundwork | Zendesk Developer Docs
適宜emailなどを入力するとデフォルトのZENDESKアプリが出来ます。
ZENDESKアプリを動かしてみる
--scaffoldした場合、manifest.jsonは/srcの中に入っています。 なので、cd srcでsrcフォルダに移り、そこでzat serverをするとデフォルトアプリを動かすことが出来ます。
localhost:4567に接続するよう言われるので接続するとこんなのが出てくる l
ZENDESKアプリを表示する
今回は下記を参考にZENDESKアプリを作成するので、編集するものはmanifest.jsonのみです。 localhostで作成したページを表示したいので、localhostの該当ページのURLを挿入し、ZENDESKの組織のページに表示したいのでlocationもorganization_sidebarに変更します。
そしてchange_organization_idのURLに該当する箇所に適当なコードを書いてみます
change_organization_id.tsx
import { NextPage } from 'next'; import React from 'react'; const ChangeOrganizationId: NextPage = () => { return <div>hogedayo</div>; }; export default ChangeOrganizationId;
無事組織フィールドに表示されました!
ZENDESKアプリからexternal_idを変更できるようにする
先程作成したchange_organization_idの中身を、external_idを差し替えできるようなフォームに書き換えたのが下記コードです
change_organization_id.tsx
import { NextPage } from 'next'; import React, { useEffect, useState } from 'react'; import { useZafClient } from '@/App/Service/ZafClient'; import { Button, Col, Container, Form, Row } from 'react-bootstrap'; interface ZendeskOrganization { organization: OrganizationObj; } interface OrganizationObj { id: number; tags: string[]; name: string; domains: string; details: string; notes: string; externalId: string; sharedTickets: boolean; sharedComments: boolean; } const ChangeOrganiztionId: NextPage = () => { const client = useZafClient(); const [newExternalId, setNewExternalId] = useState<string>(''); const [organization, setOrganization] = useState<OrganizationObj>(); useEffect(() => { if (!client) return; client.get('organization').then(function (res: ZendeskOrganization) { setOrganization(res.organization); }); }, [client]); if (!client) return <p>読込中</p>; if (!organization) return <p>organizationがありません</p>; const options = { url: `/api/v2/organizations/${organization.id}`, data: JSON.stringify({ 'organization': { 'external_id': newExternalId, }, }), contentType: 'application/json', type: 'PUT', }; const onSubmit: React.FormEventHandler = async e => { e.preventDefault(); await client.request(options); }; return ( <Container className='bg-white' style={{ height: '220px' }}> <Form.Group as={Row} className='pt-3 align-items-center'> <Col xs={6}> <h5>現在のexternal_id</h5> </Col> <Col className='text-right' xs={6}> {organization.externalId} </Col> </Form.Group> <Form.Group as={Row} className='align-items-center'> <Col xs={6}> <h5>新しいexternal_id</h5> </Col> <Col xs={6}> <Form.Control placeholder='123456' className='mr-2' type='text' value={newExternalId} onChange={e => setNewExternalId(e.target.value)} /> </Col> </Form.Group> <div className='text-right'> <Button variant='primary w-100' onClick={e => onSubmit(e)}> 更新する </Button> </div> </Container> ); }; export default ChangeOrganiztionId;
コードを貼り付けてハイ終わりだと不明点が多すぎると思うので、上から順番に解説していきます。
const client = useZafClient();は
ZENDESKから組織情報を取得したり、ZENDESKにPUTリクエストをするといった、ZENDESKが用意しているメソッドを使用するために必要なコードです。
ZafClientはScriptタグを読み込む必要があり、同じpage内だとScriptを読み込んでくれないので、app.tsxとかの中に
import Script from 'next/script';
と
<Script type='text/javascript' src=’https://static.zdassets.com/zendesk_app_framework_sdk/2.0/zaf_sdk.min.js’ strategy='beforeInteractive' />
を入れることでScriptタグを読み込むようにする必要があります。
そして、ZafClient.tsxの中ではZafClientが読み込めるまで待って、読み込めたらsetClientするといった処理を書いています。
import { useEffect, useState } from 'react'; declare global { interface Window { ZAFClient: any; } } let zafClient: any = null; export function useZafClient() { const [client, setClient] = useState(zafClient); useEffect(() => { if (!client && typeof window.ZAFClient !== 'undefined') { zafClient = window.ZAFClient.init(); if (!zafClient) return; setClient(zafClient); zafClient.invoke('resize', { height: '220px' }); } }, [client]); return client; }
ZafClientを読み込むことで、下記の箇所でorganizationの情報をセット出来たり
useEffect(() => { if (!client) return; client.get('organization').then(function (res: ZendeskOrganization) { setOrganization(res.organization); }); }, [client]);
下記の箇所で該当組織へPUTリクエストを送れるようになっています。
const options = { url: `/api/v2/organizations/${organization.id}`, data: JSON.stringify({ 'organization': { 'external_id': newExternalId, }, }), contentType: 'application/json', type: 'PUT', }; const onSubmit: React.FormEventHandler = async e => { e.preventDefault(); await client.request(options); };
仕組みは今まで説明したとおりなので、あとはreturn内に新しいexternal_idを入れるようなフォームを作成すれば完成です!
本当なら送信結果が返ってくるので、成功/失敗のtry catchや、フォームのバリデーションなどを入れるべきですが、今回は簡易な説明をするために省略しています。
改めて完成イメージです。external_idが更新されることを確認いただけると思います。
これにて説明は異常です。ZENDESKアプリを作成するときの役に立てると幸いです。ありがとうございました!