I wrote this question up at RubyZoho's forum, but it's languishing there, and it's such a simple question it deserves a wider audience.
I have used RubyZoho to upload a new Lead record to the Zoho CRM API, and now I want to upload a Task with its "related to" field set to that Lead.
Configuring RubyZoho:
RubyZoho.configure do |config|
config.api_key = Setting.plugin_redmine_tigase['zoho_authorization_token']
config.crm_modules = [
'Leads',
'Tasks'
]
config.ignore_fields_with_bad_names = true
config.cache_fields = true
end
Creating the lead:
lead = RubyZoho::Crm::Lead.new
lead.first_name = splut.first
lead.last_name = splut.last
lead.full_name = params[:name]
lead.company = params[:company]
lead.email = params[:mail]
lead.description = description
lead.save
Creating the Task:
found = RubyZoho::Crm::Lead.find_by_email(params[:mail])
lead = found.first
task = RubyZoho::Crm::Task.new
task.related_to = lead.id
task.subject = params[:subject]
task.description = description
task.save
I tried task.related_to = lead.leadid, and got a Task record with a blank "related to" in the Zoho website. And when I try task.related_to = 'Lead'; task.relatedtoid = lead.leadid, I get a undefined method relatedtoid=, naturally because the variable has no setter.
So what am I missing? how do I do this simple thing?
If you look at the documentation it has a section on this
https://www.zoho.com/creator/help/script/creating-a-record-in-zoho-crm.html#create-lead
taskInfo = {
"Task Owner" : input.Owner_Name,
"SMOWNERID" : input.Owner_ID,
"Subject" : input.Subject,
"Description" : input.Description,
"SEMODULE" : "Accounts",
"SEID" : input.Account_ID,
"CONTACTID" : input.Contact_ID};
crmResp = zoho.crm.create("Tasks", taskInfo);
SMOWNERID is the ID of the Owner
SEMODULE can be Accounts or Leads or Cases
SEID is the ID of the Record given in the SEMODULE
CONTACTID is the ID of the contact record
Also if you look at the ruby_zoho_rspec for creating new task
https://github.com/amalc/rubyzoho/blob/950ffe369252f8fad3e7ae67ebddec859c84e19b/spec/ruby_zoho_spec.rb
it 'should save an task record related to an account' do
VCR.use_cassette 'zoho/task_related_to_account' do
a = RubyZoho::Crm::Account.all.first
e = RubyZoho::Crm::Task.new(
:task_owner => a.account_owner,
:subject => "Task should be related to #{a.account_name} #{Time.now}",
:description => 'Nothing',
:smownerid => "#{a.smownerid}",
:status => 'Not Started',
:priority => 'High',
:send_notification_email => 'False',
:due_date => '2014-02-16 16:00:00',
:start_datetime => Time.now.to_s[1, 19],
:end_datetime => '2014-02-16 16:00:00',
:related_to => "#{a.account_name}",
:seid => "#{a.accountid}",
:semodule => 'Accounts'
)
r_expected = e.save
r = RubyZoho::Crm::Task.find_by_activityid(r_expected.id)
r.first.subject[0..20].should eq(r_expected.subject[0..20])
end
So that should help you out link it by specifying SEMODULE and SEID
Related
I am new to ruby. I am trying to implement a chat client using em-websocket. I have the following code:
EventMachine::WebSocket.start(host: '0.0.0.0', port: 8080) do |websock|
websock.onopen do
puts 'New Connection Opened'
cookies = CGI::Cookie::parse( websock.request["cookie"])
person = Person.where(['token = ?', cookies["token"]]).first
unless person
websock.close(code = nil, body = {Error: "Invalid Token"}.to_json) unless person
return
end
puts "#{person.name} authenticated!"
person=person.attributes.merge(websock.attributes) # this doesn't work
# Subscribe the new user to the GrindServer.realtime_channel with the callback function for the push action
new_user = GrindServer.realtime_channel.subscribe { |msg| websock.send msg }
GrindServer.online_people << person
# Add the new user to the user list
#users[websock.object_id] = new_user
# Push the last messages to the user
# message.all.each do |message|
# websock.send message.to_json
# end
# puts GrindServer.realtime_channel.inspect
# Broadcast the notification to all users
onlinepeople = []
GrindServer.online_people.each do |onli|
onlinepeople << person
end
# Send last 10 messages to the newly connected user
websock.send Message.where({ receiver_id: [0, person.id}).last(10).to_json
GrindServer.realtime_channel.push ({
'id' => 0,
'sender_id' => 0,
'messagetext' => "#{person.name} joined. <$<^<#<#{#users.length}>#>^>$> users in chat",
'users' => onlinepeople,
'metadata' => websock.request["query"]["id"],
}.to_json)
end
...# other event handlers
end
Basically I am trying to maintain a list of Person (ActiveRecord Object) and its corresponding WebSocket::Connection Object.
Server code
Migration
Update: Even if I am unable to merge. I should be able to just attach a note to websocket that this belongs to a person named "x"?
I solved it by using a hash.
EventMachine::WebSocket.start(host: '0.0.0.0', port: 8080) do |websock|
websock.onopen do
puts 'New Connection Opened'
cookies = CGI::Cookie::parse( websock.request["cookie"])
person = Person.where(['token = ?', cookies["token"]]).first
unless person
websock.close(code = nil, body = {Error: "Invalid Token"}.to_json) unless person
return
end
puts "#{person.name} authenticated!"
# person=person.attributes.merge(websock.attributes)
# Subscribe the new user to the GrindServer.realtime_channel with the callback function for the push action
new_user = GrindServer.realtime_channel.subscribe { |msg| websock.send msg }
GrindServer.online_people << {:ws_oid => websock.object_id,
:websocket => websock,
:person_name => person.name,
:person_trigram => person.trigram} # this solves it
# Add the new user to the user list
#users[websock.object_id] = new_user
onlinepeople = []
GrindServer.online_people.each do |onli|
onlinepeople << onli.except(:websocket)
end
# Send last 10 messages to the newly connected user
websock.send Message.where({ receiver_id: [0, person.id]}).last(10).to_json
GrindServer.realtime_channel.push ({
'id' => 0,
'sender_id' => 0,
'messagetext' => "#{person.name} joined. <$<^<#<#{#users.length}>#>^>$> users in chat",
'users' => onlinepeople,
'metadata' => person.trigram,
}.to_json)
end
i'm facing several problem with API,
first:
send method asking for 'id'(message id or thread id) .. but why ?
i'm sending new message so it shouldn't require . according to Gmail Api documnetation
its optional .
https://developers.google.com/gmail/api/v1/reference/users/messages/send
ArgumentError: Missing required parameters: id.
second:
even after specify message id it return this message .
Your client has issued a malformed or illegal request.
code
require 'mime'
include MIME
msg = Mail.new
msg.date = Time.now
msg.subject = 'This is important'
msg.headers.set('Priority', 'urgent')
msg.body = Text.new('hello, world!', 'plain', 'charset' => 'us-ascii')
msg.from = {'hi#gmail.com' => 'Boss Man'}
msg.to = {
'list#example.com' => nil,
'john#example.com' => 'John Doe',
'jane#example.com' => 'Jane Doe',
}
#email = #google_api_client.execute(
api_method: #gmail.users.messages.send(:get),
body_object: {
raw: Base64.urlsafe_encode64(msg.to_s)
},
parameters: {
userId: 'me'
}
)
and of-course authentication working fine.
some other methods also working fine
like:
get list of messages(Users.messages.list)
get single message(Users.messages.get)
but
send message not working .
I think
#gmail.users.messages.send(:get) is equal to #gmail.users.messages.get
because ".send" is ruby method
so now this method is working with
#gmail.users.messages.to_h['gmail.users.messages.send']
example:
msg = Mail.new
msg.date = Time.now
msg.subject = options[:subject]
msg.body = Text.new(options[:message])
msg.from = {#_user.email => #_user.full_name}
msg.to = {
options[:to] => options[:to_name]
}
#email = #google_api_client.execute(
api_method: #gmail.users.messages.to_h['gmail.users.messages.send'],
body_object: {
raw: Base64.urlsafe_encode64(msg.to_s)
},
parameters: {
userId: 'me',
}
)
Thanks.
I think you may have a look at this gem I just built that use Gmail API and not using IMAP and SMTP like other gems:
gem install gmail-api-ruby
m = Gmail::Message.new(to: test#test.com, subject: "hello", html: "<b>this is html part<b>, text: "this is the text part")
m.deliver
gmail-api-ruby
It comes with a lot of helpful methods that you use in Gmail interface
I am using Ruby 1.9.3 without Rails and version 1.0.4 of the Gibbon gem.
I have referrals populated with my list and can send the following to MailChimp with Gibbon. However, only the email address and email type fields are populated in the list in MailChimp. What am I doing wrong that is prohibiting all the merge fields from being imported via API?
Here is the batch and map of the list.
referrals.each_slice(3) do |batch|
begin
prepared_batch = batch.map do |referral|
{
:EMAIL => {:email => referral['client_email']},
:EMAIL_TYPE => 'html',
:MMERGE6 => referral['field_1'],
:MMERGE7 => referral['field_2'],
:MMERGE8 => referral['field_3'],
:MMERGE9 => referral['field_4'],
:MMERGE11 => referral['field_5'],
:MMERGE12 => referral['field_6'],
:MMERGE13 => referral['field_7'],
:MMERGE14 => referral['field_8'],
:MMERGE15 => referral['field_9'],
:FNAME => referral['client_first_name']
}
end
#log.info("prepared_batch : #{prepared_batch}")
result = #gibbon.lists.batch_subscribe(
:id => #mc_list_id,
:batch => prepared_batch,
:double_optin => false,
:update_existing => true
)
#log.info("#{result}")
rescue Exception => e
#log.warn("Unable to load batch into mailchimp because #{e.message}")
end
end
The above executes successfully. However, only the email address and email type are populated but most of the fields should be populated.
Here is my log output for one of the prepared_batches. I replaced the real values with Value. I used my own email for testing.
I, [2013-11-11T09:01:14.778907 #70827] INFO -- : prepared_batch : [{:EMAIL=>
{:email=>"jason+6#marketingscience.co"}, :EMAIL_TYPE=>"html", :MMERGE6=>"Value",
:MMERGE7=>"Value", :MMERGE8=>nil, :MMERGE9=>nil, :MMERGE11=>"8/6/13 0:00",
:MMERGE12=>"Value", :MMERGE13=>nil, :MMERGE14=>"10/18/13 19:09", :MMERGE15=>"Value",
:FNAME=>"Value"}, {:EMAIL=>{:email=>"jason+7#marketingscience.co"}, :EMAIL_TYPE=>"html",
:MMERGE6=>"Value", :MMERGE7=>"Value", :MMERGE8=>nil, :MMERGE9=>nil, :MMERGE11=>"8/6/13
0:00", :MMERGE12=>"Value", :MMERGE13=>nil, :MMERGE14=>nil, :MMERGE15=>"Value",
:FNAME=>"Value"}, {:EMAIL=>{:email=>"jason+8#marketingscience.co"}, :EMAIL_TYPE=>"html",
:MMERGE6=>"Value", :MMERGE7=>"Value", :MMERGE8=>nil, :MMERGE9=>nil, :MMERGE11=>"8/7/13
0:00", :MMERGE12=>"Value", :MMERGE13=>nil, :MMERGE14=>nil, :MMERGE15=>"Value",
:FNAME=>"Value"}]
Here is the log output of result from the MailChimp call.
I, [2013-11-11T09:01:14.778691 #70827] INFO -- : {"add_count"=>3, "adds"=>
[{"email"=>"jason+3#marketingscience.co", "euid"=>"ab512177b4", "leid"=>"54637465"},
{"email"=>"jason+4#marketingscience.co", "euid"=>"eeb8388524", "leid"=>"54637469"},
{"email"=>"jason+5#marketingscience.co", "euid"=>"7dbc84cb75", "leid"=>"54637473"}],
"update_count"=>0, "updates"=>[], "error_count"=>0, "errors"=>[]}
Any advice on how to get all the fields to update in MailChimp is appreciated. Thanks.
Turns out the documentation for using the Gibbon gem to batch subscribe is not correct. You need to add the :merge_vars struct to contain the fields other than email and email type. My final code looks like the following. I'm also going to update this code in its entirety at: https://gist.github.com/analyticsPierce/7434085.
referrals.each_slice(3) do |batch|
begin
prepared_batch = batch.map do |referral|
{
:EMAIL => {:email => referral['email']},
:EMAIL_TYPE => 'html',
:merge_vars => {
:MMERGE6 => referral['field_1'],
:MMERGE7 => referral['field_2'],
:MMERGE8 => referral['field_3'],
:MMERGE9 => referral['field_4'],
:MMERGE11 => referral['field_5'],
:MMERGE12 => referral['field_6'],
:MMERGE13 => referral['field_7'],
:MMERGE14 => referral['field_8'],
:MMERGE15 => referral['field_9'],
:FNAME => referral['first_name']
}
}
end
#log.info("prepared_batch : #{prepared_batch}")
result = #gibbon.lists.batch_subscribe(
:id => #mc_list_id,
:batch => prepared_batch,
:double_optin => false,
:update_existing => true
)
#log.info("#{result}")
rescue Exception => e
#log.warn("Unable to load batch into mailchimp because #{e.message}")
end
end
I have a problem trying to update a Google document containing an image. In the first revision, the image will load as expected. But after updating it with the same HTML code I keep getting a spinner instead of the image.
I am using the Ruby gem created by Google (https://github.com/google/google-api-ruby-client).
Here is my test code:
# Setting up the client instance
require "google/api_client"
require "tempfile"
client = Google::APIClient.new
client.authorization.client_id = "<CLIENTID>"
client.authorization.client_secret = "<CLIENTSECRET>"
client.authorization.redirect_uri = "<REDIRECTURI>"
client.authorization.scope = "https://www.googleapis.com/auth/drive"
client.authorization.access_token = "<ACCESSTOKEN>"
client.authorization.refresh_token = "<REFRESHTOKEN>"
drive = client.discovered_api("drive", "v2")
# Creating the document (IMAGE DISPLAYED CORRECTLY)
file = drive.files.insert.request_schema.new({"title" => "Test document", "mimeType" => "text/html"})
temp = Tempfile.new "temp.html"
temp.write "<h1>Testing!</h1><p>Lorem ipsum.</p><img width='400px' src='http://www.digitaleconomics.nl/wp-content/uploads/2013/04/see-how-your-google-results-measure-up-with-google-grader-video-6b8bbb4b41.jpg'>"
temp.rewind
media = Google::APIClient::UploadIO.new(temp, "text/html")
result = client.execute(:api_method => drive.files.insert, :body_object => file, :media => media, :parameters => {"uploadType" => "multipart", "convert" => true})
temp.close
# Updating the document (GETTING SPINNER INSTEAD OF IMAGE)
file = client.execute(:api_method => drive.files.get, :parameters => {"fileId" => result.data.to_hash["id"]}).data
file.title = "Updated test document"
temp = Tempfile.new "temp.html"
temp.write "<h1>Testing!</h1><p>Lorem ipsum.</p><img width='400px' src='http://www.digitaleconomics.nl/wp-content/uploads/2013/04/see-how-your-google-results-measure-up-with-google-grader-video-6b8bbb4b41.jpg'>"
temp.rewind
media = Google::APIClient::UploadIO.new(temp, "text/html")
result = client.execute(:api_method => drive.files.update, :body_object => file, :media => media, :parameters => {"uploadType" => "multipart", "convert" => true, "fileId" => result.data.to_hash["id"], "newRevision" => false})
temp.close
Also, setting newRevision to false does not prevent a new revision from being created.
Can anyone help me out?
I'm currently using Fog to manage Dyn DNS provider. According the documentation, there's a destroy method on the DNS record object. However, when I call destroy, on a record, nothing happens... the method just returns true, but it is never deleted. Here's the code I'm using:
#dynect = Fog::DNS.new(
:provider => "dynect",
:dynect_customer => "CUSTOMER",
:dynect_username => "USERNAME",
:dynect_password => 'PASSWORD'
)
#zone = #dynect.zones.get('zone.example.com')
#record = #zone.records.find{|r| r.name == 'master.zone.example.com' && r.type == 'CNAME'}
#record.destroy
#zone.save
This will return true, but nothing ever happens - the DNS record still exists on Dyn.
How do I delete a record with Fog and Dyn?
Turns out you need to then publish (not save) the zone... This is not obvious, since other providers, like AWS, don't require. Here's an updated code snippet:
#dynect = Fog::DNS.new(
:provider => "dynect",
:dynect_customer => "CUSTOMER",
:dynect_username => "USERNAME",
:dynect_password => 'PASSWORD'
)
#zone = #dynect.zones.get('zone.example.com')
#record = #zone.records.find{|r| r.name == 'master.zone.example.com' && r.type == 'CNAME'}
#record.destroy
#zone.publish # changed this