tukaのブログ

気が向いた時に何か書きます

Zendesk Supportのチケット起票をWebhookでSlackに連携する(雑文&小ネタです)

今年から仕事で本格的に Zendesk というカスタマーサポートのSaaSを使い始めました。

何か新しいツールを使い始めると連携したくなってしまうのですが、ZendeskにはSlackインテグレーションがあり、有効にするとSlackから問い合わせチケットに関する通知や操作などができるようになります。

support.zendesk.com

↑にも記載があるけど具体的にインテグレーションではこんなことができそう。

  • Slackでのチケットイベント通知
  • チャンネルの構成(SupportグループごとのSlackチャンネルとの紐付け)
  • Slackから新規チケット作成
  • リクエスタの作成と割り当て
  • サイドカンバセーション
  • Slack用Answer Bot

問い合わせなどの受信に気づくきっかけとしてSlack連携は必須だったので、インテグレーションを試しましたがうまく行かず。

先ほどの記事をよく読むと制約があり、Slackの1ワークスペースにつきZendeskのサブドメインを1つしか登録することができない(※2020年12月現在)らしく、これに該当していました。

通知が出来ないのは困る、でもよく見るとインテグレーションは高機能すぎる(欲しいのは通知だけ)なので、Webhookで実現することにしました。

ZendeskのSlack通知に必要なこと

ざっくりだけどこんな感じ。

  • Slack で Incoming Webhook を作成
  • Zendesk で通知先とするターゲットを作成
  • ターゲットに通知するトリガを作成

Slack通知するためのターゲットを作成

管理 > 設定 > 拡張機能 を開き、ターゲットを追加します。 (もしかしたらZendeskを契約した時期やプランによってメニューが異なるかもしれません?)

f:id:tukaelu:20201229102805p:plain

Slackで作成した Incoming Webhook URL を設定します。この時、HTTPメソッドはPOST、コンテンツタイプをJSONにするのをお忘れなく。

f:id:tukaelu:20201229103008p:plain

ターゲット作成はこれで完了。

Slack通知するためのトリガを作成

設定 > ビジネスルール > トリガ から新しいトリガを追加します。

f:id:tukaelu:20201229103539p:plain

  • トリガ名
    • 任意
  • 説明
    • 任意
  • 条件
    • コメント = パブリック
  • アクション
    • ターゲットに通知 で先ほど追加したターゲットを選択

f:id:tukaelu:20201229104739p:plain

続いてターゲットに通知するメッセージデータをJSONで指定するのですが、今回は通知内容の見栄えを良くしたかったので Attachment 形式のメッセージを送信しようと思います。

そんな時に便利なのがSlackのメッセージビルダーです。

api.slack.com

メッセージを構成するJSONからSlackでの実際の見え方をチェックすることができるので、試しに以下を入力してプレビューで確認してみます。

{
  "attachments": [
      {
          "pretext": "pretext",
          "author_name": "{{ticket.requester.name}}",
          "author_link": "https://xxxxxx.zendesk.com/agent/users/{{ticket.requester.id}}/requested_tickets",
          "title": "{{ticket.title}}",
          "title_link": "{{ticket.link}}",
          "fields": [
              {
                  "title": "企業名",
                  "value": "{{ticket.organization.name}}",
                  "short": false
              },
              {
                  "title": "カスタムフィールド",
                  "value": "{{ticket.ticket_field_xxxxxxxxxxxx}}",
                  "short": false
              },
              {
                  "title": "本文",
                  "value": "{{ticket.latest_public_comment}}",
                  "short": false
              }
          ],
          "footer": "フッター文字列",
          "footer_icon": "https://example.com/path/to/icon.png"
      }
  ]
}

こんな感じ。

f:id:tukaelu:20201229110242p:plain

{{ticket.organization.name}} などのタグは Zendesk Support のプレースホルダなので、実際にPOSTされる際はトリガとなったチケットの情報が埋め込まれて通知されます。

どんなプレースホルダがあるかは ↓ で確認できます。

support.zendesk.com

メッセージビルダーでレイアウトの調整などが出来たら、あとはトリガ設定にJSONボディとして指定して完了です。

