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
bundle add jwtSet 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.
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:
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:
Rails.application.routes.draw do
post "/api/ticketping-token", to: "ticketping_tokens#create"
endCall 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.
<% 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
- Sign in on localhost and run this in the browser console:
await (await fetch('/api/ticketping-token', {
method: 'POST',
headers: {
Accept: 'text/plain',
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
}
})).text()- Paste the token into the token validator under Settings → API → Identity secret. It shows the claims, or says exactly what to fix.
- 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
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.