Monday 26 June 2017

Generate random meaningful word, sentence or paragraph in Rails.

Sometimes we need generate randome meaningful sentences or paragraph for our app. We can acheive it in rails app with literate_randomizer gem.

So, in Gemfile-


gem 'literate_randomizer'


Run bundle

Now, this will provide LiterateRandomizer global Randommizer instance as LiterateRandomizer.global

We can use it simply like this -

    a) Generate word

		> LiterateRandomizer.word
		
		=> "Early"


		
		 > LiterateRandomizer.sentence

		 => "Surely we have believed."


    c) Generate paragraph

		> LiterateRandomizer.paragraph

		 => "Two hours later. ILLINGWORTH laughing and I. Meantime we should open the glare of the moon which. Faced by their own 			downfall. Anything more than actual specimen in this account of the dark indicate vegetable. While we should. Such is like two 			half-breeds from my return to mitigate. A fellow-countryman in his chair. Written upon the precipice we might there was no."


You can do customization in LiterateRandomizer global Randommizer instance.

As example -


	 > LiterateRandomizer.paragraph(:sentences => 2, :words => 5)

	 => "Visitin my house ready for. To-night however which took a!"

Saturday 17 June 2017

Convert speech to text using watson api's in Rails

The Watson api's Speech to Text service of IBM® provides an API that lets you add speech transcription capabilities to your applications. To transcribe the human voice accurately, the service leverages machine intelligence to combine information about grammar and language structure with knowledge of the composition of the audio signal.

To get service credentials, follow these steps:

    1. Log in to Bluemix at https://bluemix.net. If you don't have an account, sign   up here for a 30-day free trial.

    2. Create an instance of the service:

        a) In the Bluemix Catalog, scroll down to Services and select the Speech To Text service from Watson.

        b) Under Add Service, type a unique name for the service instance in the Service name field. For example, type my-service-name. Leave the default values for the other options.

        c) Click Create.

    3. Copy your credentials:

        a) On the left side of the page, click Service Credentials to view your service credentials.

        b) Copy username and password from these service credentials and paste them into the watson.yml file

Make a watson.yml file in config

In watson.yml

default: &default
   auth_url: https://stream.watsonplatform.net/authorization/api/v1/token?url=https://stream.watsonplatform.net/speech-to-text/api
   watson_url: wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize?watson-token=
   user_name: username
   password: password
   params:
      action: start
      content-type: audio/wav
      continuous: true
      inactivity_timeout: -1
      interim_results: true

 development:
   <<: *default

 test:
   <<: *default

 staging:
   <<: *default

 production:
   <<: *default 


In Gemfile:

 gem 'activesupport'
 gem 'eventmachine'
 gem 'websocket-client-simple'

Run bundle.

Make a File.rb file in config/intializer. In which we will define a instance method for an audio file.

 class File
   def read_chunk(chunk_size=2000)
     yield read(chunk_size) until eof?
   end
 end


Now, we will create a method for speech to text conversion in which will take an audio file as an argument.

   WATSON = YAML.load_file(File.join(Rails.root, 'config', 'watson.yml'))[Rails.env]

   def speech_to_text(wav_file)
     params = WATSON['params']

     token = ''
     uri = URI.parse(WATSON['auth_url'])
     Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
       request = Net::HTTP::Get.new(uri)
       request.basic_auth WATSON['user_name'], WATSON['password']
       token = http.request(request)
     end

     watson_url = WATSON['watson_url']+"#{token.body}"
     file_url = wav_file #replace this with the file you want to read
     init_message = params.to_json
     ws = ''
     # run websocket in an EventMachine
     EM.run {
       ws = WebSocket::Client::Simple.connect watson_url
       file_sent = false

       ws.on :message do |event|
  data = JSON.parse(event.data)
  if data['state'] && data['state'] == 'listening'
    if !!file_sent
      EM::stop_event_loop
    else
      file_sent = true
      open(file_url, 'rb') do |file|
        file.read_chunk { |chunk| ws.send(chunk, type: :binary) }
      end
      ws.send("", type: :binary)
    end
  elsif data['results'] && data['results'].first['final']
    puts data['results'].first['alternatives'].first['transcript'] if data['results'].first['alternatives']
  end

       end

       ws.on :open do
  puts "-- websocket open"
  puts init_message
  ws.send(init_message)
       end

       ws.on :close do |e|
  puts "-- websocket close #{
  if e!=nil then
    (e)
  end}"
  exit 1
       end

       ws.on :error do |e|
  puts "-- error (#{e.inspect})"
       end
     }
     ws.close
   end

Sunday 11 June 2017

Allow serialized attributes with unknown keys to be permitted in strong parameters.

Suppose that, we have Attempt model and we have serialized an attribute in attempt.rb like this



class Attempt < ApplicationRecord

 #==== Serializations ==================
   serialize :response

 end


Now, if you are creating attempt through strong parameters in controller -

   
   
Attempt.create(attempts_params)


And you have permitted response attribute in strong parameters like this


 def attempts_params
     params.require(:attempt).permit(:response)
 end


        OR

   

 def attempts_params
     params.require(:attempt).permit(:response => {})
 end


Above strong parameters will save response as nil or blank. In this scenario we have to permit keys of serialized attributes in strong parameter



 def attempts_params
     response_keys = params[:attempt][:response].keys
     params.require(:attempt).permit(response: response_keys)
 end

Saturday 3 June 2017

Twilio Phone Number authentication with Authy in Ruby on Rails.

Authy is a Twilio service that provides two factor authentication as an API, making it easy to secure users accounts. Using authy services we can authenticate users by their phone number. OTP will be send on phone number and it will be verified at the twilio end.


In Gemfile.

    # Use Authy for sending token
    gem 'authy'
    # Use Twilio to send confirmation message
    gem 'twilio-ruby'

We need an API key for Authy. You can get this from your Twilio account portal. Click the link to access the Authy dashboard.

If you don’t already have an Authy account, this will set one up for you. You will need to verify your email address and set up two factor authentication. Then you can create an application with Authy and this will give you your API key.

Create a new file authy.rb in config/initializers.

In authy.rb


    Authy.api_key = 'api_key'

    Authy.api_uri = 'https://api.authy.com/'

Now, we can start phone verification via sending a sms.

In sessions controller


     def send_otp

         response = Authy::PhoneVerification.start(via: "sms", country_code: 1, phone_number: "111-111-1111")

         render json: {response: response.message}, status: response.code

     end


    def verify_otp

        response = Authy::PhoneVerification.check(verification_code: "1234", country_code: 1, phone_number: "111-111-1111")

        if response.ok?

              # verification was successful

            end       

    end

In routes.rb


    resources :sessions do

        collection do

          post :send_otp

          post :verify_otp

        end

    end