この記事は Ateam LifeDesign Advent Calendar 2023 の 4日目の記事です。
概要
コールセンターのお客様対応マニュアルを社内専用のWordPressにて管理していたのですが、
WordPressということもあり、下記の課題がありました。
- 表や強調などの装飾がhtmlで構成されており、知識を持つ専任の担当者が必要
- アップデートでの問題発生時、エンジニアが1日張り付きで対応
- 行き過ぎたプラグイン活用により、相性問題が多発
- また、問題発生時の要因特定に時間が必要
- 個人IDに対する権限管理が複雑で入社・異動・退職にて営業事務の工数を奪っていた
➡ (つまり)エンジニア・更新担当・営業事務すべての工数を減らしつつ、便利に使いたい
以上の問題を解決すべく、他社ツールを比較検討した結果、
Qiita Teamにて社内ナレッジを管理することといたしました。
選んだ理由
もちろん、Qiita Teamがエイチームグループの製品ということもありますが、
比較検討の際に重視した点は以下の通りです。
- 安価かつ、ユーザー数での課金など明瞭な価格設計
- "記事数"課金だと書きすぎ注意という謎規制ができてしまう
- お客様対応の途中で必要な記事を確認できるなど、十分な検索性を持つ
- メデイアファイル(画像やpdf、動画など)を記事内に埋め込める
- 特に、pdfがリンクではなく、埋込表示になることは必須
- 記事やアカウント管理にエンジニアが不要で、現場管理者に判断に委ねられる
- IP制限や権限管理などセキュリティ周りがしっかりとしている
- WordPressの既存記事を手動ではなく、システム的に一括移行できる
Qiita Teamは他社製品などのように「検索エンジンにすごくこだわってます!」といった、
何かに特化したプロダクトではない(と思う)のですが、すべてのことがバランスよくできることと、
グループ企業製品ということを抜きにしても安い料金設計であることからQiita Teamにいたしました。
記事移行の手順
Qiita TeamにはAPIがあるので記事の一括投稿は、
WordPressから記事データを抜き出してAPIで送れば良いです。
ただし、メデイアファイルは一括投稿できないので注意。
今回は、一旦メディアファイルはGoogle Driveに投稿し、GASを用いて埋込用URLを一括取得し(※)、
記事内のメディアタグと差し替えることで見れるようにしました。
※今回作成した、Google Driveにあるメディアファイルの埋込URLを一括取得するGASサンプルです。
指定したフォルダの下層すべてを取得します。
const getFileUrlsInFolderAndSubFolders = () => {
const folderId = 'ここに取得したいフォルダのIDを入力'; // 選択したフォルダ配下を一括取得
const folder = DriveApp.getFolderById(folderId); // DriveAppオブジェクトのgetFolderByIdメソッドを使用して、指定したIDのフォルダを取得
// CSVデータを作成します。
let csvData = '"Folder Path/File Name","URL"\n'; // CSVの1行目(ヘッダー)を定義します。
csvData += getFileUrlsInFolder(folder, folder.getName()); // フォルダ名を取得し、getFileUrlsInFolder関数に渡す
// CSVファイルを作成します。
const csvFile = DriveApp.createFile('FileUrls.csv', csvData); // DriveAppオブジェクトのcreateFileメソッドでCSVファイルを作成
Logger.log(`Created file: ${csvFile.getUrl()}`); // 作成されたファイルのURLをログに出力
}
const getFileUrlsInFolder = (folder, folderPath) => {
let csvData = ''; // csvDataを初期化します。
const files = folder.getFiles(); // folderオブジェクトのgetFilesメソッドでフォルダ内のファイル一覧を取得
while (files.hasNext()) { // hasNextメソッドを使ってファイルがあるかどうかを確認し、ファイルがある場合は、ループを続行
const file = files.next(); // nextメソッドで次のファイルを取得
const url = file.getUrl(); // getFileメソッドでファイルのURLを取得
// csvDataにファイルの情報(フォルダのパスとファイル名、ファイルのURL)を追加
csvData += `"${folderPath}/${file.getName()}","${url}"\n`; // フォルダ名に/を挿入してファイル名とURLを追加し、\nで改行
}
// サブフォルダを検索
const subFolders = folder.getFolders(); // folderオブジェクトのgetFoldersメソッドでサブフォルダの一覧を取得
while (subFolders.hasNext()) { // hasNextメソッドを使ってサブフォルダがあるかどうかを確認し、サブフォルダがある場合は、ループを続行
const subFolder = subFolders.next(); // nextメソッドで次のサブフォルダを取得
csvData += getFileUrlsInFolder(subFolder, `${folderPath}/${subFolder.getName()}`); // 再帰的にgetFileUrlsInFolder関数を呼び出す
}
return csvData; // csvDataを出力
}
こちらで埋込用URLを記載したCSVが出力されます。
なお、今後追加するものに関しては通常通り、エディタ記事にて添付してもらえれば問題ないです。
1番の難関
移行データが純粋なテキストデータだけであれば良いのですが、
表や強調表示などを含めて再現したかったため、
WordPressからはhtml形式で出力いたしました。
が! Qiita Teamではhtmlは使えません…。
そこで、
html形式 → Markdown形式
の変換を行いました。
ここではある程度のエンジニア工数を利用しましたが、
今の時代、セキュリティが許すのであれば、chatGPTでの変換が早そうです。
▼まとめ
移行後の結果
結論、問題なく使えています。
確かにWordPressに比べるとプラグインがない所もあり、機能性で劣る部分もあることは否定できませんが、クリティカルに「これがないと難しい」という機能は今のところ見つかっておりません。
また、Qiita Teamの仕様上、投稿記事の編集は「投稿者しか編集できない」もしくは「全員編集できる」の2択ですが、後者でも投稿や編集は上手く回っています(善意性によるものが大きいですが)。
使いやすくした小技
- 表を3カラム以上かつ長文で使っている記事が多く、Qiita Teamのデフォルト本文幅では正直見難かったため、
Chrome拡張機能で、Qiita Teamの幅のCSSを広げるものを作って配布しました。 - 記事の検索機能はありますが、SQL感がありオペレーターが毎回これを入力するのは手間そうでした
- この問題を解消するため、よく使う検索結果画面のURLをお知らせやリンク記事に貼り付けることで、ワンクリックでこの検索結果を見れるようにしています。
学び
- 本プロジェクトで長くかかったのは圧倒的にツールを比較・検討している段階ですが、
"機能"にフォーカスしていると「A社もいいけどB社もいい…」となりがちで決まりきりません。 - 費用がもしも決まっていなかったとしても、いっそ費用感を先に決めてからその費用感内で、
必須機能があるかを確認していく方がいいかと思いました。 - また、運用が軌道に乗るかどうかは導入者の動きやサポートにかかっている部分が大きいので、
ツールの性能よりも「このツールが正解かは分からないが、"自分が正解にする"」と
いった気概が重要だと思いました。 - 精神論のような教訓ではありますが、現場利用者はわからないことが無数に発生するので
頼れるサポート体制やマニュアルを設計しておくことは現実的にも重要です。
最後に(宣伝)
Qiita Teamでは無料トライアルが60日間行えるキャンペーンを2024年1月8日まで開催しているようです。
グループ会社の製品ではありますが、私自身はQiita Teamと特別な関係はありません。
が、Markdown自体がhtmlと比べると非開発者も書きやすく、
自由度高すぎて散漫しがちなスプレッドシートよりも向いているドキュメントもあると思います。
調べた限りだと料金も他社製品より安いため、
「あんまり費用かけられないけど、スプレッドシートでの情報共有は限界があるよな…」と感じている組織では、
第一歩の選択肢としてQiita Teamを選択しても良いのではないでしょうか。
(最悪、APIで記事ぶっこ抜いてお引越しできますしね! )