-
Notifications
You must be signed in to change notification settings - Fork 1
/
mei_portuguese_bot.rb
170 lines (151 loc) · 5.46 KB
/
mei_portuguese_bot.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
DB = Sequel.connect(ENV['DATABASE_URL'] || 'postgres://localhost:5432/mei_portuguese_bot')
BOT_TOKEN = ENV['BOT_TOKEN']
Events = DB[:events]
InterfaceChats = DB[:interface_chats]
Tokens = DB[:tokens]
EMOJI = /([\u{1F600}-\u{1F6FF}])/
def send_message(message)
bot_api = Faraday.new(url: "https://api.telegram.org/bot#{BOT_TOKEN}/sendMessage")
bot_api.post do |request|
request.headers['Content-Type'] = 'application/json'
request.body = message
end
end
def send_sticker(message)
bot_api = Faraday.new(url: "https://api.telegram.org/bot#{BOT_TOKEN}/sendSticker")
bot_api.post do |request|
request.headers['Content-Type'] = 'application/json'
request.body = message
end
end
def get_new_token
tokens_api = Faraday.new(url: "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13")
response = tokens_api.post do |request|
request.headers = { 'Content-Type' => 'application/x-www-form-urlencoded' }
request.body = {
client_id: ENV['CLIENT_ID'],
client_secret: ENV['CLIENT_SECRET'],
scope: 'http://api.microsofttranslator.com',
grant_type: 'client_credentials'
}
end
new_token = JSON.parse(response.body)
if new_token['error']
raise "[Error] generating token: #{new_token['error']}\n[Error] description: #{new_token['error_description']}"
end
new_token
end
def save_token(new_token)
Tokens.delete
Tokens.insert(
expires_at: Time.now.to_i + new_token['expires_in'].to_i,
value: new_token['access_token']
)
end
def token
last_token = Tokens.order(:expires_at).last
if last_token && last_token[:expires_at] > Time.now.to_i + 10
last_token[:value]
else
puts "[INFO] creating new token"
new_token = get_new_token
save_token(new_token)
puts "[INFO] new token created"
new_token['access_token']
end
end
def translate(message)
translation_api = Faraday.new(url: "http://api.microsofttranslator.com/v2/Http.svc/Translate")
puts "[INFO] requesting translation"
response = translation_api.get do |request|
request.headers['Authorization'] = "Bearer #{token}"
request.params['from'] = 'pt'
request.params['to'] = 'en'
request.params['text'] = message
end
if response.status.to_i > 200 && response.body =~ /^<html>/
puts "[Error] translation api returned this:\n#{response.body}"
"[Error] translation api returned this:\n#{response.body}"
else
response.body =~ />([^<]+)</
$1
end
end
def register_chat chat_id
if InterfaceChats.where(chat_id: chat_id)
send_message({chat_id: chat_id, text: 'chat was already registered'}.to_json)
puts "[Info] send_message({chat_id: #{chat_id}, text: #{'chat was already registered'}}.to_json)"
else
InterfaceChats.insert(chat_id: chat_id)
send_message({chat_id: chat_id, text: 'chat registered successfully'}.to_json)
puts "[Info] send_message({chat_id: #{chat_id}, text: #{'chat registered successfully'}}.to_json)"
end
end
def unregister_chat chat_id
if InterfaceChats.where(chat_id: chat_id)
InterfaceChats.where(chat_id: chat_id).delete
send_message({chat_id: chat_id, text: 'chat unregistered'}.to_json)
puts "[Info] send_message({chat_id: #{chat_id}, text: #{'chat unregistered'}}.to_json)"
else
send_message({chat_id: chat_id, text: 'nothing to do here'}.to_json)
puts "[Info] send_message({chat_id: #{chat_id}, text: #{'nothing to do here'}}.to_json)"
end
end
def sender(from)
"#{from['first_name']} #{from['last_name']} (#{from['username']})"
end
def text_message(message, from)
case message['text']
when '/start_mei_bot'
# register_chat(message['chat']['id'])
when '/end_mei_bot'
# unregister_chat(message['chat']['id'])
else
translated_message = "#{sender(from)} said:\n"
text = message['text']
translated_message << Rumoji.encode(translate(Rumoji.decode(text)))
puts "[Info] going to publish message to #{InterfaceChats.count} telegram things"
InterfaceChats.map(:chat_id).each do |chat_id|
request = send_message({chat_id: chat_id, text: translated_message}.to_json)
puts "[Info] send_message({chat_id: #{chat_id}, text: #{translated_message}}.to_json)"
end
{ published_message: translated_message }
end
end
def sticker_message(message, from)
puts "[Info] going to publish message to #{InterfaceChats.count} telegram things"
InterfaceChats.map(:chat_id).each do |chat_id|
request = send_message({chat_id: chat_id, text: "#{sender(from)} sent the sticker:\n"}.to_json)
request = send_sticker({chat_id: chat_id, sticker: message['sticker']['file_id']}.to_json)
puts "[Info] sticker sent"
end
{ published_message: 'sticker' }
end
def handle_message result
return {already: 'processed'} if Events[telegram_id: result['update_id']]
DB.transaction do
message = result['message']
Events.insert(telegram_id: result['update_id'], content: {message: message}.to_json)
from = message['from']
text_message(message, from) if message['text']
sticker_message(message, from) if message['sticker']
end
end
def process ping
if ping.keys.include?('ok') && !ping['ok']
if ping.keys.include?('error_code') && ping.keys.include?('description')
puts "[Error] #{ping['error_code']}: #{ping['description']}"
{ error: :sorry }
else
{ random: 'error' }
end
else
handle_message ping
end
end
post "/#{BOT_TOKEN}" do
ping = JSON.parse request.body.read
puts "[Info] received new message with keys: #{ping.keys.inspect}"
puts "[DEBUG] #{ping.inspect}" if ENV['DEBUG']
json(process(ping))
end