Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F77434
telegram.ex
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
10 KB
Subscribers
None
telegram.ex
View Options
defmodule
Nola.Telegram
do
require
Logger
@behaviour
Telegram.ChatBot
def
my_path
()
do
"https://t.me/beauttebot"
end
def
send_message
(
id
,
text
,
md2
\\
false
)
do
md
=
if
md2
,
do
:
"MarkdownV2"
,
else
:
"Markdown"
token
=
Keyword
.
get
(
Application
.
get_env
(
:nola
,
:telegram
,
[]),
:key
)
Telegram.Bot.ChatBot.Chat.Session.Supervisor
.
start_child
(
Nola.Telegram
,
id
)
Telegram.Api
.
request
(
token
,
"sendMessage"
,
chat_id
:
id
,
text
:
text
,
parse_mode
:
"Markdown"
)
end
@impl
Telegram.ChatBot
def
init
(
chat_id
)
when
chat_id
<
0
do
{
:ok
,
state
}
=
Nola.TelegramRoom
.
init
(
chat_id
)
{
:ok
,
%{
room_state
:
state
}}
end
def
init
(
chat_id
)
do
Logger
.
info
(
"Telegram session starting:
#{
chat_id
}
"
)
account
=
Nola.Account
.
find_meta_account
(
"telegram-id"
,
chat_id
)
account_id
=
if
account
,
do
:
account
.
id
{
:ok
,
%{
account
:
account_id
}}
end
@impl
Telegram.ChatBot
def
handle_update
(
update
,
token
,
%{
room_state
:
room_state
})
do
{
:ok
,
room_state
}
=
Nola.TelegramRoom
.
handle_update
(
update
,
token
,
room_state
)
{
:ok
,
%{
room_state
:
room_state
}}
end
def
handle_update
(%{
"message"
=>
m
=
%{
"chat"
=>
%{
"type"
=>
"private"
},
"text"
=>
text
=
"/start"
<>
_
}},
_token
,
state
)
do
text
=
"*Welcome to beautte!*
\n\n
Query the bot on IRC and say \"enable-telegram\" to continue."
send_message
(
m
[
"chat"
][
"id"
],
text
)
{
:ok
,
%{
account
:
nil
}}
end
def
handle_update
(%{
"message"
=>
m
=
%{
"chat"
=>
%{
"type"
=>
"private"
},
"text"
=>
text
=
"/enable"
<>
_
}},
_token
,
state
)
do
key
=
case
String
.
split
(
text
,
" "
)
do
[
"/enable"
,
key
|
_
]
->
key
_
->
"nil"
end
#Handled message "1247435154:AAGnSSCnySn0RuVxy_SUcDEoOX_rbF6vdq0" %{"message" =>
# %{"chat" => %{"first_name" => "J", "id" => 2075406, "type" => "private", "username" => "ahref"},
# "date" => 1591027272, "entities" =>
# [%{"length" => 7, "offset" => 0, "type" => "bot_command"}],
# "from" => %{"first_name" => "J", "id" => 2075406, "is_bot" => false, "language_code" => "en", "username" => "ahref"},
# "message_id" => 11, "text" => "/enable salope"}, "update_id" => 764148578}
account
=
Nola.Account
.
find_meta_account
(
"telegram-validation-code"
,
String
.
downcase
(
key
))
text
=
if
account
do
net
=
Nola.Account
.
get_meta
(
account
,
"telegram-validation-target"
)
Nola.Account
.
put_meta
(
account
,
"telegram-id"
,
m
[
"chat"
][
"id"
])
Nola.Account
.
put_meta
(
account
,
"telegram-username"
,
m
[
"chat"
][
"username"
])
Nola.Account
.
put_meta
(
account
,
"telegram-username"
,
m
[
"chat"
][
"username"
])
Nola.Account
.
delete_meta
(
account
,
"telegram-validation-code"
)
Nola.Account
.
delete_meta
(
account
,
"telegram-validation-target"
)
Nola.Irc.Connection
.
broadcast_message
(
net
,
account
,
"Telegram
#{
m
[
"chat"
][
"username"
]
}
account added!"
)
"Yay! Linked to account **
#{
account
.
name
}
**."
else
"Token invalid"
end
send_message
(
m
[
"chat"
][
"id"
],
text
)
{
:ok
,
%{
account
:
account
.
id
}}
end
#[debug] Unhandled update: %{"message" =>
# %{"chat" => %{"first_name" => "J", "id" => 2075406, "type" => "private", "username" => "ahref"},
# "date" => 1591096015,
# "from" => %{"first_name" => "J", "id" => 2075406, "is_bot" => false, "language_code" => "en", "username" => "ahref"},
# "message_id" => 29,
# "photo" => [
# %{"file_id" => "AgACAgQAAxkBAAMdXtYyz4RQqLcpOlR6xKK3w3NayHAAAnCzMRuL4bFSgl_cTXMl4m5G_T0kXQADAQADAgADbQADZVMBAAEaBA",
# "file_size" => 9544, "file_unique_id" => "AQADRv09JF0AA2VTAQAB", "height" => 95, "width" => 320},
# %{"file_id" => "AgACAgQAAxkBAAMdXtYyz4RQqLcpOlR6xKK3w3NayHAAAnCzMRuL4bFSgl_cTXMl4m5G_T0kXQADAQADAgADeAADZFMBAAEaBA",
# "file_size" => 21420, "file_unique_id" => "AQADRv09JF0AA2RTAQAB", "height" => 148, "width" => 501}]},
# "update_id" => 218161546}
for
type
<-
~w(photo voice video document animation)
do
def
handle_update
(
data
=
%{
"message"
=>
%{
unquote
(
type
)
=>
_
}},
token
,
state
)
do
start_upload
(
unquote
(
type
),
data
,
token
,
state
)
end
end
#[debug] Unhandled update: %{"callback_query" =>
# %{
# "chat_instance" => "-7948978714441865930", "data" => "evolu.net/#dmz",
# "from" => %{"first_name" => "J", "id" => 2075406, "is_bot" => false, "language_code" => "en", "username" => "ahref"},
# "id" => "8913804780149600",
# "message" => %{"chat" => %{"first_name" => "J", "id" => 2075406, "type" => "private", "username" => "ahref"},
# "date" => 1591098553, "from" => %{"first_name" => "devbeautte", "id" => 1293058838, "is_bot" => true, "username" => "devbeauttebot"},
# "message_id" => 62,
# "reply_markup" => %{"inline_keyboard" => [[%{"callback_data" => "random/#", "text" => "random/#"},
# %{"callback_data" => "evolu.net/#dmz", "text" => "evolu.net/#dmz"}]]},
# "text" => "Where should I send the file?"}
# }
# , "update_id" => 218161568}
#def handle_update(t, %{"callback_query" => cb = %{"data" => "resend", "id" => id, "message" => m = %{"message_id" => m_id, "chat" => %{"id" => chat_id}, "reply_to_message" => op}}}) do
#end
def
handle_update
(%{
"callback_query"
=>
cb
=
%{
"data"
=>
"start-upload:"
<>
target
,
"id"
=>
id
,
"message"
=>
m
=
%{
"message_id"
=>
m_id
,
"chat"
=>
%{
"id"
=>
chat_id
},
"reply_to_message"
=>
op
}}},
t
,
state
)
do
account
=
Nola.Account
.
find_meta_account
(
"telegram-id"
,
chat_id
)
if
account
do
target
=
case
String
.
split
(
target
,
"/"
)
do
[
"everywhere"
]
->
Nola.Membership
.
of_account
(
account
)
[
net
,
chan
]
->
[{
net
,
chan
}]
end
Telegram.Api
.
request
(
t
,
"editMessageText"
,
chat_id
:
chat_id
,
message_id
:
m_id
,
text
:
"Processing..."
,
reply_markup
:
%{})
{
content
,
type
}
=
cond
do
op
[
"photo"
]
->
{
op
[
"photo"
],
""
}
op
[
"voice"
]
->
{
op
[
"voice"
],
" a voice message"
}
op
[
"video"
]
->
{
op
[
"video"
],
""
}
op
[
"document"
]
->
{
op
[
"document"
],
""
}
op
[
"animation"
]
->
{
op
[
"animation"
],
""
}
end
file
=
if
is_list
(
content
)
&&
Enum
.
count
(
content
)
>
1
do
Enum
.
sort_by
(
content
,
fn
(
p
)
->
p
[
"file_size"
]
end
,
&>=/
2
)
|>
List
.
first
()
else
content
end
file_id
=
file
[
"file_id"
]
file_unique_id
=
file
[
"file_unique_id"
]
text
=
if
(
op
[
"caption"
],
do
:
": "
<>
op
[
"caption"
]
<>
""
,
else
:
""
)
resend
=
%{
"inline_keyboard"
=>
[
[%{
"text"
=>
"re-share"
,
"callback_data"
=>
"resend"
}]
]}
spawn
(
fn
()
->
with
\
{
:ok
,
file
}
<-
Telegram.Api
.
request
(
t
,
"getFile"
,
file_id
:
file_id
),
path
=
"https://api.telegram.org/file/bot
#{
t
}
/
#{
file
[
"file_path"
]
}
"
,
{
:ok
,
%
HTTPoison.Response
{
status_code
:
200
,
body
:
body
}}
<-
HTTPoison
.
get
(
path
),
<<
smol_body
::
binary
-
size
(
20
),
_
::
binary
>>
=
body
,
{
:ok
,
magic
}
<-
GenMagic.Pool
.
perform
(
Nola.GenMagic
,
{
:bytes
,
smol_body
}),
bucket
=
Application
.
get_env
(
:nola
,
:s3
,
[])
|>
Keyword
.
get
(
:bucket
),
ext
=
Path
.
extname
(
file
[
"file_path"
]),
s3path
=
"
#{
account
.
id
}
/
#{
file_unique_id
}#{
ext
}
"
,
Telegram.Api
.
request
(
t
,
"editMessageText"
,
chat_id
:
chat_id
,
message_id
:
m_id
,
text
:
"*Uploading...*"
,
reply_markup
:
%{},
parse_mode
:
"MarkdownV2"
),
s3req
=
ExAws.S3
.
put_object
(
bucket
,
s3path
,
body
,
acl
:
:public_read
,
content_type
:
magic
.
mime_type
),
{
:ok
,
_
}
<-
ExAws
.
request
(
s3req
)
do
path
=
NolaWeb.Router.Helpers
.
url
(
NolaWeb.Endpoint
)
<>
"/files/
#{
s3path
}
"
sent
=
for
{
net
,
chan
}
<-
target
do
txt
=
"sent
#{
type
}#{
text
}
#{
path
}
"
Nola.Irc
.
send_message_as
(
account
,
net
,
chan
,
txt
)
"
#{
net
}
/
#{
chan
}
"
end
if
caption
=
op
[
"caption"
],
do
:
as_irc_message
(
chat_id
,
caption
,
account
)
text
=
"Sent on "
<>
Enum
.
join
(
sent
,
", "
)
<>
" !"
Telegram.Api
.
request
(
t
,
"editMessageText"
,
chat_id
:
chat_id
,
message_id
:
m_id
,
text
:
"_Sent!_"
,
reply_markup
:
%{},
parse_mode
:
"MarkdownV2"
)
else
error
->
Telegram.Api
.
request
(
t
,
"editMessageText"
,
chat_id
:
chat_id
,
message_id
:
m_id
,
text
:
"Something failed."
,
reply_markup
:
%{},
parse_mode
:
"MarkdownV2"
)
Logger
.
error
(
"Failed upload from Telegram:
#{
inspect
error
}
"
)
end
end
)
end
{
:ok
,
state
}
end
def
handle_update
(%{
"message"
=>
m
=
%{
"chat"
=>
%{
"id"
=>
id
,
"type"
=>
"private"
},
"text"
=>
text
}},
_
,
state
)
do
account
=
Nola.Account
.
find_meta_account
(
"telegram-id"
,
id
)
if
account
do
as_irc_message
(
id
,
text
,
account
)
end
{
:ok
,
state
}
end
def
handle_update
(
m
,
_
,
state
)
do
Logger
.
debug
(
"Unhandled update:
#{
inspect
m
}
"
)
{
:ok
,
state
}
end
@impl
Telegram.ChatBot
def
handle_info
(
info
,
%{
room_state
:
room_state
})
do
{
:ok
,
room_state
}
=
Nola.TelegramRoom
.
handle_info
(
info
,
room_state
)
{
:ok
,
%{
room_state
:
room_state
}}
end
def
handle_info
(
_info
,
state
)
do
{
:ok
,
state
}
end
defp
as_irc_message
(
id
,
text
,
account
)
do
reply_fun
=
fn
(
text
)
->
send_message
(
id
,
text
)
end
trigger_text
=
cond
do
String
.
starts_with?
(
text
,
"/"
)
->
"/"
<>
text
=
text
"!"
<>
text
Enum
.
any?
(
Nola.Irc.Connection
.
triggers
(),
fn
({
trigger
,
_
})
->
String
.
starts_with?
(
text
,
trigger
)
end
)
->
text
true
->
"!"
<>
text
end
message
=
%
Nola.Message
{
id
:
FlakeId
.
get
(),
transport
:
:telegram
,
network
:
"telegram"
,
channel
:
nil
,
text
:
text
,
account
:
account
,
sender
:
%
ExIRC.SenderInfo
{
nick
:
account
.
name
},
replyfun
:
reply_fun
,
trigger
:
Nola.Irc.Connection
.
extract_trigger
(
trigger_text
),
at
:
nil
}
Nola.Irc.Connection
.
publish
(
message
,
[
"messages:private"
,
"messages:telegram"
,
"telegram/
#{
account
.
id
}
:messages"
])
message
end
defp
start_upload
(
_type
,
%{
"message"
=>
m
=
%{
"chat"
=>
%{
"id"
=>
id
,
"type"
=>
"private"
}}},
token
,
state
)
do
account
=
Nola.Account
.
find_meta_account
(
"telegram-id"
,
id
)
if
account
do
text
=
if
(
m
[
"text"
],
do
:
m
[
"text"
],
else
:
nil
)
targets
=
Nola.Membership
.
of_account
(
account
)
|>
Enum
.
map
(
fn
({
net
,
chan
})
->
"
#{
net
}
/
#{
chan
}
"
end
)
|>
Enum
.
map
(
fn
(
i
)
->
%{
"text"
=>
i
,
"callback_data"
=>
"start-upload:
#{
i
}
"
}
end
)
kb
=
if
Enum
.
count
(
targets
)
>
1
do
[%{
"text"
=>
"everywhere"
,
"callback_data"
=>
"start-upload:everywhere"
}]
++
targets
else
targets
end
|>
Enum
.
chunk_every
(
2
)
keyboard
=
%{
"inline_keyboard"
=>
kb
}
Telegram.Api
.
request
(
token
,
"sendMessage"
,
chat_id
:
id
,
text
:
"Where should I send this file?"
,
reply_markup
:
keyboard
,
reply_to_message_id
:
m
[
"message_id"
],
parse_mode
:
"MarkdownV2"
)
end
{
:ok
,
state
}
end
end
File Metadata
Details
Attached
Mime Type
text/x-ruby
Expires
Mon, Jul 7, 4:01 PM (1 d, 9 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
49914
Default Alt Text
telegram.ex (10 KB)
Attached To
rNOLA Nola
Event Timeline
Log In to Comment