2016-06-13 22:18:36 +02:00
local twitter_send = { }
function twitter_send : init ( config )
if not cred_data.tw_consumer_key then
print ( ' Missing config value: tw_consumer_key. ' )
print ( ' twitter_send.lua will not be enabled. ' )
return
elseif not cred_data.tw_consumer_secret then
print ( ' Missing config value: tw_consumer_secret. ' )
print ( ' twitter_send.lua will not be enabled. ' )
return
end
twitter_send.triggers = {
2016-08-14 00:37:09 +02:00
" ^/tw (auth) (%d+)$ " ,
2016-06-13 22:18:36 +02:00
" ^/tw (unauth)$ " ,
" ^/tw (verify)$ " ,
2016-08-14 00:37:09 +02:00
" ^/tw (.+)$ " ,
" ^/(twwhitelist add) (%d+)$ " ,
" ^/(twwhitelist del) (%d+)$ " ,
" ^/(twwhitelist add)$ " ,
" ^/(twwhitelist del)$ "
2016-06-13 22:18:36 +02:00
}
twitter_send.doc = [ [ *
] ] .. config.cmd_pat .. [ [ tw * _ < Text > _ : Sendet einen Tweet an den Account , der im Chat angemeldet ist
* ] ] .. config.cmd_pat .. [ [ tw * _verify_ : Gibt den angemeldeten User aus , inklusive Profilbild
* ] ] .. config.cmd_pat .. [ [ twwitelist * _add_ _ < user > _ : Schaltet User für die Tweet - Funktion frei
* ] ] .. config.cmd_pat .. [ [ twwitelist * _del_ _ < user > _ : Entfernt User von der Tweet - Whitelist
* ] ] .. config.cmd_pat .. [ [ tw * _auth_ _ < PIN > _ : Meldet mit dieser PIN an ( Setup )
* ] ] .. config.cmd_pat .. [ [ tw * _unauth_ : Meldet Twitter - Account ab
] ]
end
twitter_send.command = ' tw <Tweet> '
local consumer_key = cred_data.tw_consumer_key
local consumer_secret = cred_data.tw_consumer_secret
function can_send_tweet ( msg )
local hash = ' user: ' .. msg.from . id
local var = redis : hget ( hash , ' can_send_tweet ' )
if var == " true " then
return true
else
return false
end
end
local client = OAuth.new ( consumer_key , consumer_secret , {
RequestToken = " https://api.twitter.com/oauth/request_token " ,
AuthorizeUser = { " https://api.twitter.com/oauth/authorize " , method = " GET " } ,
AccessToken = " https://api.twitter.com/oauth/access_token "
} )
function twitter_send : do_twitter_authorization_flow ( hash , is_chat )
local callback_url = " oob "
local values = client : RequestToken ( { oauth_callback = callback_url } )
local oauth_token = values.oauth_token
local oauth_token_secret = values.oauth_token_secret
-- save temporary oauth keys
redis : hset ( hash , ' oauth_token ' , oauth_token )
redis : hset ( hash , ' oauth_token_secret ' , oauth_token_secret )
local auth_url = client : BuildAuthorizationUrl ( { oauth_callback = callback_url , force_login = true } )
if is_chat then
2016-07-02 00:13:17 +02:00
return ' Bitte schließe den Vorgang ab, indem du unten auf den attraktiven Button klickst und mir die angezeigte PIN per `/tw auth PIN` *in der Gruppe von gerade eben* übergibst. ' , auth_url
2016-06-13 22:18:36 +02:00
else
2016-07-02 00:13:17 +02:00
return ' Bitte schließe den Vorgang ab, indem du unten auf den attraktiven Button klickst und mir die angezeigte PIN per `/tw auth PIN` übergibst. ' , auth_url
2016-06-13 22:18:36 +02:00
end
end
function twitter_send : get_twitter_access_token ( hash , oauth_verifier , oauth_token , oauth_token_secret )
local oauth_verifier = tostring ( oauth_verifier ) -- must be a string
-- now we'll use the tokens we got in the RequestToken call, plus our PIN
local client = OAuth.new ( consumer_key , consumer_secret , {
RequestToken = " https://api.twitter.com/oauth/request_token " ,
AuthorizeUser = { " https://api.twitter.com/oauth/authorize " , method = " GET " } ,
AccessToken = " https://api.twitter.com/oauth/access_token "
} , {
OAuthToken = oauth_token ,
OAuthVerifier = oauth_verifier
} )
client : SetTokenSecret ( oauth_token_secret )
local values , err , headers , status , body = client : GetAccessToken ( )
if err then return ' Einloggen fehlgeschlagen! ' end
-- save permanent oauth keys
redis : hset ( hash , ' oauth_token ' , values.oauth_token )
redis : hset ( hash , ' oauth_token_secret ' , values.oauth_token_secret )
2016-08-14 00:37:09 +02:00
local screen_name = values.screen_name
return ' Erfolgreich eingeloggt als <a href="https://twitter.com/ ' .. screen_name .. ' ">@ ' .. screen_name .. ' </a> (User-ID: ' .. values.user_id .. ' ) '
2016-06-13 22:18:36 +02:00
end
function twitter_send : reset_twitter_auth ( hash , frominvalid )
redis : hdel ( hash , ' oauth_token ' )
redis : hdel ( hash , ' oauth_token_secret ' )
if frominvalid then
2016-08-14 00:37:09 +02:00
return ' <b>Authentifizierung nicht erfolgreich, wird zurückgesetzt...</b> '
2016-06-13 22:18:36 +02:00
else
2016-08-14 00:37:09 +02:00
return ' <b>Erfolgreich abgemeldet!</b> Entziehe den Zugriff endgültig in deinen <a href="https://twitter.com/settings/applications">Twitter-Einstellungen</a>! '
2016-06-13 22:18:36 +02:00
end
end
function twitter_send : resolve_url ( url )
local response_body = { }
local request_constructor = {
url = url ,
method = " HEAD " ,
sink = ltn12.sink . table ( response_body ) ,
headers = { } ,
redirect = false
}
local ok , response_code , response_headers , response_status_line = http.request ( request_constructor )
if ok and response_headers.location then
return response_headers.location
else
return url
end
end
function twitter_send : twitter_verify_credentials ( oauth_token , oauth_token_secret )
local client = OAuth.new ( consumer_key , consumer_secret , {
RequestToken = " https://api.twitter.com/oauth/request_token " ,
AuthorizeUser = { " https://api.twitter.com/oauth/authorize " , method = " GET " } ,
AccessToken = " https://api.twitter.com/oauth/access_token "
} , {
OAuthToken = oauth_token ,
OAuthTokenSecret = oauth_token_secret
} )
local response_code , response_headers , response_status_line , response_body =
client : PerformRequest (
" GET " , " https://api.twitter.com/1.1/account/verify_credentials.json " , {
include_entities = false ,
skip_status = true ,
include_email = false
}
)
local response = json.decode ( response_body )
if response_code == 401 then
return twitter_send : reset_twitter_auth ( hash , true )
end
if response_code ~= 200 then
return ' HTTP-Fehler ' .. response_code .. ' : ' .. data.errors [ 1 ] . message
end
-- TODO: copied straight from the twitter_user plugin, maybe we can do it better?
local full_name = response.name
local user_name = response.screen_name
if response.verified then
user_name = user_name .. ' ✅ '
end
if response.protected then
user_name = user_name .. ' 🔒 '
end
local header = full_name .. " (@ " .. user_name .. " ) \n "
local description = unescape ( response.description )
if response.location then
location = response.location
else
location = ' '
end
if response.url and response.location ~= ' ' then
url = ' | ' .. twitter_send : resolve_url ( response.url ) .. ' \n '
elseif response.url and response.location == ' ' then
url = twitter_send : resolve_url ( response.url ) .. ' \n '
else
url = ' \n '
end
local body = description .. ' \n ' .. location .. url
local favorites = comma_value ( response.favourites_count )
local follower = comma_value ( response.followers_count )
local following = comma_value ( response.friends_count )
local statuses = comma_value ( response.statuses_count )
local footer = statuses .. ' Tweets, ' .. follower .. ' Follower, ' .. following .. ' folge ich, ' .. favorites .. ' Tweets favorisiert '
local text = ' Eingeloggter Account: \n ' .. header .. body .. footer
local pp_url = string.gsub ( response.profile_image_url_https , " normal " , " 400x400 " )
return text , pp_url
end
function twitter_send : send_tweet ( tweet , oauth_token , oauth_token_secret , hash )
local client = OAuth.new ( consumer_key , consumer_secret , {
RequestToken = " https://api.twitter.com/oauth/request_token " ,
AuthorizeUser = { " https://api.twitter.com/oauth/authorize " , method = " GET " } ,
AccessToken = " https://api.twitter.com/oauth/access_token "
} , {
OAuthToken = oauth_token ,
OAuthTokenSecret = oauth_token_secret
} )
local response_code , response_headers , response_status_line , response_body =
client : PerformRequest (
" POST " , " https://api.twitter.com/1.1/statuses/update.json " , {
status = tweet
}
)
local data = json.decode ( response_body )
if response_code == 401 then
return twitter_send : reset_twitter_auth ( hash , true )
end
if response_code ~= 200 then
return ' HTTP-Fehler ' .. response_code .. ' : ' .. data.errors [ 1 ] . message
end
local statusnumber = comma_value ( data.user . statuses_count )
local screen_name = data.user . screen_name
local status_id = data.id_str
2016-08-14 00:37:09 +02:00
return ' <a href="https://twitter.com/ ' .. screen_name .. ' /status/ ' .. status_id .. ' ">Tweet # ' .. statusnumber .. ' gesendet!</a> '
2016-06-13 22:18:36 +02:00
end
function twitter_send : add_to_twitter_whitelist ( user_id )
local hash = ' user: ' .. user_id
local whitelisted = redis : hget ( hash , ' can_send_tweet ' )
if whitelisted ~= ' true ' then
print ( ' Setting can_send_tweet in redis hash ' .. hash .. ' to true ' )
redis : hset ( hash , ' can_send_tweet ' , true )
return ' *User ' .. user_id .. ' kann jetzt Tweets senden!* '
else
return ' *User ' .. user_id .. ' kann schon Tweets senden.* '
end
end
function twitter_send : del_from_twitter_whitelist ( user_id )
local hash = ' user: ' .. user_id
local whitelisted = redis : hget ( hash , ' can_send_tweet ' )
if whitelisted == ' true ' then
print ( ' Setting can_send_tweet in redis hash ' .. hash .. ' to false ' )
redis : hset ( hash , ' can_send_tweet ' , false )
return ' *User ' .. user_id .. ' kann jetzt keine Tweets mehr senden!* '
else
return ' *User ' .. user_id .. ' ist nicht whitelisted.* '
end
end
function twitter_send : action ( msg , config , matches )
2016-08-14 00:37:09 +02:00
if matches [ 1 ] == " twwhitelist add " then
2016-06-13 22:18:36 +02:00
if msg.from . id ~= config.admin then
utilities.send_reply ( self , msg , config.errors . sudo )
return
else
2016-08-14 00:37:09 +02:00
local user_id = matches [ 2 ]
if not user_id then
if not msg.reply_to_message then
return
end
user_id = msg.reply_to_message . from.id
end
utilities.send_reply ( self , msg , twitter_send : add_to_twitter_whitelist ( user_id ) , true )
2016-06-13 22:18:36 +02:00
return
end
end
2016-08-14 00:37:09 +02:00
if matches [ 1 ] == " twwhitelist del " then
2016-06-13 22:18:36 +02:00
if msg.from . id ~= config.admin then
utilities.send_reply ( self , msg , config.errors . sudo )
return
else
2016-08-14 00:37:09 +02:00
local user_id = matches [ 2 ]
if not user_id then
if not msg.reply_to_message then
return
end
user_id = msg.reply_to_message . from.id
end
utilities.send_reply ( self , msg , twitter_send : del_from_twitter_whitelist ( user_id ) , true )
2016-06-13 22:18:36 +02:00
return
end
end
local hash = get_redis_hash ( msg , ' twitter ' )
local oauth_token = redis : hget ( hash , ' oauth_token ' )
local oauth_token_secret = redis : hget ( hash , ' oauth_token_secret ' )
-- Thanks to the great doc at https://github.com/ignacio/LuaOAuth#a-more-involved-example
if not oauth_token and not oauth_token_secret then
if msg.chat . type == ' group ' or msg.chat . type == ' supergroup ' then
if msg.from . id ~= config.admin then
utilities.send_reply ( self , msg , config.errors . sudo )
return
else
2016-07-02 00:13:17 +02:00
local text , auth_url = twitter_send : do_twitter_authorization_flow ( hash , true )
local res = utilities.send_message ( self , msg.from . id , text , true , nil , true , ' {"inline_keyboard":[[{"text":"Bei Twitter anmelden","url":" ' .. auth_url .. ' "}]]} ' )
2016-06-13 22:18:36 +02:00
if not res then
utilities.send_reply ( self , msg , ' Bitte starte mich zuerst [privat](http://telegram.me/ ' .. self.info . username .. ' ?start). ' , true )
elseif msg.chat . type ~= ' private ' then
2016-07-02 00:13:17 +02:00
local result = utilities.send_message ( self , msg.chat . id , ' _Bitte warten, der Administrator meldet sich an..._ ' , true , nil , true )
redis : hset ( hash , ' login_msg ' , result.result . message_id )
2016-06-13 22:18:36 +02:00
end
return
end
else
2016-07-02 00:13:17 +02:00
local text , auth_url = twitter_send : do_twitter_authorization_flow ( hash )
local result = utilities.send_reply ( self , msg , text , true , ' {"inline_keyboard":[[{"text":"Bei Twitter anmelden","url":" ' .. auth_url .. ' "}]]} ' )
redis : hset ( hash , ' login_msg ' , result.result . message_id )
2016-06-13 22:18:36 +02:00
return
end
end
if matches [ 1 ] == ' auth ' and matches [ 2 ] then
if msg.chat . type == ' group ' or msg.chat . type == ' supergroup ' then
if msg.from . id ~= config.admin then
utilities.send_reply ( self , msg , config.errors . sudo )
return
end
end
if string.len ( matches [ 2 ] ) > 7 then utilities.send_reply ( self , msg , ' Invalide PIN! ' ) return end
2016-08-14 00:37:09 +02:00
utilities.send_reply ( self , msg , twitter_send : get_twitter_access_token ( hash , matches [ 2 ] , oauth_token , oauth_token_secret ) , ' HTML ' )
2016-07-02 00:13:17 +02:00
local message_id = redis : hget ( hash , ' login_msg ' )
utilities.edit_message ( self , msg.chat . id , message_id , ' *Anmeldung abgeschlossen!* ' , true , true )
redis : hdel ( hash , ' login_msg ' )
2016-06-13 22:18:36 +02:00
return
end
if matches [ 1 ] == ' unauth ' then
if msg.chat . type == ' group ' or msg.chat . type == ' supergroup ' then
if msg.from . id ~= config.admin then
utilities.send_reply ( self , msg , config.errors . sudo )
return
end
end
2016-08-14 00:37:09 +02:00
utilities.send_reply ( self , msg , twitter_send : reset_twitter_auth ( hash ) , ' HTML ' )
2016-06-13 22:18:36 +02:00
return
end
if matches [ 1 ] == ' verify ' then
local text , pp_url = twitter_send : twitter_verify_credentials ( oauth_token , oauth_token_secret )
local file = download_to_file ( pp_url )
utilities.send_photo ( self , msg.chat . id , file , nil , msg.message_id )
utilities.send_reply ( self , msg , text )
return
end
if msg.chat . type == ' group ' or msg.chat . type == ' supergroup ' then
if not can_send_tweet ( msg ) then
utilities.send_reply ( self , msg , ' *Du darfst keine Tweets senden.* Entweder wurdest du noch gar nicht freigeschaltet oder ausgeschlossen. ' , true )
return
else
2016-08-14 00:37:09 +02:00
utilities.send_reply ( self , msg , twitter_send : send_tweet ( matches [ 1 ] , oauth_token , oauth_token_secret , hash ) , ' HTML ' )
2016-06-13 22:18:36 +02:00
return
end
else
2016-08-14 00:37:09 +02:00
utilities.send_reply ( self , msg , twitter_send : send_tweet ( matches [ 1 ] , oauth_token , oauth_token_secret , hash ) , ' HTML ' )
2016-06-13 22:18:36 +02:00
return
end
end
return twitter_send