Slackに通知する際は、通知する項目やその公開範囲などに注意する必要がありますが、プレースホルダにはカスタムフィールド(独自のフォーム項目)も指定できるのでインテグレーションよりも柔軟にメッセージを構成できるのは嬉しいですね。

実際に僕も業務でWebhookを仕込んで通知をしているのですが、POSTされるデータサイズが大きすぎるとSlack側でエラーとなってしまうので、使用するプレースホルダがどの程度のサイズになるかなどは意識して組み立てるなど注意が必要です。

最後に

Zendeskには API なども用意されているので、このあたりも活用して業務効率を上げる取り組みなどもしていきたいなー。

今年は兎にも角にもZendeskと共にあった一年なので最後に小ネタでした。それでは。

近況

最近起きたイベント

  • ほぼ9割は在宅勤務になり、引きこもりになった
  • 7月末の会社の総会で表彰してもらった & 昇給した
  • Lambdaで動かしていたあれこれをNode.jsからGoに置き換えた
  • はてなブログの独自ドメインを解除した(ドメイン更新しない)
  • Gatsby + Netlifyで構築したブログのクローズを進めている
    • 近々記事はこちらにマージする
    • 代わりになにかペライチを作ろうとしている
  • 宅食サービスの利用しはじめた
  • mac miniをポチった
  • あまり体調が思わしくない…

最近買ったもの

  • 6-7年使用したカモメファンが劣化で所々破損してしまったのでサーキュレーターに買い替えた
  • 上下左右に首振ってくれるのがいい

  • 引越し後に雨が多く、浴室乾燥機がないので購入
  • サーキュレーターを当てるのに位置取りが難しい

  • 長らく使っていたP社のドライヤーが限界だったので買い替え
  • 風量が多いのでよい買い物をした

  • USB Type-C / HDMIのケーブルが欲しかったので購入
  • ディスプレイ付属のHDMIよりケーブルが柔らかいので配線がいい感じにできる

  • 炭酸水飲みすぎるので購入
  • ペットボトルのゴミが8割減ったのが体験良すぎる
  • 強炭酸水を作るとき、冷水使用&水量少なめにしないと溢れる

  • ワイヤレス充電 + スタンドの体験が良すぎた

  • やっていかねば…

在宅勤務する環境を整えてみた

新型コロナウイルスの影響で3月末頃から在宅勤務になり、自宅の作業環境を整えるのに買って良かったものをまとめてみた。

買ったもの

ディスプレイアーム

ディスプレイは iiyama XUB2492HSU-B2 という24インチのディスプレイを使っていて、 昇降式ではあるもののディスプレイ下にあるスタンド脚の存在が邪魔だったので2月末頃に購入。

購入価格は11,000円。ずっと迷っていたけど色々と体験が良くてもっと早く買えばよかった。

  • 良かった点
    • ディスプレイ直下に空間が出来るの最高
    • 正面位置以外に移動できるのもたまに気分転換になってとてもよい
    • 掃除が楽になるなどあらゆる面で満足度が高い
  • 悪かった点
    • どこまでディスプレイ位置を上げられるかポテンシャルがわからず関節部分を外してしまう(これは僕が悪そう…)

ディスプレイアームは価格・種類面で多々あるけど、引っかかることなくスムーズに動かせるのでとにかく満足している!

Webカメラ

mac本体にカメラがあるので正直なくてもいいんだけど、ランプが付いているカメラに正面で挑むのが気分的にアレなので買ってみた。 購入価格は6,800円くらいだったかな。

  • 良かった点
    • 価格の割に高画質で広角レンズ/オートフォーカス/プライバシーシャッターなど機能豊富でよい
  • 悪かった点
    • カメラがデバイスとして認識されていても稀に映らない時がある
    • ライティングでフォーカス位置が変わるのむずかしい…

稀に映らない件、Chromeのプロファイルで映る/映らないケースがあったりでよくわからないけど、OS再起動すると直る事が多いのでmacとの相性かも。

マイク

