Translator Bot using Google Translate API - ruby

Hey Stackoverflow Community,
I'm new to Ruby and working on a small project for a course assignment. I've to create a mobile bot that uses the Google Translate API and returns the translated text.
I'm stuck trying to figure out how to write the code for the bot to get the inputted text and output the translation.
Could anyone have a look, please? Would really appreciate it
def transl8 (input,lang) #method to translate incoming text
# Translates some text into Russian
# Instantiates a client
translate = Google::Cloud::Translate.new project: project-217401
puts input + "Looks like you're speak in #{detection.language}"
puts "Confidence: #{detection.confidence}"
translation = translate.translate input, to: lang
return "In #{lang} that's" + translation
end
def transl8 (input,lang) #method to translate incoming text
detection = $translate.detect input
puts input + "Looks like you're speak in #{detection.language}"
puts "Confidence: #{detection.confidence}"
translation = $translate.translate input, to: lang
return "In #{lang} that's" + translation
end
def listlang #method to show language code
language_code = "en"
languages = $translate.languages
puts "Supported languages:"
languages.each do |language|
puts "#{language.code} #{language.name}"
end
end
configure :development do
require 'dotenv'
Dotenv.load
end
#Translate End-point
https://translation.googleapis.com/language/translate/v2 endpoint
get "/incoming/sms/" do
"Hey! I'm AllSpeak, a translator bot. The list of supported languages are
below. Just ask by typing (TEXT) (space) (Language Code)"
incoming_text = params['Body']
text_to_translate = incoming_text.split(' ')[0]
lang_requested = incoming_text.split(' ')[1]
twiml_body = transl8(text_to_translate, lang_requested)
#return twiml here with twiml_body
end
#Look into Including method to set default language for commonly used
phrases
puts listlang
transl8 (text)
# Build a twilio response object
twiml = Twilio::TwiML::MessagingResponse.new do |r|
r.message do |m|
end
end

Regarding the Translation API Code:
For listlang:
You're missing an end on the do loop and you're not setting the project_id variable
For transl8:
You're not initializing the detection variable
Sample code:
#!/usr/bin/ruby
require "google/cloud/translate"
$translate = Google::Cloud::Translate.new project: "slatebot-217401"
def transl8 (input,lang) #method to translate incoming text
detection = $translate.detect input
puts input + "Looks like you're speak in #{detection.language}"
puts "Confidence: #{detection.confidence}"
translation = $translate.translate input, to: lang
return "In #{lang} that's" + translation
end
def listlang #method to show language code
language_code = "en"
languages = $translate.languages
puts "Supported languages:"
languages.each do |language|
puts "#{language.code} #{language.name}"
end
end

Jarod from Twilio. I noticed your question and wanted to suggest you parse the users SMS that would be incoming to your "incoming/sms". Once you have configured your phone number to make a GET request to "incoming/sms" Twilio will start sending incoming SMS to that URL. When Twilio does this it will also pass you a bunch of information in the http request. The incoming SMS body is passed as the Body in the request. So you could do something like this
get '/incoming/sms' do
incoming_text = params['Body']
text_to_translate = incoming_text.split(' ')[0]
lang_requested = incoming_text.split(' ')[1]
twiml_body = transl8(text_to_translate, lang_requested)
#return twiml here with twiml_body
end
Does that make sense? Looks like your twiml method is mostly ready to go so just insert that at the end of your response and you should be good to go! Fun app. Excited to see it finished!

Related

How to use webmock to simulate a request?

My app create a github gist using API. I need to simulate a request to the API with rspec. I'm using the webmock gem but I don't quite understand how to use it for my application. I need a little help to get started.
This is my spec/Git_Request_spec.rb
require_relative '../Gist_Request.rb'
require 'spec_helper'
RSpec.describe GistRequest do
describe "#post" do
it "crear gist" do
filename = "test.txt"
description = "descripción"
state = true
content = "contenido"
gist_create = GistRequest.new(description, state, filename, content)
gist_create.post()
expect(gist_create.response_status).to eq "201"
end
it "campos no válidos" do
filename = "test.txt"
description = "descripción"
state = true
content = "contenido"
gist_create = GistRequest.new(filename, content, state, description)
gist_create.post()
expect(gist_create.response_status).to eq "422"
end
end
end
Any ideas?
You need to use the method stub_request to simulate your interaction with api
stub_request(:http_method, url).with(`your data in
request`).to_return(`what do you expect to receive in response`).

How to make dynamic template in ror...

