I try make feature when in chat there are some unacceptable message that any other users can reply on this message with command '/report' and admins received meesage from bot with inline keyboad where he can:
ban sender of report
ban reporter of message
So, for this I have two methods:
Action "/report" - it sends to admin inline keyboard(there is all
needed data)
"callback_query" - it processes message(don't have data what need
for ban of user) - it has only data of chat, user who clicked inline
button
Ok, i can save data from point 1 to redis and pass it into point 2, but how can I found(indenify) that variable to use it...
Any tips?
def report!(*)
Rails.cache.write(:update, update)
# create_report
# binding.pry
user_name_reporter = "#{update.dig('message', 'from', 'first_name')} #{update.dig('message', 'from', 'last_name')}"
user_name_sender = "#{update.dig('message', 'reply_to_message', 'from', 'first_name')} #{update.dig('message', 'reply_to_message', 'from', 'last_name')}"
respond_with :message, text: "We got report in the group!\n#{user_name_reporter} sent report on #{user_name_sender}", reply_markup: {
inline_keyboard: [
[
{text: t('.restrict_messages_for_sender'), callback_data: 'restrict_messages_for_sender'},
{text: t('.restrict_messages_for_reporter'), callback_data: 'restrict_messages_for_reporter'},
],
[
{text: t('.ban_for_sender'), callback_data: 'ban_for_sender'},
{text: t('.ban_for_reporter'), callback_data: 'ban_for_reporter'},
],
# [{text: t('.repo'), url: 'https://github.com/telegram-bot-rb/telegram-bot'}],
],
}
end
def callback_query(data)
report_update = Rails.cache.read(:update)
sender_user_id = report_update.dig('message', 'from', 'id')
reporter_user_id = report_update.dig('message', 'reply_to_message', 'from', 'id')
chat_id = report_update.dig('message', 'chat', 'id')
# binding.pry
case data
when 'restrict_messages_for_sender'
answer_callback_query t('.alert'), show_alert: true
bot.restrict_chat_member(chat_id: chat_id, user_id: sender_user_id, permissions: { can_send_messages: false }.to_json, until_date: (Time.now + 1.hours).to_i)
when 'restrict_messages_for_reporter'
answer_callback_query t('.no_alert')
bot.restrict_chat_member(chat_id: chat_id, user_id: reporter_user_id, permissions: { can_send_messages: false }.to_json, until_date: (Time.now + 1.hours).to_i)
when 'ban_for_sender'
answer_callback_query t('.no_alert')
bot.ban_chat_member(chat_id: chat_id, user_id: sender_user_id)
when 'ban_for_reporter'
answer_callback_query t('.no_alert')
bot.ban_chat_member(chat_id: chat_id, user_id: reporter_user_id)
end
end
data in action '/report' :
{
"update_id" => 156273636,
"message" => {
"message_id" => 523,
"from" => {
"id" => 308967324,
"is_bot" => false,
"first_name" => "PRD",
"last_name" => "RSD",
"username" => "anko20094",
"language_code" => "en"
},
"chat" => {
"id" => -686671946,
"title" => "test gropt for bots",
"type" => "group",
"all_members_are_administrators" => true
},
"date" => 1659272502,
"reply_to_message" => {
"message_id" => 522,
"from" => {
"id" => 1949490661,
"is_bot" => false,
"first_name" => "Den",
"username" => "ItshenotI",
"language_code" => "uk"
},
"chat" => {
"id" => -686671946,
"title" => "test gropt for bots",
"type" => "group",
"all_members_are_administrators" => true
},
"date" => 1659272484,
"text" => "unacceptable text, that must be reported"
},
"text" => "/report",
"entities" => [
[0] {
"offset" => 0,
"length" => 7,
"type" => "bot_command"
}
]
}
}
and here data in action 'callback_query':
{
"update_id" => 156273638,
"callback_query" => {
"id" => "1327004554721482603",
"from" => {
"id" => 308967324,
"is_bot" => false,
"first_name" => "PRD",
"last_name" => "RSD",
"username" => "anko20094",
"language_code" => "en"
},
"message" => {
"message_id" => 524,
"from" => {
"id" => 5362380113,
"is_bot" => true,
"first_name" => "anko_test",
"username" => "anko_test_bot"
},
"chat" => {
"id" => -686671946,
"title" => "test gropt for bots",
"type" => "group",
"all_members_are_administrators" => true
},
"date" => 1659272601,
"text" => "We got report in the group!\nPRD RSD sent report on Den",
"reply_markup" => {
"inline_keyboard" => [
[0] [
[0] {
"text" => "Restrict messages for sender user",
"callback_data" => "restrict_messages_for_sender"
},
[1] {
"text" => "Restrict messages for reported user",
"callback_data" => "restrict_messages_for_reporter"
}
],
[1] [
[0] {
"text" => "Ban for sender",
"callback_data" => "ban_for_sender"
},
[1] {
"text" => "Ban for reporter",
"callback_data" => "ban_for_reporter"
}
]
]
}
},
"chat_instance" => "-5057992267045364113",
"data" => "restrict_messages_for_sender"
}
}
and screenshot how it looks in telegram:in telegram
Related
I'm having issues with a Ruby gem that used to work, but now doesn't. It's openstates https://rubygems.org/gems/openstates . The code to find Legislators doesn't seem to work anymore. We have had this code in production for a while, but are now getting this error
NoMethodError - undefined method `map' for #<String:0x007ff0b51941c0>
openstates (0.0.1) lib/openstates/model.rb:37:in `where'
This is the how we are calling the method.
OpenStates::Legislator.where(parameters)
parameters = {:state=>"Ca"}
Your code hasn't changed, the gem hasn't changed, but the API probably has.
Here's a very basic module to help you get an Array from OpenStates::Legislator.where(parameters) :
require 'open-uri'
require 'active_support/core_ext/object'
module OpenStates
class Legislator
#cache={}
class << self
def where(parameters)
url = "https://openstates.org/api/v1/legislators/?#{parameters.to_query}"
#cache[url] ||= get_json(url)
end
private
def get_json(url)
puts "# Downloading #{url}"
sleep 2
JSON.load(open(url))
end
end
end
end
parameters = {:state=>"Ca"}
p OpenStates::Legislator.where(parameters).first(2)
It outputs :
# Downloading https://openstates.org/api/v1/legislators/?state=Ca
[
{
"last_name" => "Gatto",
"updated_at" => "2016-09-24 07:16:00",
"nimsp_candidate_id" => nil,
"full_name" => "Mike Gatto",
"id" => "CAL000123",
"first_name" => "Mike",
"middle_name" => "",
"district" => "43",
"chamber" => "lower",
"state" => "ca",
"votesmart_id" => "120220",
"party" => "Democratic",
"+capitol_office" => {
"phone" => "(916) 319-2043",
"street" => "P.O. Box 942849, Room 4140",
"zip" => "94249-0043",
"city" => "Sacramento"
},
"all_ids" => [
"CAL000123",
"CAL000246",
"CAL000246",
"CAL000367"
],
"leg_id" => "CAL000123",
"active" => true,
"transparencydata_id" => "76584a5322274b9b892642b7b6ae3db5",
"photo_url" => "http://assembly.ca.gov/sites/assembly.ca.gov/files/memberphotos/AD43.jpg",
"+district_offices" => [
{
"phone" => "(818) 240-6330",
"street" => "300 East Magnolia, Suite 504",
"zip" => "91502",
"city" => "Burbank"
}
],
"url" => "http://asmdc.org/members/a43",
"country" => "us",
"created_at" => "2012-01-31 19:25:09",
"level" => "state",
"+district" => "43",
"offices" => [
{
"fax" => nil,
"name" => "Capitol Office",
"phone" => "916-319-2043",
"address" => "P.O. Box 942849, Room 5136\nSacramento, CA 94249-0043",
"type" => "capitol",
"email" => nil
},
{
"fax" => nil,
"name" => "District Office",
"phone" => "818-558-3043",
"address" => "300 East Magnolia Blvd, Suite 504\nBurbank, CA 91502",
"type" => "district",
"email" => nil
}
],
"+party" => "Democratic",
"suffixes" => ""
},
{
"last_name" => "Gordon",
"updated_at" => "2016-09-24 07:16:01",
...
I got this query:
User.collection.aggregate([
{"$project" => {
"dayOfMonth" => {"$dayOfMonth" => "$created_time"},
"month" => {"$month" => "$created_time"},
"year" => {"$year" => "$created_time"},
}},
{"$group" => {
"_id" => { "dayOfMonth" => "$dayOfMonth", "month" => "$month", "year" => "$year"},
"Total" => {"$sum" => 1}
}},
{"$sort" => {
"created_at" => -1
}}
])
My user table has username and fullname which I need,
I did something like
User.collection.aggregate([
{"$project" => {
"dayOfMonth" => {"$dayOfMonth" => "$created_at"},
"month" => {"$month" => "$created_at"},
"year" => {"$year" => "$created_at"},
"username" => "$username"
}},
{"$group" => {
"_id" => { "dayOfMonth" => "$dayOfMonth", "month" => "$month", "year" => "$year"},
"Total" => {"$sum" => 1}
}},
{"$sort" => {
"created_at" => -1
}}
])
but it doesn't work and gives same result like above, doesn't print username, any ideas ?
My goal is get username, after grouping by created at date.
User.collection.aggregate([
{"$project" => {
"dayOfMonth" => {"$dayOfMonth" => "$created_at"},
"month" => {"$month" => "$created_at"},
"year" => {"$year" => "$created_at"},
"username" => "$username"
}},
{"$group" => {
"_id" => { "dayOfMonth" => "$dayOfMonth", "month" => "$month", "year" => "$year"},
"Total" => {"$sum" => 1},
"username" => {"$first" => "$username"}
}},
{"$sort" => {
"created_at" => -1
}}
])
When things went wrong, Rails echoes a dump of given params, it looks like this:
Parameters:
{"utf8"=>"✓",
"filter"=>{"title"=>"1",
"address"=>"2",
"city"=>{"title"=>"3"},
"people"=>{"name"=>"4",
"surname"=>"5",
"patronymic"=>"6",
"emails"=>{"email"=>"7"}},
"emails"=>{"email"=>"8"}},
"sort"=>{"0"=>{"field"=>"",
"dir"=>"asc"},
"1"=>{"field"=>"",
"dir"=>"asc"}},
"commit"=>"Show"}
But it actually would be much more useful if looks like this:
{
"utf8" => "✓",
"filter" => {
"title" => "1",
"address" => "2",
"city" => {
"title" => "3"
},
"people" => {
"name" => "4",
"surname" => "5",
"patronymic" => "6",
"emails" => {
"email" => "7"
}
},
"emails" => {
"email" => "8"
}
},
"sort" => {
"0" => {
"field" => "",
"dir" => "asc"
},
"1" => {
"field" => "",
"dir" => "asc"
}
},
"commit" => "Show"
}
How to achieve that?
With vanilla Ruby the nicest way is to turn the hash to JSON:
JSON::pretty_generate(hash_here, :allow_nan => true, :max_nesting => false)
This outputs a prettified JSON version of your object (array, hash or whatever). It won´t be pure ruby but this comes right at the base library so there is no need to install anything.
Trying to figure out a way to get the max/min values out of a hash of hash. Example would be that I want to get the player with the highest deaths and the player with the highest kills.
Example of a hash:
{ 1234 =>
{ :steamID => 1234,
:alias => "Bob",
:kills => "50",
:deaths => "10"
},
5678 =>
{ :steamID => 5678,
:alias => "Jim",
:kills => "10",
:deaths => "12"
},
}
Trying to get an output of something like:
{ :most_kills =>
{ :steamID => 12345,
:name => "Bob",
:stat => "50"},
:most_deaths =>
{ :steamID => 12345,
:name => "Bob",
:stat => "50"
}
}
The following will find the player with the max kills and deaths stats and map the output to the desired format:
input = { 1234 =>
{ steamID: 1234,
alias: "Bob",
kills: "50",
deaths: "10"
},
5678 =>
{ steamID: 5678,
alias: "Jim",
kills: "10",
deaths: "12"
},
}
output = [:kills, :deaths].each_with_object({}) do |stat, h|
max = input.max_by {|k,v| v[stat]}
h["most_#{stat}".to_sym] = {
:steamID => max[0],
:name => max[1][:alias],
:stat => max[1][stat]
}
end
The output is:
{
:most_kills => {
:steamID => 1234,
:name => "Bob",
:stat => "50"
},
:most_deaths => {
:steamID => 5678,
:name => "Jim",
:stat => "12"
}
}
I might write it like this:
def most(input, key_name)
_, v = input.max_by { |_,v| v[key_name.to_sym] }
[("most_#{key_name}").to_sym, v]
end
["deaths", "kills"].map {|key_name| most(input, key_name) }.to_h
#=> {:most_deaths=>{:steamID=>5678, :alias=>"Jim",
# :kills=>"10", :deaths=>"12"},
# :most_kills =>{:steamID=>1234, :alias=>"Bob",
# :kills=>"50", :deaths=>"10"}}
I'm trying to pass the following ruby hash into an active resource(3.0.9) find(:from) call.
my_hash = {
:p => {:s => 100, :e => 2},
:k => "blah",
:f => [
{
:fl => :bt,
:tp => :trm,
:vl => "A::B"
},
{
:fl => :jcni,
:tp => :trm,
:vl => [133, 134]
},
{
:mnfl => :bmns,
:mxfl => :bmxs,
:tp => :rfstv,
:vl => 1e5
},
{
:fl => :bpo,
:tp => :rftv,
:op => :eta,
:vl => 1.months.ago.strftime("%Y-%m-%d")
}
]
}
Resource.find_by_x_and_y(:all, :from => :blah, params: my_hash)
On the server side action, when I print the params hash, its all messed up. ( last 3 hashes in the array mapped to :f )
{
"f" => [
{
"fl" => "bt",
"tp" => "trm",
"vl" => "A::B"
},
{
"fl" => "jcni",
"tp" => "trm",
"vl" => [
"133",
"134"
],
"mnfl" => "bmns",
"mxfl" => "bmxs"
},
{
"tp" => "rfstv",
"vl" => "100000.0",
"fl" => "bpo",
"op" => "eta"
},
{
"tp" => "rftv",
"vl" => "2013-01-25"
}
],
"k" => "blah",
"p" => {
"e" => "2",
"s" => "100"
},
"action" => "blah",
"controller" => "x/Y",
"format" => "json"
}
my_hash.to_query gives me
f[][fl]=bt&f[][tp]=trm&f[][vl]=A%3A%3AB&f[][fl]=jcni&f[][tp]=trm&f[][vl][]=133&f[][vl][]=134&f[][mnfl]=bmns&f[][mxfl]=bmxs&f[][tp]=rfstv&f[][vl]=100000.0&f[][fl]=bpo&f[][op]=eta&f[][tp]=rftv&f[][vl]=2013-01-25&k=blah&p[e]=2&p[s]=100
which doesn't have indices, hence the mixup.
Is there a name for this type of serialization using "[]" ? Is this guaranteed to serialize/deserialize arbitrarily nested hashes/arrays/primitives faithfully ? How do I make active resource behave sanely ?