Skip to content

Commit

Permalink
Add new Help Scout integration and Beacon functionality (#304) (#308)
Browse files Browse the repository at this point in the history
* Added very basic initial functionality

* Implemented hmac hash checking (maybe?)

* Basic hello world to test signature validation in test deploy

* Add Help Scout secret

* Add more debugging

* Updated to latest version of typescript, fixed Help Scout signature validation

* Pushing some more changes to see how they look

* Make time zone questions required

* Testing some more

* Make timezone questions required

* Fix punctuation in dates

* Lots of Help Scout integration UI element improvements

* Finishing touches for Help Scout integration

* Help Scout Beacon support improvements

* Add info about Help Scout integration/Beacon to README

* Apparently you can't define secrets in both deployment.yaml and a Beehive yaml

* Remove package script that doesn't work

* Upgraded packages, including Handlebars

* Re-implemented Help Scout templates using Handlebars

* Show selected application/confirmation questions in Help Scout

* Cleanup Help Scout API security

* Remove extra lines

* A few final fixes and tweaks

* Make time zone questions required

* test file questions help scout view

* Fix file helpscout download URL

* actually fix help scout file links

* Remove some console.logs

* minor fixes

Co-authored-by: Evan Strat <evan10s@users.noreply.github.com>
Co-authored-by: Stephanie A <almeidasmail@gmail.com>

Co-authored-by: Evan Strat <evan10s@users.noreply.github.com>
Co-authored-by: Stephanie A <almeidasmail@gmail.com>
  • Loading branch information
3 people committed Sep 20, 2020
1 parent 85a0453 commit 589fbaf
Show file tree
Hide file tree
Showing 19 changed files with 667 additions and 117 deletions.
52 changes: 51 additions & 1 deletion README.md
Expand Up @@ -86,6 +86,12 @@ QUESTIONS_FILE | Specify a path for the `questions.json` file. (default: ./serve
THEME_FILE | Specify a path for the `theme.css` file, which will be loaded last at every page.
FAVICON_FILE | Path to the favicon file (default is no favicon).
FAVICON_FILE_BASE64 | Same as `FAVICON_FILE_BASE64` but the file is base64 encoded.
HELPSCOUT_INTEGRATION_ENABLED | Whether to enable the backend API endpoint that can provide a dynamic app for Help Scout (default: false)
HELPSCOUT_INTEGRATION_SECRET_KEY | A random, 40-character long string of letters, numbers, and symbols. Must also be entered in Help Scout; see the Setting Up Help Scout integration section for more information. (required if Help Scout integration is enabled)
HELPSCOUT_BEACON_ENABLED | Whether to show the Help Scout Beacon on certain frontend pages (default: false)
HELPSCOUT_BEACON_ID | Unique ID for the Beacon provided by Help Scout (required if Beacon functionality is enabled)
HELPSCOUT_BEACON_SUPPORT_HISTORY_SECRET_KEY | Secret key provided by Help Scout for the Beacon Support History option (required if Beacon functionality is enabled)



## Contributing
Expand All @@ -106,4 +112,48 @@ If you have some time and want to help us out with development, thank you! You c

## License

Copyright &copy; 2019 HackGT. Released under the MIT license. See [LICENSE](LICENSE) for more information.
Copyright &copy; 2020 HackGT. Released under the MIT license. See [LICENSE](LICENSE) for more information.

## Help Scout

Registration includes two features to enable deep integration with Help Scout, a service desk solution, allowing us to
provide better support to users requesting support.

- The **Help Scout Integration** allows registration to serve a Dynamic App for Help Scout to show additional information
about a user's application to a specific event, based on the email address they sent the email from.
- The **Help Scout Beacon** adds a small widget to user-facing pages requiring authentication making it super easy to
send an email asking for help, engage in live chat support (if enabled), or view knowledge base articles (if enabled).

### Help Scout Integration
(Note: The Help Scout dynamic app integration will not work if registration is being hosted from `localhost`. In other
words, you can't test local changes to the Help Scout integration functionality in registration and view them in Help Scout.)

To setup Help Scout integration:

1. Configure the 2 required environment variables for Help Scout integration, starting with `HELPSCOUT_INTEGRATION`
2. Create a new custom app in Help Scout
3. For **Content Type**, choose **Dynamic Content**
4. For **Callback Url**, enter `<URL to your registration instance>/api/helpscout/userInfo`
5. For **Secret Key**, enter the exact same value as set in the `HELPSCOUT_INTEGRATION_SECRET_KEY` environment variable
6. Once you get the integration working, turn off **Debug Mode** in Help Scout.
7. Pick the mailboxes you want the registration integration to appear in.

### Help Scout Beacon
To setup the Help Scout Beacon:

1. Make sure the `HELPSCOUT_BEACON_ENABLED` environment variable is set to `true`.
2. In Help Scout, go to Manage > Beacons and find or create a new Beacon.
3. First, find the Beacon ID. Go to the Installation tab of the Beacon settings and look for the part of the code (near the bottom)
that looks like `window.Beacon('init', '<THIS IS THE BEACON ID>')`.
4. Set the `HELPSCOUT_BEACON_ID` environment variable to the Beacon ID you just found.
5. Now go to the Contact settings page for your Beacon.
6. In the Contact Form setting, turn on the **Support history security** setting.
7. A **secure key** will appear. Set the `HELPSCOUT_BEACON_SUPPORT_HISTORY_SECRET_KEY` to this value.
8. That's all the required configuration on registration's end. However, make sure you check out all of the available customization
options for Beacons available in Help Scout. You can change the settings remotely through Help Scout without changing
any code or configuration in registration!

(Note: If you set the secure key environment variable but do not enable the **Support history security** setting for the Beacon
in Help Scout, the Beacon **will not** work and you'll see a network error in the console when you try to send a message through the Beacon.)


4 changes: 4 additions & 0 deletions client/helpscout/email_not_found.html
@@ -0,0 +1,4 @@
<h4>
<a href="mailto:{{email}}">{{email}}</a>
</h4>
<h4>There are no users in registration with this email</h4>
103 changes: 103 additions & 0 deletions client/helpscout/main.html
@@ -0,0 +1,103 @@
{{#*inline "listBlock"}}
<li class="c-sb-list-item">
<span class="c-sb-list-item__label">{{title}}
<span class="c-sb-list-item__text">{{> @partial-block}}</span>
</span>
</li>
{{/inline}}

{{#*inline "badge"}}
<span class="badge {{type}}">{{> @partial-block}}</span>
{{/inline}}

{{#*inline "applicationQuestionListBlock"}}
<li class="c-sb-list-item">
<span class="c-sb-list-item__label">App: {{title}}
<span class="c-sb-list-item__text">{{> @partial-block}}</span>
</span>
</li>
{{/inline}}

{{#*inline "confirmationQuestionListBlock"}}
<li class="c-sb-list-item">
<span class="c-sb-list-item__label">Confirmation: {{title}}
<span class="c-sb-list-item__text">{{> @partial-block}}</span>
</span>
</li>
{{/inline}}

<h4>
<a href="mailto:{{email}}">{{email}}</a>
</h4>

<h4>{{applicationBranch}}</h4>

<ul class="c-sb-list c-sb-list--two-line">
{{#if applied}}
{{#> listBlock title="Applied?"}}
To {{applicationBranch}} on {{applicationSubmitTime}}
{{/listBlock}}
{{else}}
{{#> listBlock title="Applied?"}}
No application
{{/listBlock}}
{{/if}}

{{#if confirmationBranch}}
{{#> listBlock title="Accepted?"}}
{{#if accepted}}
{{#> badge type="success"}}
Accepted
{{/badge}} ({{confirmationBranch}})
{{else}}
{{#> badge type="error"}}
Rejected
{{/badge}} ({{confirmationBranch}})
{{/if}}
{{/listBlock}}

{{#> listBlock title="Confirmed?"}}
{{#if confirmed}}
{{#if accepted}}
{{#> badge type="success"}}
Confirmed
{{/badge}}{{#if confirmationSubmitTime}} on {{confirmationSubmitTime}}{{/if}}
{{else}}
{{#> badge type="pending"}}
Confirmed
{{/badge}}
{{/if}}
{{else}}
No
{{/if}}
{{/listBlock}}
{{else}}
{{#if applied}}
{{#> listBlock title="Accepted?"}}
{{#> badge type="pending"}}
No decision
{{/badge}}
{{/listBlock}}
{{/if}}
{{/if}}
{{#each applicationQuestionsToShow}}
{{#> applicationQuestionListBlock title=this.name}}
{{#ifCond this.type "file"}}
<a href="{{../../rootURL}}/{{this.prettyValue}}">{{this.prettyValue}}</a>
{{else}}
{{this.prettyValue}}
{{/ifCond}}
{{/applicationQuestionListBlock}}
{{/each}}

{{#each confirmationQuestionsToShow}}
{{#> confirmationQuestionListBlock title=this.name}}
{{this.prettyValue}}
{{/confirmationQuestionListBlock}}
{{/each}}

{{#> listBlock title="Ground Truth UUID"}}
{{uuid}}
{{/listBlock}}
</ul>

2 changes: 0 additions & 2 deletions client/index.html
Expand Up @@ -170,7 +170,5 @@ <h2>Your status:</h2>
</div>
</section>
{{/sidebar}}
<script type="text/javascript">!function(e,t,n){function a(){var e=t.getElementsByTagName("script")[0],n=t.createElement("script");n.type="text/javascript",n.async=!0,n.src="https://beacon-v2.helpscout.net",e.parentNode.insertBefore(n,e)}if(e.Beacon=n=function(t,n,a){e.Beacon.readyQueue.push({method:t,options:n,data:a})},n.readyQueue=[],"complete"===t.readyState)return a();e.attachEvent?e.attachEvent("onload",a):e.addEventListener("load",a,!1)}(window,document,window.Beacon||function(){});
</script><script type="text/javascript">window.Beacon('init', 'e25770bc-77c7-4583-befd-17e37d0b59bc')</script>
</body>
</html>
2 changes: 2 additions & 0 deletions client/js/admin.ts
Expand Up @@ -598,6 +598,7 @@ const interstitialTypeSelect = document.getElementById("interstitial-type") as H

let emailRenderedArea: HTMLElement | ShadowRoot = document.getElementById("email-rendered") as HTMLElement;
let interstitialRenderedArea: HTMLElement | ShadowRoot = document.getElementById("interstitial-rendered") as HTMLElement;
// @ts-ignore
if (document.head.attachShadow) {
// Browser supports Shadow DOM
emailRenderedArea = emailRenderedArea.attachShadow({ mode: "open" });
Expand Down Expand Up @@ -991,6 +992,7 @@ let sendEmailButton = document.getElementById("sendEmail") as HTMLButtonElement;
let batchEmailSubject = document.getElementById("batch-email-subject") as HTMLInputElement;
let batchEmailEditor = new EasyMDE({ element: document.getElementById("batch-email-content")! });
let batchEmailRenderedArea: HTMLElement | ShadowRoot = document.getElementById("batch-email-rendered") as HTMLElement;
// @ts-ignore
if (document.head.attachShadow) {
// Browser supports Shadow DOM
batchEmailRenderedArea = batchEmailRenderedArea.attachShadow({ mode: "open" });
Expand Down
13 changes: 13 additions & 0 deletions client/partials/sidebar.html
Expand Up @@ -34,3 +34,16 @@ <h1>{{siteTitle}}</h1>
{{> @partial-block }}
</main>
</div>
{{#unless unauthenticated}}
{{#if helpscout.beaconEnabled}}
<script type="text/javascript">!function(e,t,n){function a(){var e=t.getElementsByTagName("script")[0],n=t.createElement("script");n.type="text/javascript",n.async=!0,n.src="https://beacon-v2.helpscout.net",e.parentNode.insertBefore(n,e)}if(e.Beacon=n=function(t,n,a){e.Beacon.readyQueue.push({method:t,options:n,data:a})},n.readyQueue=[],"complete"===t.readyState)return a();e.attachEvent?e.attachEvent("onload",a):e.addEventListener("load",a,!1)}(window,document,window.Beacon||function(){});
</script><script type="text/javascript">
window.Beacon('init', "{{helpscout.beaconId}}");
window.Beacon('identify', {
name: "{{user.name}}",
email: "{{user.email}}",
signature: "{{helpscout.signature}}"
})
</script>
{{/if}}
{{/unless}}
2 changes: 2 additions & 0 deletions deployment.yaml
Expand Up @@ -15,6 +15,8 @@ secrets:
- GROUND_TRUTH_ID
- GROUND_TRUTH_SECRET
- STORAGE_ENGINE_OPTIONS
- HELPSCOUT_INTEGRATION_SECRET_KEY
- HELPSCOUT_BEACON_SUPPORT_HISTORY_SECRET_KEY

env:
STORAGE_ENGINE: gcs
Expand Down

0 comments on commit 589fbaf

Please sign in to comment.