マイクは正直なくても全然よかったけど、揃えるならマイクも欲しいくらいのノリで買ってしまった感はある。 購入価格は6,000円。

  • 良かった点
    • 単一指向性にスイッチできるのでスピーカー(ディスプレイ)の前面に配置してもそこまで集音していないはず
    • マイクが正面にあるだけでテンション/緊張感が上がる。気持ちの問題。
  • 悪かった点
    • いまのところなし

ちなみにこのマイクはよだれいぬさんに教えてもらった!

マイクの効果は自分では感じられていないけど、たぶん効果はあるはずだ!

アウトドアチェア

アウトドアグッズ揃えようと思って欲しかったんだけど、少しでも外に出る(と言ってもベランダ…)機会を増やすために購入。

そして購入してから天気があまりよくないんだけど、青空の下で作業するのよさそう!

わりと座り心地よくてリビングのソファとかアウトドア用品で揃えてもいいかもとかちょっと思ってしまった。 まあソファと比較すると当然クオリティは落ちそうだけどポータビリティは上がっていいこともありそう!?

伊藤園 香り薫るむぎ茶 ティーバッグ

伊藤園 香り薫るむぎ茶 ティーバッグ 54袋×10本

伊藤園 香り薫るむぎ茶 ティーバッグ 54袋×10本

  • 発売日: 2016/05/30
  • メディア: 食品&飲料

この時期に買うと思わなかった麦茶のティーバッグ。

近所のスーパーで2Lペットのお茶や炭酸水を買っていたんだけど、この時期に購入の都度スーパーに通うのも微妙なのでティーバッグで毎朝作るようにしている。

毎朝というのもオフィスのフリードリンクがなくなってから水分を取る機会が減り、トイレに行かず座ったままでいることが多くなったため。 その日のお茶はその日のうちに消費するように心がけていて、コスパいいし健康にもいいので一石二鳥感がある。

ニトリ IH フライパン

www.nitori-net.jp

ずっと家にいるので毎日何かしら料理を作るようになった。

5年程使用しているティファールのフライパン、取っ手が取れるのは便利な反面、面倒くさくもあるので26cmと深型24cmを購入。

通販番組でやっているような焦げ付かないけどお高いものを長く使うより、ニトリで買って1年サイクルで買い換える方が料理体験はよさそうとあらためて痛感。

そしていま欲しい物…

せっかくなので今気になっているものもまとめてみる。

PCスタンド

とにかく腰が痛くてオフィスの椅子にどれほど助けられていたのかと痛感しつつ購入を検討している。 正直PCスタンドよりも良い椅子を買うべきなんだろうけどそんなお金もないので暫定的にこれが欲しい。

以前勤めていた会社でこれを使ったことがあり、腰が爆発しそうな時はわりと有効だった気がしているけどちょっと悩んでいる。

気分を変えるインテリア

ワークスペースの正面と右横が窓で、それなりにいい景色が見れてはいるんだけど何かが足りない気持ちでいる。

casie.jp

ずっと気になっている絵画をレンタルできるサブスクリプション。

IKEAとかFrancfrancで壁掛けを買うのもいいかなーと思ったりしながら悩んでいる。

fujifilmmall.jp

富士フィルムのウォールデコもよさそう。

昨年、SIGMA fp を購入したので自分が撮った写真をインテリアにするものいいかもな〜。

健康的なおやつ

普段そんなにお菓子食べないんだけど、在宅になってから食べるようになったのと近所のスーパーでおやつ買うとジャンキーになりがち。

ドライフルーツやナッツの量り売りもあるけど、トングで取るタイプの売り方は情勢に関わらずあまり衛生的ではないという思いがあって手が出ない…。

lp.snaq.me

友達が子供のために定期購入していて、評判も良かったのでずっと気になっているサブスク。

昨年のAWSサミットでいただいたおつまみもメッチャおいしかったんだよなーと思っていたら

syouさんのレポートを待って僕も契約してみよう😋

check-metaプラグインをアップデートしました(v0.1.1)

check-meta プラグインv0.1.1にバージョンアップしました。

github.com

前回のアップデートで追加したメタデータ同士の比較オプションですが、 今回のアップデートで期待値(Expected)にメタデータを指定した場合は、その値をローカルにキャッシュを行います。


