Support APIQuick starts by stack

Quick start: Laravel

Laravel 10+, PHP ≥ 8.1. About 15 minutes to a verified chat message.

composer require gauge/support
# .env
GAUGE_APP_ID=<app id>
GAUGE_IDENTITY_SECRET=<identity secret>
GAUGE_WEBHOOK_SECRET=<whsec_…>

1 and 3. One controller: app/Http/Controllers/GaugeController.php

<?php

namespace App\Http\Controllers;

use Gauge\Support\Gauge;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

class GaugeController extends Controller
{
    public function token(Request $request)
    {
        $user = $request->user();
        $token = Gauge::mintToken(env('GAUGE_IDENTITY_SECRET'), env('GAUGE_APP_ID'), (string) $user->id, 'customer', [
            'name' => $user->name,
            'email' => $user->email,
        ]);
        return response()->json(['token' => $token])->header('Cache-Control', 'no-store');
    }

    public function webhook(Request $request)
    {
        $result = Gauge::verifyWebhook(env('GAUGE_WEBHOOK_SECRET'), $request->getContent(), $request->headers->all());
        if (!$result->valid) {
            return response($result->reason, 400);
        }
        $event = $result->event;
        // add() is false when the id is already there: retries and resends repeat it.
        if (Cache::add('gauge-event:' . $event['id'], true, now()->addDay())) {
            Log::info('gauge', ['event' => $event['event'], 'id' => $event['id']]);
        }
        return response('', 200);
    }
}

In production read the values through config/services.php rather than env() (config caching). routes/web.php:

use App\Http\Controllers\GaugeController;

Route::get('/gauge-token', [GaugeController::class, 'token'])->middleware('auth');
Route::post('/gauge/webhooks', [GaugeController::class, 'webhook'])
    ->withoutMiddleware([\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken::class]);

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