# frozen_string_literal: true require 'sinatra' require 'json' require 'yaml' # Configure Sinatra set :port, ENV['PORT'] || 4567 set :bind, '::' # Load responses from YAML file RESPONSES = YAML.load_file('responses.yml') DEFAULT_LANGUAGE = 'en' # Helper method to get a random "no" response def get_no_response(lang = DEFAULT_LANGUAGE) language = RESPONSES[lang] || RESPONSES[DEFAULT_LANGUAGE] language['responses'].sample end # Helper method to get language name def get_language_name(lang) language = RESPONSES[lang] || RESPONSES[DEFAULT_LANGUAGE] language['name'] end # Helper method to get available languages def get_available_languages RESPONSES.map { |code, data| { code: code, name: data['name'] } } end # Helper method to determine language from request def determine_language(params, headers) # Priority: URL parameter > Accept-Language header > default return params[:lang] if params[:lang] && RESPONSES[params[:lang]] # Parse Accept-Language header if headers['HTTP_ACCEPT_LANGUAGE'] accepted_langs = headers['HTTP_ACCEPT_LANGUAGE'] .split(',') .map { |lang| lang.split(';').first.downcase.strip } # Check for exact matches first accepted_langs.each do |lang| return lang if RESPONSES[lang] # Check for language family matches (e.g., 'nb' or 'nn' -> 'no') case lang when /^zh/ # Chinese variants return 'zh' when /^es/ # Spanish variants return 'es' when /^hi/ # Hindi variants return 'hi' when /^ar/ # Arabic variants return 'ar' when /^bn/ # Bengali variants return 'bn' when /^pt/ # Portuguese variants return 'pt' when /^ru/ # Russian variants return 'ru' when /^ja/ # Japanese variants return 'ja' when /^tr/ # Turkish variants return 'tr' when /^ko/ # Korean variants return 'ko' when /^fr/ # French variants return 'fr' when /^de/ # German variants return 'de' when /^vi/ # Vietnamese variants return 'vi' when /^it/ # Italian variants return 'it' when /^th/ # Thai variants return 'th' when /^pl/ # Polish variants return 'pl' when /^nl/ # Dutch variants return 'nl' when /^ur/ # Urdu variants return 'ur' when /^ms/ # Malay variants return 'ms' when /^nb|nn/ # Norwegian Bokmål/Nynorsk return 'no' when /^sv/ # Swedish variants return 'sv' when /^da/ # Danish variants return 'da' when /^is/ # Icelandic variants return 'is' when /^fi/ # Finnish variants return 'fi' when /^fo/ # Faroese variants return 'fo' when /^se|smi/ # Sami variants return 'smi' end end end DEFAULT_LANGUAGE end # Root endpoint - returns HTML by default get '/' do lang = determine_language(params, request.env) no_response = get_no_response(lang) case request.accept.first&.to_s when %r{application/json} content_type :json { answer: no_response, language: lang, language_name: get_language_name(lang), timestamp: Time.now.iso8601 }.to_json else content_type :html erb :index, locals: { no_response: no_response, language: lang, language_name: get_language_name(lang), available_languages: get_available_languages } end end # Languages endpoint - list available languages get '/languages' do content_type :json { languages: get_available_languages, default: DEFAULT_LANGUAGE, timestamp: Time.now.iso8601 }.to_json end # Explicit JSON endpoint with language support get '/api/no' do lang = determine_language(params, request.env) content_type :json { answer: get_no_response(lang), language: lang, language_name: get_language_name(lang), timestamp: Time.now.iso8601, service: 'No as a Service', version: '2.0.0' }.to_json end # Language-specific endpoint get '/api/no/:lang' do lang = params[:lang] unless RESPONSES[lang] content_type :json status 404 return { error: 'Language not supported', requested: lang, available: get_available_languages.map { |l| l[:code] }, timestamp: Time.now.iso8601 }.to_json end content_type :json { answer: get_no_response(lang), language: lang, language_name: get_language_name(lang), timestamp: Time.now.iso8601, service: 'No as a Service', version: '2.0.0' }.to_json end # Health check endpoint get '/health' do content_type :json { status: 'healthy', languages_loaded: RESPONSES.keys.size, timestamp: Time.now.iso8601 }.to_json end # Catch-all route for any other endpoint get '/*' do lang = determine_language(params, request.env) no_response = get_no_response(lang) case request.accept.first&.to_s when %r{application/json} content_type :json { answer: no_response, language: lang, language_name: get_language_name(lang), timestamp: Time.now.iso8601 }.to_json else content_type :html erb :index, locals: { no_response: no_response, language: lang, language_name: get_language_name(lang), available_languages: get_available_languages } end end __END__ @@index No as a Service

No as a Service

The definitive multilingual API for negative responses

Currently in: <%= language_name %> <% if language == 'no' %>🇳🇴<% end %> <% if language == 'sv' %>🇸🇪<% end %> <% if language == 'da' %>🇩🇰<% end %> <% if language == 'is' %>🇮🇸<% end %> <% if language == 'fi' %>🇫🇮<% end %> <% if language == 'fo' %>🇫🇴<% end %>
<%= no_response %>

API Usage

JSON API: GET /api/no or GET /api/no/:lang

Languages: GET /languages

URL Parameter: ?lang=<%= language %>

Accept-Language header supported

Health Check: GET /health