Release 2.4
[NEW] command /link to retrieve chat invite link [NEW] commands /mute, /unmute, /ban, /unban, /promote to manage chats [NEW] command /leave! to leave group as owner [FIX] tested and fixed some chat commands
This commit is contained in:
parent
edfae83b8f
commit
c3197cd000
|
@ -1,3 +1,17 @@
|
|||
DEFAULTS = {
|
||||
lib_path: 'lib/',
|
||||
verbosity: 2,
|
||||
loglevel: :debug,
|
||||
client: {api_id: 50322, api_hash: '9ff1a639196c0779c86dd661af8522ba', use_chat_info_database: false},
|
||||
content: {path: '', link: '', upload: ''}
|
||||
}
|
||||
|
||||
PERMISSIONS = {
|
||||
admin: {can_be_edited: true, can_change_info: true, can_post_messages: true, can_edit_messages: true, can_delete_messages: true, can_invite_users: true, can_restrict_members: true, can_pin_messages: true, can_promote_members: false},
|
||||
member: TD::Types::ChatPermissions.new(can_send_messages: true, can_send_media_messages: true, can_send_polls: true, can_send_other_messages: true, can_add_web_page_previews: true, can_change_info: true, can_invite_users: true, can_pin_messages: true),
|
||||
readonly: TD::Types::ChatPermissions.new(can_send_messages: false, can_send_media_messages: false, can_send_polls: false, can_send_other_messages: false, can_add_web_page_previews: false, can_change_info: false, can_invite_users: false, can_pin_messages: false),
|
||||
}
|
||||
|
||||
HELP_GATE_CMD = %q{Available commands:
|
||||
/login phone — sign in
|
||||
/logout — sign out
|
||||
|
@ -26,9 +40,15 @@ HELP_CHAT_CMD= %q{Available commands:
|
|||
/block — blacklist current user
|
||||
/unblock — unblacklist current user
|
||||
/invite id or @username — add user to current chat
|
||||
/link — get invite link for current chat
|
||||
/kick id or @username — remove user from current chat
|
||||
/ban id or @username [hours] — restrict @username from current chat for [hours] or forever
|
||||
/mute id or @username [hours] — mute user in current chat
|
||||
/unmute id or @username — unrestrict user from current chat
|
||||
/ban id or @username [hours] — restrict @username from current chat
|
||||
/unban id or @username — unbans @username in current chat (and devotes from admins)
|
||||
/promote id or @username — promote user to admin in current chat
|
||||
/leave — leave current chat
|
||||
/leave! — leave current chat (for owners)
|
||||
/close — close current secret chat
|
||||
/delete — delete current chat from chat list
|
||||
/members [query] — search members [by optional query] in current chat (requires admin rights)
|
||||
|
@ -37,18 +57,16 @@ HELP_CHAT_CMD= %q{Available commands:
|
|||
|
||||
class TelegramClient
|
||||
|
||||
attr_reader :session, :state
|
||||
@@config = {loglevel: :debug, verbosity: 2, lib_path: 'lib/', client: {api_id: 50322, api_hash: '9ff1a639196c0779c86dd661af8522ba', use_chat_info_database: false}, content: {path:'',link:'',upload:''}} # defaults
|
||||
|
||||
## configure tdlib (when valid tdlib params specified) or zhabogram
|
||||
def self.configure(**config)
|
||||
@@config = @@config.merge(config)
|
||||
@@config = DEFAULTS.merge(config)
|
||||
TD.config.update(config[:tdlib])
|
||||
TD::Api.set_log_verbosity_level(@@config[:tdlib_verbosity])
|
||||
end
|
||||
|
||||
## initialize telegram client instance (xmpp = XMPP stream, jid = user's jid , login = user's telegram login (for now, it is phone number)
|
||||
def initialize(xmpp, jid, **session)
|
||||
return unless @@config
|
||||
@logger = Logger.new(STDOUT, level: @@config[:loglevel], progname: 'TelegramClient: %s | %s' % [jid, session[:login]] )
|
||||
@xmpp = xmpp
|
||||
@jid = jid
|
||||
|
@ -225,6 +243,7 @@ class TelegramClient
|
|||
return @cache[:chats][id], @cache[:users][id]
|
||||
end
|
||||
|
||||
## get last messages from specified chat
|
||||
def get_lastmessages(id, query=nil, from=nil, count=1)
|
||||
result = @telegram.search_chat_messages(id, query.to_s, from.to_i, 0, 0, count.to_i, TD::Types::SearchMessagesFilter::Empty.new).value
|
||||
return (result) ? result.messages : []
|
||||
|
@ -247,15 +266,17 @@ class TelegramClient
|
|||
when TD::Types::UserStatus::Offline then show, status = (Time.now.getutc.to_i-status.was_online.to_i<3600) ? :away : :xa,
|
||||
DateTime.strptime((status.was_online+Time.now.getlocal(@session[:timezone]).utc_offset).to_s,'%s').strftime("Last seen at %H:%M %d/%m/%Y")
|
||||
end
|
||||
@xmpp.send_presence(@jid, id, nil, show, status, nil, photo, immed)
|
||||
return @xmpp.send_presence(@jid, id, nil, show, status, nil, photo, immed)
|
||||
end
|
||||
|
||||
## send outgoing message to telegram user
|
||||
def process_outgoing_message(id, text)
|
||||
return if self.process_command(id, text.split.first, text.split[1..-1]) or not self.online? # try to execute commands
|
||||
@logger.warn 'Sending message to chat %s' % id
|
||||
message, reply = self.format_input(text)
|
||||
@telegram.send_message(id, reply, nil, nil, message).rescue{|e| @xmpp.send_message(@jid, id, "Not sent: %s" % e)}
|
||||
reply = text.lines[0].scan(/\d+/).first.to_i if text.lines[0] =~ /^> ?[0-9]{10}/
|
||||
text = TD::Types::FormattedText.new(text: !reply ? text : text.lines[1..-1].join, entities: [])
|
||||
message = TD::Types::InputMessageContent::Text.new(text: text, disable_web_page_preview: false, clear_draft: false)
|
||||
return (id) ? @telegram.send_message(id, reply.to_i, nil, nil, message).rescue{|e| @xmpp.send_message(@jid, id, "Not sent: %s" % e)} : message
|
||||
end
|
||||
|
||||
## /commands (some telegram actions)
|
||||
|
@ -278,7 +299,7 @@ class TelegramClient
|
|||
else # chat commands
|
||||
case cmd
|
||||
when '/d' then @telegram.delete_messages(chat.id, self.get_lastmessages(chat.id, nil, @me.id, args[0]||1).map(&:id), true) # delete message
|
||||
when '/s' then @telegram.edit_message_text(chat.id, self.get_lastmessages(chat.id, nil, @me.id, 1).first.id, nil, self.format_input(args.join(' ')).first) # edit message
|
||||
when '/s' then @telegram.edit_message_text(chat.id, self.get_lastmessages(chat.id, nil, @me.id, 1).first.id, nil, self.process_outgoing_message(nil, args.join(' '))) # edit message
|
||||
when '/add' then @telegram.search_public_chat(args[0]).then{|chat| @xmpp.send_presence(@jid, chat.id, :subscribe)}.wait # add @contact
|
||||
when '/join' then @telegram.join_chat_by_invite_link(args[0]) # join https://t.me/publichat
|
||||
when '/supergroup' then @telegram.create_new_supergroup_chat(args[0], false, args[1..-1].join(' '), nil) # create new supergroup
|
||||
|
@ -287,14 +308,20 @@ class TelegramClient
|
|||
when '/group' then @telegram.create_new_basic_group_chat(chat.id, args[0]) # create group chat with current user
|
||||
when '/block' then @telegram.block_user(chat.id) # blacklists current user
|
||||
when '/unblock' then @telegram.unblock_user(chat.id) # unblacklists current user
|
||||
when '/invite' then @telegram.add_chat_member(chat.id, self.get_contact(args[0]).first.id, 100) # invite @username to current groupchat
|
||||
when '/kick' then @telegram.set_chat_member_status(chat.id, self.get_contact(args[0]).first.id, self.format_restrict()) # kick @username from current group chat
|
||||
when '/ban' then @telegram.set_chat_member_status(chat.id, self.get_contact(args[0]).first.id, self.format_restrict(true, args[1])) # ban @username from current chat [for N hours]
|
||||
when '/leave' then @telegram.leave_chat(chat.id).then{@xmpp.send_presence(@jid, id, :unsubscribed)} # leave current chat
|
||||
when '/close' then @telegram.close_secret_chat(chat.type.secret_id).then{@xmpp.send_presence(@jid, id, :unsubscribed)} # close secret chat
|
||||
when '/delete' then @telegram.delete_chat_history(chat.id, true, true).then{@xmpp.send_presence(@jid, id, :unsubscribed)} # delete current chat
|
||||
when '/members' then @telegram.search_chat_members(chat.id, args[0], 9999, TD::Types::ChatMembersFilter::Members.new).then{|m| @xmpp.send_message(@jid, chat.id, (m.members.map do |u| "%s | role: %s" % [self.format_contact(u.user_id), u.status.class] end).join("\n")) } # chat members
|
||||
when '/search' then @telegram.search_chat_messages(chat.id, args[0].to_s, 0, 0, 0, args[1].to_i||100, TD::Types::SearchMessagesFilter::Empty.new).value.messages.reverse.each{|m| @xmpp.send_message(@jid, chat.id, self.format_message(nil,nil,nil,msg))} # search
|
||||
when '/invite' then @telegram.add_chat_member(chat.id, self.get_contact(args[0]).first.id, 100) # invite @username to current groupchat
|
||||
when '/link' then @telegram.generate_chat_invite_link(chat.id).then{|link| @xmpp.send_message(@jid, chat.id, link.invite_link)} # get link to current chat
|
||||
when '/kick' then @telegram.set_chat_member_status(chat.id, self.get_contact(args[0]).first.id, TD::Types::ChatMemberStatus::Left.new()) # kick @username
|
||||
when '/mute' then @telegram.set_chat_member_status(chat.id, self.get_contact(args[0]).first.id, TD::Types::ChatMemberStatus::Restricted.new(is_member: true, restricted_until_date: self.format_bantime(args[0]), permissions: PERMISSIONS[:readonly])) # mute @username [n hours]
|
||||
when '/unmute' then @telegram.set_chat_member_status(chat.id, self.get_contact(args[0]).first.id, TD::Types::ChatMemberStatus::Restricted.new(is_member: true, restricted_until_date: 0, permissions: PERMISSIONS[:member])) # unmute @username
|
||||
when '/ban' then @telegram.set_chat_member_status(chat.id, self.get_contact(args[0]).first.id, TD::Types::ChatMemberStatus::Banned.new(banned_until_date: self.format_bantime(args[0]))) # ban @username [n hours]
|
||||
when '/unban' then @telegram.set_chat_member_status(chat.id, self.get_contact(args[0]).first.id, TD::Types::ChatMemberStatus::Member.new()) # unban @username
|
||||
when '/promote' then @telegram.set_chat_member_status(chat.id, self.get_contact(args[0]).first.id, TD::Types::ChatMemberStatus::Administrator.new(custom_title: args[0].to_s, **PERMISSIONS[:admin])) # promote @username to admin
|
||||
when '/leave' then @telegram.leave_chat(chat.id).then{@xmpp.send_presence(@jid, chat.id, :unsubscribed)} # leave current chat
|
||||
when '/leave!' then @telegram.delete_supergroup(chat.type.supergroup_id).then{@xmpp.send_presence(@jid, chat.id, :unsubscribed)}.rescue{|e| puts e.to_s} # leave current chat (for owners)
|
||||
when '/close' then @telegram.close_secret_chat(chat.type.secret_id).then{@xmpp.send_presence(@jid, chat.id, :unsubscribed)} # close secret chat
|
||||
when '/delete' then @telegram.delete_chat_history(chat.id, true, true).then{@xmpp.send_presence(@jid, chat.id, :unsubscribed)} # delete current chat
|
||||
when '/search' then @telegram.get_messages(chat.id, self.get_lastmessages(chat.id, args[0], 0, args[1]||100).map(&:id)).value.messages.reverse.each{|msg| @xmpp.send_message(@jid, chat.id, self.format_message(chat.id,msg,false))} # message search
|
||||
when '/help' then @xmpp.send_message(@jid, id, HELP_CHAT_CMD)
|
||||
else return # continue
|
||||
end
|
||||
|
@ -325,31 +352,24 @@ class TelegramClient
|
|||
return str
|
||||
end
|
||||
|
||||
def format_input(text)
|
||||
reply = text.lines[0].scan(/\d+/).first.to_i if text.lines[0] =~ /^> ?[0-9]{10}/ # quotes
|
||||
file = TD::Types::InputFile::Remote.new(id: text) if text.start_with? @@config[:content][:upload] # attaches
|
||||
text = TD::Types::FormattedText.new(text: (reply or file) ? text.lines[1..-1].join : text, entities: []) # remove first line (quotes/files)
|
||||
input = (file) ? TD::Types::InputMessageContent::Document.new(document: file, caption: text) : TD::Types::InputMessageContent::Text.new(text: text, disable_web_page_preview: false, clear_draft: false) # message
|
||||
return input, reply.to_i
|
||||
end
|
||||
|
||||
def format_forward(fwd)
|
||||
str = case fwd.origin
|
||||
when TD::Types::MessageForwardOrigin::User then self.format_contact(fwd.origin.sender_user_id)
|
||||
when TD::Types::MessageForwardOrigin::HiddenUser then fwd.origin.sender_name
|
||||
when TD::Types::MessageForwardOrigin::Channel then [self.format_contact(fwd.origin.chat_id), fwd.origin.author_signature].join(' ')
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
def format_content(file, fname)
|
||||
str = "%s (%d kbytes) | %s/%s%s" % [fname, file.size/1024, @@config[:content][:link], Digest::SHA256.hexdigest(file.remote.id), File.extname(fname).to_s]
|
||||
return str
|
||||
end
|
||||
|
||||
def format_restrict(ban=false, hours=0)
|
||||
till = (hours==0) ? 0 : Time.now.getutc.to_i + hours.to_i*3600
|
||||
return (ban) ? TD::Types::ChatMemberStatus::Banned.new(banned_until_date: till) : TD::Types::ChatMemberStatus::Left.new
|
||||
def format_forward(fwd)
|
||||
str = case fwd.origin
|
||||
when TD::Types::MessageForwardOrigin::User then self.format_contact(fwd.origin.sender_user_id)
|
||||
when TD::Types::MessageForwardOrigin::HiddenUser then fwd.origin.sender_name
|
||||
when TD::Types::MessageForwardOrigin::Channel then [self.format_contact(fwd.origin.chat_id), fwd.origin.author_signature].join ' '
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
def format_bantime(hours=0)
|
||||
now = Time.now.getutc.to_i
|
||||
till = now + hours.to_i*3600
|
||||
return (hours.to_i>0) ? till : 0
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Reference in a new issue