I am new to ROR.I am working on spree gem extension. I want to make email template dynamic means the content of html.erb file should store in database table .On shooting mail, all data and dynamic data are managed..?? Is it possible in ror and how to achieve this.??
Yes you can do like this just replace dynamic variables in DB like this:
You have successfully placed Service Request No. {service_requests_id} for {service_requests_category} . Our representative will be in touch with you soon for the same. Thank you." This string is store in database.
and create a helper
def replace_dynamic_variables(str,variables=nil)
variables.each do |k ,v|
str = str.gsub('{' + k.to_s + '}',v || "")
end
return str.html_safe
end
and on mailer prepare variables like:
class yourMailer < ApplicationMailer
def send_service_email(args) # email sending method
#variables = {}
# Other code like subject, to, from etc.
#db_string = #string you get form DB
#variables[:service_requests_id] = #service_requests.id
#variables[:service_requests_category] = #service_requests.category.name
#mail to:
end
end
and in send_service_email.html.erb/ send_service_email.txt.erb whatever suite in your case just call
<%= replace_dynamic_variables(#db_string,#variables)%>
I have not tested but hope this will work for you

Creating a Ruby API

I have been tasked with creating a Ruby API that retrieves youtube URL's. However, I am not sure of the proper way to create an 'API'... I did the following code below as a Sinatra server that serves up JSON, but what exactly would be the definition of an API and would this qualify as one? If this is not an API, how can I make in an API? Thanks in advance.
require 'open-uri'
require 'json'
require 'sinatra'
# get user input
puts "Please enter a search (seperate words by commas):"
search_input = gets.chomp
puts
puts "Performing search on YOUTUBE ... go to '/videos' API endpoint to see the results and use the output"
puts
# define query parameters
api_key = 'my_key_here'
search_url = 'https://www.googleapis.com/youtube/v3/search'
params = {
part: 'snippet',
q: search_input,
type: 'video',
videoCaption: 'closedCaption',
key: api_key
}
# use search_url and query parameters to construct a url, then open and parse the result
uri = URI.parse(search_url)
uri.query = URI.encode_www_form(params)
result = JSON.parse(open(uri).read)
# class to define attributes of each video and format into eventual json
class Video
attr_accessor :title, :description, :url
def initialize
#title = nil
#description = nil
#url = nil
end
def to_hash
{
'title' => #title,
'description' => #description,
'url' => #url
}
end
def to_json
self.to_hash.to_json
end
end
# create an array with top 3 search results
results_array = []
result["items"].take(3).each do |video|
#video = Video.new
#video.title = video["snippet"]["title"]
#video.description = video["snippet"]["description"]
#video.url = video["snippet"]["thumbnails"]["default"]["url"]
results_array << #video.to_json.gsub!(/\"/, '\'')
end
# define the API endpoint
get '/videos' do
results_array.to_json
end
An "API = Application Program Interface" is, simply, something that another program can reliably use to get a job done, without having to busy its little head about exactly how the job is done.
Perhaps the simplest thing to do now, if possible, is to go back to the person who "tasked" you with this task, and to ask him/her, "well, what do you have in mind?" The best API that you can design, in this case, will be the one that is most convenient for the people (who are writing the programs which ...) will actually have to use it. "Don't guess. Ask!"
A very common strategy for an API, in a language like Ruby, is to define a class which represents "this application's connection to this service." Anyone who wants to use the API does so by calling some function which will return a new instance of this class. Thereafter, the program uses this object to issue and handle requests.
The requests, also, are objects. To issue a request, you first ask the API-connection object to give you a new request-object. You then fill-out the request with whatever particulars, then tell the request object to "go!" At some point in the future, and by some appropriate means (such as a callback ...) the request-object informs you that it succeeded or that it failed.
"A whole lot of voodoo-magic might have taken place," between the request object and the connection object which spawned it, but the client does not have to care. And that, most of all, is the objective of any API. "It Just Works.™"
I think they want you to create a third-party library. Imagine you are schizophrenic for a while.
Joe wants to build a Sinatra application to list some YouTube videos, but he is lazy and he does not want to do the dirty work, he just wants to drop something in, give it some credentials, ask for urls and use them, finito.
Joe asks Bob to implement it for him and he gives him his requirements: "Bob, I need YouTube library. I need it to do:"
# Please note that I don't know how YouTube API works, just guessing.
client = YouTube.new(api_key: 'hola')
video_urls = client.videos # => ['https://...', 'https://...', ...]
And Bob says "OK." end spends a day in his interactive console.
So first, you should figure out how you are going to use your not-yet-existing lib, if you can – sometimes you just don't know yet.
Next, build that library based on the requirements, then drop it in your Sinatra app and you're done. Does that help?

Cleverbot ruby irc bot

I wrote this auto-reply bot with ruby, it is supposed to autoreply with cleverbot messages when im away:
require "cleverbot"
require "cinch"
$client = Cleverbot::Client.new
def get_answer(text)
reply = $client.write text
return reply
end
bot = Cinch::Bot.new do
configure do |c|
c.nick = "mybotsnickname"
c.server = "my.irc.testserver"
c.channels = ["#mychannel"]
end
on :message do |m|
m.reply m.user
m.reply get_answer(m.message)
end
end
bot.start
It works fine but the session id changes every message. What do i have to change to keep it? best case scenario is every user writing me gets a different session id at cleverbot so they have individual conversations.
I'm pretty new to ruby.
I used: https://github.com/benmanns/cleverbot
and https://github.com/cinchrb/cinch
Comparing this to the structure of my cinch bot, I'd try the following:
1) Make get_answer a helper block and place it inside the bot = Cinch::Bot.new block:
helpers do
def get_answer(text)
reply = $client.write text
return reply
end
end
2) Replace
on :message do |m|
with
on :message do |m, text|
3) Replace
m.reply get_answer(m.message)
with
m.reply get_answer(text)
I suspect this should work. But I'm a relatively new to Ruby as well.

