feat: expose internal signals attribution API

This commit is contained in:
Sojan Jose
2026-06-26 14:31:27 -07:00
parent 4339e0ee0a
commit d5f46f922d
3 changed files with 68 additions and 0 deletions
+5
View File
@@ -555,6 +555,11 @@ Rails.application.routes.draw do
end
resources :email_channel_migrations, only: [:create]
end
if ChatwootApp.enterprise?
namespace :internal do
resources :accounts, only: [:index]
end
end
end
end
end
@@ -0,0 +1,52 @@
# frozen_string_literal: true
class Platform::Api::V1::Internal::AccountsController < ActionController::API
include RequestExceptionHandler
CONFIG_KEY = 'SIGNALS_PLATFORM_API_TOKEN'
DEFAULT_LIMIT = 100
MAX_LIMIT = 1000
before_action :authenticate_internal_token!
def index
@accounts = filtered_accounts.limit(limit)
end
private
def authenticate_internal_token!
return if internal_token.present? && secure_token_match?(request_token, internal_token)
render json: { error: 'Invalid access_token' }, status: :unauthorized
end
def request_token
bearer_token || request.headers[:api_access_token] || request.headers[:HTTP_API_ACCESS_TOKEN]
end
def bearer_token
request.authorization&.split&.then { |scheme, token| token if scheme&.casecmp('Bearer')&.zero? }
end
def internal_token
@internal_token ||= GlobalConfigService.load(CONFIG_KEY, nil)
end
def secure_token_match?(token, configured_token)
return false if token.blank? || configured_token.blank? || token.bytesize != configured_token.bytesize
ActiveSupport::SecurityUtils.secure_compare(token, configured_token)
end
def filtered_accounts
scope = Account.order(:created_at, :id)
scope = scope.where('created_at >= ?', Time.zone.at(params[:since].to_i)) if params[:since].present?
scope = scope.where('created_at <= ?', Time.zone.at(params[:until].to_i)) if params[:until].present?
scope
end
def limit
params.fetch(:limit, DEFAULT_LIMIT).to_i.clamp(1, MAX_LIMIT)
end
end
@@ -0,0 +1,11 @@
json.array! @accounts do |account|
json.id account.id
json.name account.name
json.created_at account.created_at
json.updated_at account.updated_at
json.status account.status
json.plan_name account.custom_attributes['plan_name']
json.custom_attributes account.custom_attributes
json.limits account.limits
json.marketing_attribution account.internal_attributes['marketing_attribution']
end