メタデータ同士を比較する際は、実際値(Actual)を取得→期待値(Expected)を取得→比較のような流れになります。 この取得した期待値をキャッシュして、次回のチェックの際に期待値が取得できない場合は直前にキャッシュした値を参照します。


キャッシュの保存先は環境変数MACKEREL_PLUGIN_WORKDIRに従いますが、未指定だと/var/tmp/mackerel-agent/などになります。 こちらの配下にcheck-meta/check-meta-{ハッシュ文字列}.jsonのようなファイルを作成してキャッシュします。


例えば以下のようなメタデータ同士を比較するとします。


# {
#   "status": "Mackerel",
#   "expect_status": "mackerel"
# }

[plugin.checks.meta_test]
command = ["check-meta", "-n", "foobar", "-k", "status", "-K", "expect_status"]


キャッシュの内容は以下のようになります。

$ cat /var/tmp/mackerel-agent/check-meta/check-meta-56a8b39277323c32b6aeb18b465f1190.json | jq
{
  "options": [
    "-n",
    "foobar",
    "-k",
    "status",
    "-K",
    "expect_status"
  ],
  "expected": "mackerel",
  "updated_at": 1580604720
}


optionsは使用している項目ではないですが、どの設定のキャッシュかがわかるように保存しています。通常は意識しないですかね。

expectedが最新のメタデータの値、updated_atはキャッシュを保存した際のUNIXタイムスタンプです。 現時点ではキャッシュの有効期限チェックのオプションは設けていませんが、そんなオプションもゆるゆると追加していきます。

check-metaプラグインをアップデートしました(v0.1.0)

先日公開したcheck-metaプラグインをアップデートしました。

tukaelu.hatenablog.jp

現時点で最新版のv0.1.0では以下のオプションに対応しました。

それぞれさらっとご紹介です。


正規表現での比較(メタデータ値が文字列の場合)

v0.0.1ではメタデータの値が文字列型の場合は--expectedで指定した文字列との等価比較をしてましたが、--regexオプションを有効にすると正規表現としてマッチを行うようにしました。

Application Options:
  -n, --namespace=NAMESPACE            Uses the metadata for the specified namespace
  -k, --key=KEY                        The value matching the specified key is used for comparison
  -e, --expected=EXPECTED-VALUE        Compares with the specified expected value
      --regex                          Compare with regular expression if specified (Enable only for string type value)
 :

--regexオプションはメタデータの値が文字列以外の場合は作用しません。

(指定してもエラーになりません)


設定例はこんな感じ。

# GET /api/v0/hosts/<hostId>/metadata/namespace
# {
#   "key1": "value1",
#    :
# }
[plugin.checks.meta_match_regex]
command = ["/path/to/check-meta", "--namespace", "namespace", "--key", "key1", "--expected", "value[0-9]{1}", "--regex"]

check-logcheck-procsなどは--pettern正規表現を指定する形式なのに対し、必要な時にだけ正規表現として作用させるためにあえてフラグという選択をしました。


数値の大小比較(メタデータ値が数値の場合)

メタデータの値が数値型(JSONのnumber)の場合、actualを左辺、expectedを右辺として大小比較するフラグオプションを追加しました。

Application Options:
 :
    --gt   Compare as 'actual > expected' (Enable only for number type value)
    --lt   Compare as 'actual < expected' (Enable only for number type value)
    --ge   Compare as 'actual >= expected' (Enable only for number type value)
    --le   Compare as 'actual <= expected' (Enable only for number type value)
 :

設定例はこんな感じ。

# GET /api/v0/hosts/<hostId>/metadata/namespace
# {
#   "key1": "value1",
#   "key2": 1000,
#    :
# }
[plugin.checks.meta_match_regex]
command = ["/path/to/check-meta", "--namespace", "namespace", "--key", "key2", "--expected", "1000", "--le"]

比較オプションを複数指定した場合はエラーとなります。n以上、m以下の様な条件指定は現時点では非対応です。


メタデータ同士の比較

メタデータ同士の比較に対応しました:sparkles:

