# Examples of Custom Behavior

## Custom dial trigger

Rep.ai can be invoked by most HTML elements by adding an `onclick` attribute.

```markup
<button onclick="RepAI('dial')">Need live help?</button>
```

Or you can listen for the `click` event in JavaScript.

```javascript
var button = document.getElementById('my-button');
button.addEventListener("click", function() {
  RepAI("dial");
});
```

## Require permission before initializing

You can take the `RepAI("init")` snippet and call it at any point, including after the user has agreed to a permission (e.g. by clicking "accept" in a modal or banner.) However, **you still must keep the long part of the snippet that looks like `!function...` first**, in order to load the `RepAI` API.

Here's an example using a jQuery dialog, but it would work with any JavaScript framework.

```markup
<div id="dialog-confirm" title="Receive calls?">
  <p><span class="ui-icon ui-icon-alert" style="float:left; margin:12px 12px 20px 0;"></span>
  Would you like to opt-in to receiving calls from our team during your session?</p>
</div>

<script>
  // Inject the RepAI API.
  !function(w,d){function e(e,n){w.RepAI.q=w.RepAI.q||[],w.RepAI.q.push([e,n])}if(!w.RepAI){var t=function(n){for(var t=arguments.length,i=new Array(t>1?t-1:0),r=1;r<t;r++)i[r-1]=arguments[r];e(n,i)};["init","identify","dial","alert","bookMeeting","hide","show","expand","collapse","connect","disconnect"].forEach((function(i){t[i]=function(){for(var t=arguments.length,i=new Array(t),r=0;r<t;r++)i[r]=arguments[r];e(n,i)}})),w.RepAI=t}var s=d.createElement("script");s.id="rep-ai-script",s.src="https://cdn.servicebell.com/main.js",s.async=1;var i=d.getElementsByTagName("script")[0];i.parentNode.insertBefore(s,i)}(window,document);

  // Pop open jQuery dialog to confirm they're OK with being called.
  $(function () {
    $("#dialog-confirm").dialog({
      resizable: false,
      height: "auto",
      width: 400,
      modal: true,
      buttons: {
        Accept: function () {
          RepAI("init", "YOUR_CLIENT_KEY_HERE");
          $(this).dialog("close");
        },
        Decline: function () {
          $(this).dialog("close");
        },
      },
    });
  });
</script>
```

## Handling missed calls

If you want to trigger custom behavior after a visitor tries dialing but nobody answers their request, you can listen to the `sb:dialmiss` event.

Here's an example that directs the visitor to the contact page if they're missed:

```javascript
window.addEventListener("sb:dialmiss", function() {
  window.location.href = "/contact-us";
});
```

## Show expanded widget, hide on collapse

If you want to keep the widget hidden most of the time, but expand it to let the user decide if they want to call or book a meeting (depending on availability) without immediately dialing, you can do that with a combination of `RepAI` methods and events.

```javascript
// Show & expand the widget.
RepAI("show");
RepAI("expand");

// If the visitor closes it after expanding, hide it completely.
window.addEventListener("sb:collapse", () => {
  RepAI("hide");
});
```

## Listen for initialization or error

If Rep.ai is initialized and triggered as a core part of your user flow, you may want to handle the UX of a user encountering an error with widget initialization.

```javascript
// On clicking a button, initialize the widget and dial.
const button = document.getElementById("call-button");
button.addEventListener("click", () => {
  button.disabled = true;
  RepAI("init", "CLIENT_KEY_HERE");
  RepAI("dial");
  
  // Widget initialized correctly.
  window.addEventListener("sb:initialized", () => {
    button.disabled = false;
  });
  
  // Widget encountered a critical error.
  window.addEventListener("sb:error", (ev) => {
    button.disabled = false;
    alert("Failed to start a call! Please contact support.");
    console.log("What happened?!", ev.detail);
  });
});
```
