I understand the whole process of dialogflow and I have a working deployed bot with 2 different intents. How do I actually get the response from the bot when a user answers questions? (I set the bot on fulfillment to go to my domain). Using rails 5 app and it's deployed with Heroku.
Thanks!
If you have already set the GOOGLE_APPLICATION_CREDENTIALS path to the jso file, now you can test using a ruby script.
Create a ruby file -> ex: chatbot.rb
Write the code bellow in the file.
project_id = "Your Google Cloud project ID"
session_id = "mysession"
texts = ["hello"]
language_code = "en-US"
require "google/cloud/dialogflow"
session_client = Google::Cloud::Dialogflow::Sessions.new
session = session_client.class.session_path project_id, session_id
puts "Session path: #{session}"
texts.each do |text|
query_input = { text: { text: text, language_code: language_code } }
response = session_client.detect_intent session, query_input
query_result = response.query_result
puts "Query text: #{query_result.query_text}"
puts "Intent detected: #{query_result.intent.display_name}"
puts "Intent confidence: #{query_result.intent_detection_confidence}"
puts "Fulfillment text: #{query_result.fulfillment_text}\n"
end
Insert your project_id. You can find this information on your agent on Dialogflow. Click on the gear on the right side of the Agent's name in the left menu.
Run the ruby file in the terminal or in whatever you using to run ruby files. Then you see the bot replying to the "hello" message you have sent.
Obs: Do not forget to install the google-cloud gem:
Not Entirely familiar with Dilogflow, but if you want to receive a response when an action occurs on another app this usually mean you need to receive web-hooks from them
A WebHook is an HTTP callback: an HTTP POST that occurs when something happens; a simple event-notification via HTTP POST. A web application implementing WebHooks will POST a message to a URL when certain things happen.
I would recommend checking their fulfillment documentation for an example. Hope this helps you out.
Related
I'm working on getting my Rails app interacting with the AWS Comprehend service for text entity extraction. I'm using the aws-sdk-comprehend gem. I have successfully gotten my app working with the AWS Rekognition service for image analysis using the aws-sdk-rekognition gem.
I can't seem to get the AWS Comprehend authentication correct as all of my calls result in an Aws::Comprehend::Errors::InvalidRequestException.
I have all of the following ENV variables set:
AWSAccessKeyId
AWSSecretKey
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
My code looks something like this:
class MyApp::Aws::ComprehendService < MyApp::ServiceBase
def call
#credentials = Aws::Credentials.new(ENV['AWSAccessKeyId'], ENV['AWSSecretKey'])
#client = Aws::Comprehend::Client.new(region: "us-west-1", credentials: credentials)
#client.detect_entities({text: "this is a simply little blob of text", language_code: "en"})
end
end
This resulted in Aws::Comprehend::Errors::InvalidRequestException. So I also tried:
class MyApp::Aws::ComprehendService < MyApp::ServiceBase
def call
# use ENV credential format I've seen in examples...
#credentials = Aws::Credentials.new(ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY'])
#client = Aws::Comprehend::Client.new(region: "us-west-1", credentials: credentials)
#client.detect_entities({text: "this is a simply little blob of text", language_code: "en"})
end
end
I found an example that didn't use the #credential approach. The example claimed "The initialize method will load the credentials environment variables by itself". So I tried this:
class MyApp::Aws::ComprehendService < MyApp::ServiceBase
def call
# ignore setting the credentials
#client = Aws::Comprehend::Client.new(region: "us-west-1")
#client.detect_entities({text: "this is a simply little blob of text", language_code: "en"}).
end
end
This also resulted in Aws::Comprehend::Errors::InvalidRequestException.
Can you see anything I'm doing wrong? Has anyone had success in using this gem to interact with the Comprehend API?
Per the Documentation for Aws::Comprehend::Client#detect_entities
If the system detects a document-level error in your input document, the API returns an InvalidRequestException error response. For details about this exception, see Errors in semi-structured documents in the Comprehend Developer Guide.
So it appears your usage is not necessarily the issue but rather the input documents themselves.
The response however should include what the actual issue is according to the Developer Guide:
Document-level errors
If the ClassifyDocument or DetectEntities API operation detects a document-level error in your input document, the API returns an InvalidRequestException error response.
In the error response, the Reason field contains the value INVALID_DOCUMENT.
The Detail field contains one of the following values:
DOCUMENT_SIZE_EXCEEDED – Document size is too large. Check the size of your file and resubmit the request.
UNSUPPORTED_DOC_TYPE – Document type is not supported. Check the file type and resubmit the request.
PAGE_LIMIT_EXCEEDED – Too many pages in the document. Check the number of pages in your file and resubmit the request.
TEXTRACT_ACCESS_DENIED_EXCEPTION – Access denied to Amazon Textract. Verify that your account has permission to use the Amazon Textract DetectDocumentText and AnalyzeDocument API operations and resubmit the request.
The Aws::Comprehend::Errors::InvalidRequestException object is documented so it appears you could potentially figure out what is wrong via
def call
# use ENV credential format I've seen in examples...
#credentials = Aws::Credentials.new(ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY'])
#client = Aws::Comprehend::Client.new(region: "us-west-1", credentials: credentials)
begin
#client.detect_entities({text: "this is a simply little blob of text", language_code: "en"})
rescue Aws::Comprehend::Errors::InvalidRequestException => e
# interrogate the error object here e.g.
puts {reason: e.reason, detail: e.detail}
end
end
I have implemented a platform using rails, and the goal is to send thousands of emails to customers with one click. The concept is that an email array runs each loop and inside each loop runs send email functionality like below.
#emails = ['abc#gmai.com', 'abc#example.com'] # More than 3 thousands
#emails.each do |email|
aws_email_sender(email, #email_subject, #email_body_html)
end
And the email function is like below:
def aws_email_sender(recipient, subject, htmlbody)
sender = "hello#example.com"
awsregion = "ap-west-1"
# The HTML body of the email.
htmlbodycontent = "#{htmlbody}"
# The email body for recipients with non-HTML email clients.
textbody = "This email was sent with Amazon SES using the AWS SDK for Ruby."
# Specify the text encoding scheme.
encoding = "UTF-8"
# Create a new SES resource and specify a region
ses = Aws::SES::Client.new(region: awsregion)
# Try to send the email.
begin
# Provide the contents of the email.
resp = ses.send_email({
destination: {
to_addresses: [recipient]
},
message: {
body: {
html: {
charset: encoding,
data: htmlbodycontent
},
text: {
charset: encoding,
data: textbody,
},
},
subject: {
charset: encoding,
data: subject,
},
},
source: sender,
});
# If something goes wrong, display an error message.
rescue Aws::SES::Errors::ServiceError => error
puts "Email not sent. Error message: #{error}"
end
end
The email is sending well by AWS but my rails application has gone down like
A timeout occurred, error code 524
I couldn't get the breaking point, why has my application gone down every time?
Thanks in Advance
If 524 is an HTTP status code then it means...
Cloudflare was able to make a TCP connection to the website behind them, but it did not reply with an HTTP response before the connection timed out.
Meaning your Rails app is behind a Cloudflare proxy. Cloudflare received an HTTP request, forwarded it to your app, waited around for your app to respond, but your app never did. A more detailed explanation can be found here.
Probably because it's trying to send emails to 3000 people one-by-one.
There's two strategies to fix this.
Use Bulk Email
Since the content of the email is the same for everyone, use an email template to send bulk email using the #send_bulk_templated_email method.
You can send to up to 50 addresses at a time, so use #each_slice to loop through emails in slices of 50.
This will be more efficient, but your app will still be waiting around for 3000/50 = 60 AWS API calls. At worst it will still time out. At best the user will be waiting around for a form submission.
Use A Background Job
Anytime your app needs to do something that might take a lot of time, like using a service or a large database query, consider putting it into a background job. The Rails app queues up a job to send the emails, and then it can respond to the web request while the mailing is handled in the background. This has other advantages: errors calling the service won't cause an error for the user, and failed jobs due to a temporary service outage can automatically be retried.
In Rails this is done with ActiveJob and you could write a job class to send your mail.
Use ActionMailer
However, Rails also offers a class specifically for sending email in the background: ActionMailer. You can have ActionMailer use AWS with the aws-sdk-rails gem.
config.action_mailer.delivery_method = :ses
I have Mailgun set up to forward emails to my /rails/action_mailbox/mailgun/inbound_emails/mime endpoint.
When my endpoint receives the request, it gives the following error:
ArgumentError (Missing required Mailgun API key. Set
action_mailbox.mailgun_api_key in your application's encrypted
credentials or provide the MAILGUN_INGRESS_API_KEY environment
variable.)
However, MAILGUN_INGRESS_API_KEY is in fact set. When I run ENV["MAILGUN_INGRESS_API_KEY"] in the console, I see my API key. I even pasted in the API key determination code from GitHub to see if there was a problem there, but the return value I got was my actual API key.
Any ideas on what the problem could be?
Just checking few things to see if can rectify, as I understand you know much better than me about rails.
Do you have setup mailgun api_key in environment configuration like for development config/environments/development.rb
config.action_mailer.delivery_method = :mailgun
config.action_mailer.mailgun_settings = {
api_key: ENV['MAILGUN_INGRESS_API_KEY'],
domain: 'your_domain.com',
# api_host: 'api.eu.mailgun.net' # Uncomment this line for EU region domains
}
Now let us do one test, visit (bin.mailgun.net) and get paste bin url then run rails c
mg_client = Mailgun::Client.new(ENV["MAILGUN_INGRESS_API_KEY"], "bin.mailgun.net", "aecf68de_you_got_visiting_site", ssl = false)
message_params = { from: 'bob#sending_domain.com',
to: 'sally#example.com',
subject: 'The Ruby SDK is awesome!',
text: 'It is really easy to send a message!'
}
result = mg_client.send_message("your_sending_setup_on_mailgun_domain.com", message_params)
puts result.inspect
See what message came and you may get idea. There could be environment configuration issue also for development you have to setup different then for production. Also check on paste-bin does it got any hit.
I'm using the DocuSign ruby client (https://github.com/docusign/docusign-ruby-client) on ruby on rails to send a document via email to some clients, but when I deploy the project after 15 minutes the request between the application and DocuSign gets "paused". For some reason the gem creates the request but doesn't send it as you can see in the next image where I enable the debug in the gem:
In that point the log doesn't print any more after 15 minutes.
The code that send the message in my app is:
access_token = "xxxxxxx"
account_id = "xxxxxxxxx"
base_path = "xxxxxxxxxx"
envelope_args = {
signer_email: contact.email,
signer_name: contact.name,
template_id: document.docusign_id
}
#args = {
account_id: account_id,
base_path: base_path,
access_token: access_token,
envelope_args: envelope_args
}
envelope_args = #args[:envelope_args]
# 1. Create the envelope request object
envelope_definition = make_envelope(envelope_args)
# 2. Call Envelopes::create API method
# Exceptions will be caught by the calling function
envelope_api = create_envelope_api(#args)
envelope_api.create_envelope #args[:account_id], envelope_definition
I don't know what can I do.
Thank you
Your screenshot shows everything happening at 18:29:05 -- I don't understand the issue.
Also, have you tried install/using the RoR code example?
See if it has the same problem.
We looked for the issue in our code, but we saw that in the step which the request is send in the gem here always freezes. So we debugged there and we saw that curl was being used for ruby. At that point we saw that curl was trying to reconnect with Docusign but it wasn't success, so we found this issue in the version of curl that we had (https://github.com/curl/curl/issues/4499 )
To fix it we updated the version to the latest, and it fixed the issue.
Thanks for your answers.
I have the following snippet to post to a user's feed on Facebook:
require 'httparty'
token = "..."
message = "..."
url = URI.escape("https://graph.facebook.com/me/feed?access_token=#{token}")
response = HTTParty.post(url, body: { message: message })
This posts to the wall, but no message is included. Any ideas what's wrong?
Edit:
I tried changing out the message for a caption or description and both failed as well.
Solution is to change HTTParty from using body to query for posting form data:
require 'httparty'
token = "..."
message = "..."
url = URI.escape("https://graph.facebook.com/me/feed?access_token=#{token}")
response = HTTParty.post(url, query: { message: message })
Based on the link cited above, it appears message functionality has been completely removed from the feed connection since July 12.
This is a problem for my current app as it is specifically a public opinion site. Asking users to express their opinions authentically is an important part of our design and we'd like to give them the option to post that to their feeds on Facebook as well.
Per the Facebook terms of use IV.2, "You must not pre-fill any of the fields associated with the following products, unless the user manually generated the content earlier in the workflow." The new change appears to change the terms of service: in my use, I am specifically asking the user to generate the content earlier in the workflow, but I still can't use it to pre-fill the feed dialog.
Anyone have any ideas or insight?