このプラグインに必要だなと真っ先に思った機能がメタデータ同士の比較でした。

オプションはこんな感じ。

Application Options:
 :
  -N, --compare-namespace=NAMESPACE    Uses the metadata for the specified namespace to compare
  -K, --compare-key=KEY                Uses the metadata value that matches the specified key as the expected value

比較に用いるメタデータのnamespaceとJSONのキーを指定し、メタデータ同士が同じ型ではない場合はエラーとなります。

またいずれかのオプションが指定されなかった場合は、actualな値のnamespaceもしくはJSONのキーを使用します。

リポジトリのREADMEのExampleに設定例を載せていますが、以下のようにkey1key4の値を比較する場合の定義はこのようになります。

# GET /api/v0/hosts/<hostId>/metadata/namespace
# {
#   "key1": "value1",
#    :
#   "key4": "value1",
# }
 :
## OK (compare with metadata)
[plugin.checks.meta_compare_metadata]
command = ["/path/to/check-meta", "--namespace", "namespace", "--key", "key1", "--compare-key", "key4"]

ちなみに前述の正規表現、数値の大小比較のオプションも組み合わせることが可能です。

チェック監視の条件はmackerel-agent.confに書くものでしたが、このプラグインの面白いところはAPI経由で監視条件をある程度コントロールできるところかなと思います。


まとめ

ゆるゆるとバージョンアップを続けておりますが、オプションが増えて少し便利になったかなと思います。

しかしまだAPIとの疎通ができなかった場合などの考慮に対応できていないので、次のバージョンアップではそちらにも対応しようと思います。不具合などありましたらIssueください!


メタデータが監視のみならず運用などにも使えるのではないか!と感じていただきつつ、活用していただけると!

Mackerelのホストメタデータをチェックするプラグインを作った

年明けに Mackerel のホストメタデータをチェックするプラグインを工作したのでご紹介です。

TL;DR

  • ホストに投稿されたメタデータをチェックするプラグインを作りました
  • メタデータは Mackerel API から更新できるので、監視結果を外部から操作できます
  • チェック監視の action と組み合わせると色々とできるかもしれません

Mackerel におけるプラグインとは…

そもそもの話ですが Mackerel には監視機能を拡張するためのプラグイン機構があり、大きく3つの分類があります。

メトリックプラグイン、チェックプラグインは主に監視に用いられるデータを、メタデータプラグインは Mackerel をレジストリとして登録するデータを扱うためのプラグインです。 そしてそれらのデータを mackerel-agent が Mackerel API への投稿を代理する仕組みになっています。

Mackerel ユーザーの方であればメトリックプラグイン、チェックプラグインは公式提供されているものがあるので、ご存知だったりすでにご利用いただいている方もいらっしゃるかと思います。

しかしメタデータプラグインは登録するためのインタフェースは用意されているのですが公式に提供しているものはなく、まだまだ機能としての認知度は低いですかね... :expressionless:

Mackerelのメタデータとは…

繰り返しになりますが Mackerel をレジストリ的に扱うための便利な機能で、ホスト/ロール/サービスに対してJSON形式のデータをAPI経由で投稿できます。

mackerel.io

ホストメタデータについては以下のページにあるように mackerel-agent の設定で簡単に扱えます!

mackerel.io

レジストリとして扱える点などからAnsibleやCapistranoといった各種自動化ツールと組み合わせることができる有用な機能のひとつなのではないかと思ってます!

作ったもの

そんなメタデータのうち、ホストに投稿されたメタデータの値をチェック監視するプラグインを実装しました。

github.com

利用するには、メタデータの監視をしたいホストにプラグインをインストールする必要があります。

ホストにログインして以下のコマンドを実行することで簡単にインストールできます。(mkrコマンドが必要です)

sudo mkr plugin install tukaelu/check-meta

以下はプラグインのUsageですが、以下のようなオプションが指定できます。

Usage:
  check-meta [OPTIONS]

Application Options:
  -n, --namespace= Uses the metadata for the specified namespace
  -k, --key=       The value matching the specified key is used for comparison
  -e, --expected=  Compares with the specified expected value

