Ruby on Rails

Sign Ticketping identity tokens in Rails with the jwt gem.

You’ll add one controller action and one route. The example uses Devise’s authenticate_user! and current_user; with other auth, use your own equivalents.

Install the jwt gem

bash
bundle add jwt

Set the secret

Get the identity secret from Settings → API → Identity secret and set it in your server’s environment. It’s the same value everywhere.

bash
TICKETPING_IDENTITY_SECRET=tpis_...

ENV.fetch raises if it’s missing. If you keep secrets in Rails credentials instead, use Rails.application.credentials.ticketping_identity_secret.

Add the controller

app/controllers/ticketping_tokens_controller.rb:

ruby
class TicketpingTokensController < ApplicationController
  before_action :authenticate_user!

  def create
    claims = {
      sub: current_user.id.to_s,
      email: current_user.email.presence,
      name: current_user.name.presence,
      exp: Time.now.to_i + 300
    }.compact

    token = JWT.encode(claims, ENV.fetch("TICKETPING_IDENTITY_SECRET"), "HS256")
    render plain: token
  end
end

.compact drops email and name when they’re blank, because Ticketping refuses null claims.

Add the route

config/routes.rb:

ruby
Rails.application.routes.draw do
  post "/api/ticketping-token", to: "ticketping_tokens#create"
end

Call it from your layout

Rails checks the CSRF token on POST, so send it from the csrf-token meta tag that csrf_meta_tags renders. The Accept: text/plain header makes Devise answer 401 instead of redirecting to the sign-in page when the session has ended.

html
<% if user_signed_in? %>
<script>
  window.Ticketping ||= (...args) => (Ticketping.q ||= []).push(args)

  Ticketping('identify', {
    userId: <%= current_user.id.to_s.to_json %>,
    email: <%= current_user.email.to_json %>,
    name: <%= current_user.name.to_json %>,
    getToken: async () => {
      const res = await fetch('/api/ticketping-token', {
        method: 'POST',
        headers: {
          Accept: 'text/plain',
          'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
        }
      })
      if (!res.ok) throw new Error(`Ticketping token request failed (${res.status})`)
      return res.text()
    }
  })
</script>
<% end %>
<script src="https://widget.ticketping.com/v2/loader.js" data-key="pk_..." async></script>

Call Ticketping('logout') when the user signs out, for example from your sign-out button’s click handler.

Check that it works

  1. Sign in on localhost and run this in the browser console:
js
await (await fetch('/api/ticketping-token', {
  method: 'POST',
  headers: {
    Accept: 'text/plain',
    'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
  }
})).text()
  1. Paste the token into the token validator under Settings → API → Identity secret. It shows the claims, or says exactly what to fix.
  2. Reload and send a message. The dashboard shows it with the user’s name and a Verified badge.

A 422 means the CSRF token is missing.

Copy prompt for your AI coding agent

prompt
Add Ticketping identity verification (chat widget v2) to this Rails app.

Docs index: https://ticketping.com/llms.txt
This page as Markdown: https://ticketping.com/docs/identity-rails.md

1. bundle add jwt.
2. Create TicketpingTokensController exactly as on the docs page, using this app's auth (authenticate_user! /
   current_user or equivalent): claims { sub: current_user.id.to_s, email, name, exp: Time.now.to_i + 300 }.compact,
   JWT.encode(claims, ENV.fetch("TICKETPING_IDENTITY_SECRET"), "HS256"), render plain: token.
3. Add post "/api/ticketping-token", to: "ticketping_tokens#create" to config/routes.rb.
4. Add TICKETPING_IDENTITY_SECRET= to the env example file (or Rails credentials). Never commit the value.
5. In the application layout, for signed-in users only, add the queue stub and Ticketping('identify', { userId, email, name, getToken })
   where getToken POSTs with Accept: text/plain and the X-CSRF-Token header from the csrf-token meta tag, and returns res.text().
   Add the loader script with data-key="pk_..." and ask me for the publishable key. Call Ticketping('logout') on sign-out.
6. Tell me how to verify with the token validator at Settings → API → Identity secret.