Support APIQuick starts by stack

Quick start: Rails

Rails 7+, Ruby ≥ 3.0. About 15 minutes to a verified chat message.

bundle add gauge_support
export GAUGE_APP_ID=<app id> GAUGE_IDENTITY_SECRET=<identity secret> GAUGE_WEBHOOK_SECRET=<whsec_…>

1 and 3. One controller: app/controllers/gauge_controller.rb

current_user is your auth (Devise or your own).

class GaugeController < ApplicationController
  skip_forgery_protection only: :webhook # Gauge signs the request instead
  before_action :authenticate_user!, only: :token

  def token
    token = GaugeSupport.mint_token(
      ENV.fetch("GAUGE_IDENTITY_SECRET"),
      app_id: ENV.fetch("GAUGE_APP_ID"),
      user_id: current_user.id.to_s,
      integration: "customer",
      email: current_user.email
    )
    response.headers["Cache-Control"] = "no-store"
    render json: { token: token }
  end

  def webhook
    result = GaugeSupport.verify_webhook(ENV.fetch("GAUGE_WEBHOOK_SECRET"), request.raw_post, request.headers)
    return render(plain: result.reason, status: :bad_request) unless result.valid?

    event = result.event
    # write returns false when the id is already there (unless_exist): retries and resends repeat it.
    if Rails.cache.write("gauge-event:#{event["id"]}", true, unless_exist: true, expires_in: 1.day)
      Rails.logger.info("gauge #{event["event"]} #{event["id"]}")
    end
    head :ok
  end
end

config/routes.rb:

get "/gauge-token", to: "gauge#token"
post "/gauge/webhooks", to: "gauge#webhook"

2. The widget (your page)

<script src="https://widget.gauge.chat/v1/<version>/widget.js"
  integrity="sha384-<integrity>" crossorigin="anonymous" async></script>
<script>
  window.addEventListener('load', function () {
    window.PulseWebchat.init({
      apiUrl: 'https://app.gauge.chat/backend',
      connectionId: '<chat connection id>',
      supportMode: true,
      integration: 'customer',
      getToken: function () { // called on every open, so the token is always fresh
        return fetch('/gauge-token', { credentials: 'include' })
          .then(function (r) { return r.json(); })
          .then(function (j) { return j.token; });
      },
    });
  });
</script>

CSP: script-src https://widget.gauge.chat and connect-src https://app.gauge.chat wss://app.gauge.chat. Signed-out visitors: leave out getToken; they chat anonymously where the Integration allows it. Check my site (Developers → Support) fetches your page and tells you if the snippet, its integrity and the connection id are right.

4. Check it

  1. Sign in to your site as a test user (in the sandbox: Seed test customers, then sign in as test_customer_1), open the widget and send "hello". In the console the conversation shows the user's name and Verified. Not verified? Paste the JSON from /gauge-token into Developers → Support → Token checker: it names the rule that failed.
  2. Developers → Webhooks → your endpoint → Send test event, pick support.chat.message_created: the result says Delivered · 200 and your log shows the event id. Change one byte of the secret in your env and send again: your handler answers 400 bad_signature.

Server was down? Replay failed on the same page resends everything that did not land.

On this page