Help Options:
  -h, --help       Show this help message

メタデータはnamespace(名前空間)に対してJSONを登録することになるので、例えば hoge という名前空間に以下のようなメタデータを登録していたとします。

このメタデータfoo というキーに対する値が foo-value にであるかチェックするには以下のような指定をします。

[plugin.checks.meta-hoge-foo]
command = ["/path/to/check-meta", "--namespace", "hoge", "--key", "foo", "--expected", "foo-value"]

メタデータにはオブジェクト、配列、文字列、数値、真偽値、Nullを登録できますが、リリースした v0.0.1 では文字列、数値、真偽値に対応しています。

--expected に指定する値はメタデータに登録した値の型に併せて文字列、数値、真偽値を指定してください。型が一致しない場合などはUNKNOWNとなります。

便利な使い方

check-meta はチェックプラグインなので、もちろんチェック監視の結果に応じて任意のコマンドを実行できます。

mackerel.io

既存のチェックプラグインではサーバー内部の状態をチェックするものが多いですが、APIを介して外部からメタデータを更新できるというところがポイントだったりします :bulb:

例えば state というキーの値(bool)が true であることを監視し、不一致の場合に任意のコマンドを実行する設定は以下のようになります。

[plugin.checks.meta-hoge-foo]
command = ["/path/to/check-meta", "--namespace", "hoge", "--key", "state", "--expected", "true"]
check_interval = 5
action = { command = "bash -c '[ \"$MACKEREL_STATUS\" != \"OK\" ]' && /path/to/do_something"}

この state を外部から更新することで、任意のタイミングでコマンドを実行させることが可能です。(実行されるまでに時間差はあります)

action を利用する際の注意点としてメタデータが更新されない限りは繰り返しコマンドを実行してしまうので、 do_something の処理の中でメタデータを正しい値に更新する必要があります。 (チェックプラグインという観点から check-meta 自体にメタデータの更新処理は備えていません)

また check_interval で監視間隔に余裕を持たせるなどの考慮も必要かもしれませんね。

最後に

まだ基本的なチェックしか実装してないですが、メタデータ同士の値をチェックする機能や数値の大小比較など拡張していけたらと思います。

その他、アイデアやこうしたほうがいい的なIssueやPRをお待ちしております!

また感想もtwitterとかで貰えるとっ :pray:

Windowsイベントログをコマンドプロンプト(PowerShell)から作成する

例えば以下の様な条件のイベントログを発生させたいとします。

  • イベントの種類はApplication
  • イベントソースはHogeSystem
  • イベントタイプはError、イベントIDは100
  • メッセージはThis is a test event of HogeSystem (ErrCode=100)

その場合、PowerShellのコマンドレットで以下のような手順を踏む。

  • イベントビューアにイベントソースを作成(New-EventLog)
  • イベントソースに対してイベントログを書き込む(Write-EventLog)

実際のコマンドは以下のような感じ。

New-EventLog -LogName Application -Source "HogeSystem"
Write-EventLog -LogName Application -Source "HogeSystem" -EntryType Error -EventID 100 -Message "This is a test event of HogeSystem (ErrCode=100)"

以下、コマンドレットのちょいメモ。

New-EventLogコマンドレット

イベントビューアに新しいイベントログを作成する

Option Require Description
-LogName Y イベントタイプ(種類)を指定(System, Application, など)
-Source Y イベントソースを指定
-ComputerName N コンピュータ名を指定
-ParameterResourceFile N メッセージパラメータが格納されているリソースファイル(DLL)のパスを指定

Write-EventLogコマンドレット

Windowsイベントをログに記録する

Option Require Description
-LogName Y 記録するイベントタイプ(種類)を指定(System, Application, など)
-Source Y 記録するイベントソースを指定
-EventId Y 記録するイベントIDを指定
-Message Y 記録するイベントのメッセージを指定
-EntryType N 記録するイベントのレベルを指定
-Category N 記録するイベントのタスクのカテゴリーを指定
-ComputerName N イベントを記録するコンピュータ名を指定

Mackerelcheck-windows-eventlog プラグインの設定確認をする際に覚えておくと非常に便利!