How to get RSS feed in xml format for ruby script

I am using the following ruby script from this dashing widget that retrieves an RSS feed and parses it and sends that parsed title and description to a widget.
require 'net/http'
require 'uri'
require 'nokogiri'
require 'htmlentities'
news_feeds = {
"seattle-times" => "http://seattletimes.com/rss/home.xml",
}
Decoder = HTMLEntities.new
class News
def initialize(widget_id, feed)
#widget_id = widget_id
# pick apart feed into domain and path
uri = URI.parse(feed)
#path = uri.path
#http = Net::HTTP.new(uri.host)
end
def widget_id()
#widget_id
end
def latest_headlines()
response = #http.request(Net::HTTP::Get.new(#path))
doc = Nokogiri::XML(response.body)
news_headlines = [];
doc.xpath('//channel/item').each do |news_item|
title = clean_html( news_item.xpath('title').text )
summary = clean_html( news_item.xpath('description').text )
news_headlines.push({ title: title, description: summary })
end
news_headlines
end
def clean_html( html )
html = html.gsub(/<\/?[^>]*>/, "")
html = Decoder.decode( html )
return html
end
end
#News = []
news_feeds.each do |widget_id, feed|
begin
#News.push(News.new(widget_id, feed))
rescue Exception => e
puts e.to_s
end
end
SCHEDULER.every '60m', :first_in => 0 do |job|
#News.each do |news|
headlines = news.latest_headlines()
send_event(news.widget_id, { :headlines => headlines })
end
end
The example rss feed works correctly because the URL is for an xml file. However I want to use this for a different rss feed that does not provide an actual xml file. This rss feed I want is at http://www.ttc.ca/RSS/Service_Alerts/index.rss
This doesn't seem to display anything on the widget. Instead of using "http://www.ttc.ca/RSS/Service_Alerts/index.rss", I also tried "http://www.ttc.ca/RSS/Service_Alerts/index.rss?format=xml" and "view-source:http://www.ttc.ca/RSS/Service_Alerts/index.rss" but with no luck. Does anyone know how I can get the actual xml data related to this rss feed so that I can use it with this ruby script?
You're right, that link does not provide regular XML, so that script won't work in parsing it since it's written specifically to parse the example XML. The rss feed you're trying to parse is providing RDF XML and you can use the Rubygem: RDFXML to parse it.
Something like:
require 'nokogiri'
require 'rdf/rdfxml'
rss_feed = 'http://www.ttc.ca/RSS/Service_Alerts/index.rss'
RDF::RDFXML::Reader.open(rss_feed) do |reader|
# use reader to iterate over elements within the document
end
From here you can try learning how to use RDFXML to extract the content you want. I'd begin by inspecting the reader object for methods I could use:
puts reader.methods.sort - Object.methods
That will print out the reader's own methods, look for one you might be able to use for your purposes, such as reader.each_entry
To further dig down you can inspect what each entry looks like:
reader.each_entry do |entry|
puts "----here's an entry----"
puts entry.inspect
end
or see what methods you can call on the entry:
reader.each_entry do |entry|
puts "----here's an entry's methods----"
puts entry.methods.sort - Object.methods
break
end
I was able to crudely find some titles and descriptions using this hack job:
RDF::RDFXML::Reader.open('http://www.ttc.ca/RSS/Service_Alerts/index.rss') do |reader|
reader.each_object do |object|
puts object.to_s if object.is_a? RDF::Literal
end
end
# returns:
# TTC Service Alerts
# http://www.ttc.ca/Service_Advisories/index.jsp
# TTC Service Alerts.
# TTC.ca
# http://www.ttc.ca
# http://www.ttc.ca/images/ttc-main-logo.gif
# Service Advisory
# http://www.ttc.ca/Service_Advisories/all_service_alerts.jsp#Service+Advisory
# 196 York University Rocket route diverting northbound via Sentinel, Finch due to a collision that has closed the York U Bus way.
# - Affecting: Bus Routes: 196 York University Rocket
# 2013-12-17T13:49:03.800-05:00
# Service Advisory (2)
# http://www.ttc.ca/Service_Advisories/all_service_alerts.jsp#Service+Advisory+(2)
# 107B Keele North route diverting northbound via Keele, Lepage due to a collision that has closed the York U Bus way.
# - Affecting: Bus Routes: 107 Keele North
# 2013-12-17T13:51:08.347-05:00
But I couldn't quickly find a way to know which one was a title, and which a description :/
Finally, if you still can't find how to extract what you want, start a new question with this info.
Good luck!

Resources