Zendesk Guideでは記事のフィードバックをYes / Noの取得機能しかない。そこで、Guideのテーマを編集し、Yes / Noを入力した後にフィードバックのコメントを入れられるようにする。また、このフォームから送信されるデータをZendeskには貯められないので、SlackのAPIを使って一旦受け取る。
最初は、Zapierで受け取ればGoogle Sheet / Slackに書き出すといったことも可能になるかなと思ったが、PremiumプランだったのでSlackに直接書き出す。Zapierでも基本的にはやり方はどうようになる。
Slackの設定
下記記事に従ってIncoming Webhookが取得できるのでそれをメモしておき、下記のZendesk側で設定する。
Zendesk Guideの設定
下記を編集する。
- article_page.hbs
- script.js
- script.css
article_page.hbs
article_page.hbsの編集前の下記箇所を
<div class="article-votes"> <span class="article-votes-question">{{t 'was_this_article_helpful'}}</span> <div class="article-votes-controls" role='radiogroup'> {{vote 'up' role='radio' class='button article-vote article-vote-up'}} {{vote 'down' role='radio' class='button article-vote article-vote-down'}} </div> <small class="article-votes-count"> {{vote 'label' class='article-vote-label'}} </small> </div>
下記で上書きする。ホームページ内で変更したい箇所は直接編集する。特に変更した方がよさそうな場所にはコード内でコメントしておく
<div class="article-votes"> <div class="article-votes-title">Was this article helpful?</div> <div class="article-votes-btns-wrap"> # 役に立った。などに変えても良い <span class="article-votes-btn article-votes-btn-yes js--article-votes-btn" data-type="yes">Yes, thanks</span> <span class="article-votes-btn article-votes-btn-no js--article-votes-btn" data-type="no">Not really</span> </div> <form class="article-votes-form-yes js--form-yes"> <textarea class="article-votes-textarea"></textarea> # 特にどのようなところが参考になりましたか?など <label class="article-votes-textarea-label">What did you like about this article? (optional)</label> <button class="article-votes-button js--btn-send-yes" type="submit">Submit feedback</button> </form> <form class="article-votes-form-no js--form-no"> <div class="article-votes-form-sorry-text"> Sorry about that! Why wasn't the article helpful? </div> <div class="article-votes-labels"> # どのようなところが参考になりませんでしたか?など。選択肢は追加しても良い <label><input type="radio" name="feedback-selection" value="This article didn't answer my questions or solve my problem" checked> This article didn't answer my questions or solve my problem </label> <label><input type="radio" name="feedback-selection" value="I found this article confusing or difficult to read"> I found this article confusing or difficult to read </label> <label><input type="radio" name="feedback-selection" value="I don't like how the feature works"> I don't like how the feature works </label> <label><input type="radio" name="feedback-selection" value="Other"> Other </label> </div> <div class="article-votes-form-no-textarea-wrap"> <div class="article-votes-form-no-textarea"> <textarea class="article-votes-textarea article-votes-textarea-no" placeholder="Your comments will help us to improve the article!"></textarea> <label class="article-votes-form-no-textarea-label"></label> </div> </div> <button class="article-votes-button js--btn-send-no" type="submit">Submit feedback</button> # 自社のヘルプセンターのリンクに変える <div class="article-more-questions"> If you would like to get a reply from the Support team, please create a ticket <a href="https://help.xxxx.com/hc/en-us/requests/new?referer=help-center-article">here</a> </div> </form> <div class="article-votes-feedback-success">Thank you for your feedback!</div> <div class="article-votes-feedback-fail">Error! Please try later...</div> </div>
syle.css
syle.cssの末尾に下記を追加
.article-vote-down-explanation { display: none; } .article-votes-form-yes { display: none; } .article-votes-form-yes.visible { display: block; } .article-votes-form-no { display: none; } .article-votes-form-no.visible { display: block; } .article-votes-btn { cursor: pointer; border: 1px solid rgba(5, 0, 56, 1); color: rgba(5, 0, 56, 1); border-radius: 4px; padding: 6px 20px; transition: background-color .12s ease-in-out, border-color .12s ease-in-out, color .15s ease-in-out; font-size: 12px; } .article-votes-btn.active { background: rgba(5, 0, 56, 1);; color: #fff; } .article-votes-btn-yes { margin-right: 10px; padding: 6px 16px; } .article-votes-title { margin-bottom: 14px; } .article-votes-btns-wrap { margin-bottom: 40px; } .article-votes-textarea { height: 85px; resize: none; margin-bottom: 14px; } .article-votes-textarea.validationError::-webkit-input-placeholder { /* Chrome */ color: #f2545b; } .article-votes-textarea.validationError:-ms-input-placeholder { /* IE 10+ */ color: #f2545b; } .article-votes-textarea.validationError::-moz-placeholder { /* Firefox 19+ */ color: #f2545b; opacity: 1; } .article-votes-textarea.validationError:-moz-placeholder { /* Firefox 4 - 18 */ color: #f2545b; opacity: 1; } .article-votes-form-yes { position: relative; padding: 21px 0 0; } .article-votes-textarea-label { font-size: 12px; position: absolute; top: 0; left: 10px; } .article-votes-form-no-textarea-wrap { position: relative; padding: 21px 0 0; } .article-votes-form-no-textarea-label { font-size: 12px; position: absolute; top: 0; left: 10px; } .article-votes-labels { display: flex; flex-direction: column; align-items: flex-start; } .article-votes-labels label { margin: 3px 0; } .article-votes-labels label input { margin-right: 5px; } .article-votes-button { background-color: rgba(5, 0, 56, 1); border: none; color: #fff; padding: 8px 16px; text-align: center; text-decoration: none; display: inline-block; font-size: 12px; border-radius: 4px; cursor: pointer; } .article-votes-button:focus { border: none; } .article-votes-btns-wrap.disabled .article-votes-btn { opacity: 0.6; pointer-events: none; cursor: default; } .article-votes-form-yes.disabled .article-votes-button { opacity: 0.6; pointer-events: none; cursor: default; } .article-votes-form-yes.disabled .article-votes-textarea { opacity: 0.6; pointer-events: none; cursor: default; } .article-votes-form-no.disabled .article-votes-button { opacity: 0.6; pointer-events: none; cursor: default; } .article-votes-form-no.disabled .article-votes-textarea { opacity: 0.6; pointer-events: none; cursor: default; } .article-votes-feedback-success { display: none; } .article-votes-feedback-success.active { display: block; } .article-votes-feedback-fail { display: none; } .article-votes-feedback-fail.active { display: block; } .article-votes-form-sorry-text { font-weight: 700; margin-bottom: 10px; } .article-votes-form-no .article-votes-button { margin-bottom: 20px; }
script.js
script.jsのdocument.addEventListener('DOMContentLoaded', function() {}
内の最後に入れる。
また、Zapierで取得したWebHookの設定をurlの変数で設定すること
//feedback form help center var articleVotesBtnsBlock = document.querySelector(".article-votes-btns-wrap"); var articleVotesBtns = document.querySelectorAll(".js--article-votes-btn"); var formYes = document.querySelector(".js--form-yes"); var formNo = document.querySelector(".js--form-no"); if(formNo) { var radioBtns = document.querySelectorAll("input[type='radio'][name='feedback-selection']"); var labvarextareaNo = formNo.querySelector(".article-votes-form-no-textarea-label"); var btnSendYes = document.querySelector(".js--btn-send-yes"); var btnSendNo = document.querySelector(".js--btn-send-no"); var userResponse = { subject: 'Help center feedback', url: document.location.href, responseType: 'yes', radioResponse: '-', description: '-', }; var itemSucces = document.querySelector(".article-votes-feedback-success"); var itemFail = document.querySelector(".article-votes-feedback-fail"); var date = new Date(); var commentPlaceholderText = 'Your comments will help us to improve the article!'; var commentPlaceholderErrorText = 'Please let us know how we can improve the article - leave your comment here!'; for (var i = 0; i < articleVotesBtns.length; i++) { articleVotesBtns[i].addEventListener('click', function(e){ e.preventDefault(); if(this.getAttribute('data-type') === 'yes') { setActiveBtn(); clearForm(); this.classList.add("active"); formNo.classList.remove("visible"); formYes.classList.add("visible"); } if(this.getAttribute('data-type') === 'no') { setActiveBtn(); clearForm(); this.classList.add("active"); formYes.classList.remove("visible"); formNo.classList.add("visible"); } }); } //submit btnSendYes.addEventListener('click', function(e){ e.preventDefault(); userResponse.description = formYes.querySelector(".article-votes-textarea").value; sendRequest(userResponse); }); btnSendNo.addEventListener('click', function(e){ e.preventDefault(); // userResponse for (var i = 0; i < radioBtns.length; i++) { userResponse.responseType = 'no'; if(radioBtns[i].checked){ userResponse.radioResponse = radioBtns[i].value; } userResponse.description = formNo.querySelector(".article-votes-textarea").value; } //user comment requaered validation if(userResponse.description.length > 0) { sendRequest(userResponse); } else { showValidationError(); } }); function showValidationError(){ //change placeholder for comment textarea var commentTextarea = formNo.querySelector(".article-votes-textarea"); if(commentTextarea !== undefined) { commentTextarea.placeholder = commentPlaceholderErrorText; //change placeholder color -> red commentTextarea.classList.add('validationError'); } } function sendRequest(userResponse) { var result = false; //block form setDisabledForm(); var request = new XMLHttpRequest(); # Webhookに書き換える var url = 'https://hooks.slack.com/services/xxx/xxx/xxxx' # 整形したかったらこちら var data = { text: date + '\n' + userResponse.responseType + '\n' + userResponse.radioResponse + '\n' + userResponse.description + '\n' + userResponse.url } request.open('POST', url); request.withCredentials = false; request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); request.addEventListener("readystatechange", function () { if (request.status === 200) { setCloseForm(); clearForm(); itemSucces.classList.add("active"); } else { setCloseForm(); clearForm(); } }); request.send('payload=' + JSON.stringify(data)); } function clearForm(){ formYes.querySelector(".article-votes-textarea").value = ''; for (var i = 0; i < radioBtns.length; i++) { if(i === 0 && radioBtns[i] !== undefined){ radioBtns[i].checked = true; } else { radioBtns[i].checked = false; } } var commentTextarea = formNo.querySelector(".article-votes-textarea"); commentTextarea.placeholder = commentPlaceholderText; //change placeholder color -> red commentTextarea.classList.remove('validationError'); commentTextarea.value = ''; labvarextareaNo.innerText = ''; } function setActiveBtn(){ for (var i = 0; i < articleVotesBtns.length; i++) { articleVotesBtns[i].classList.remove("active"); } } function setDisabledForm(){ articleVotesBtnsBlock.classList.add("disabled"); formYes.classList.add("disabled"); formNo.classList.add("disabled"); } function setCloseForm(){ formYes.classList.remove("visible"); formNo.classList.remove("visible"); } } });
結果
謝辞
上記スクリプトはhttps://help.miro.com/hc/en-us/を参考に作成しています。