twitter.erl 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. -module(twitter).
  2. -author('Andrii Zadorozhnii').
  3. -include_lib("nitro/include/nitro.hrl").
  4. -include_lib("n2o/include/wf.hrl").
  5. -include_lib("avz/include/avz.hrl").
  6. -include_lib("kvs/include/user.hrl").
  7. -compile(export_all).
  8. -export(?API).
  9. -define(CONSUMER_KEY, application:get_env(avz, tw_consumer_key, [])).
  10. -define(CONSUMER_SECRET, application:get_env(avz, tw_consumer_secret, [])).
  11. -define(CONSUMER, {?CONSUMER_KEY, ?CONSUMER_SECRET, hmac_sha1}).
  12. registration_data(Props, twitter, Ori)->
  13. Id = proplists:get_value(<<"id_str">>, Props),
  14. UserName = binary_to_list(proplists:get_value(<<"screen_name">>, Props)),
  15. Email = email_prop(Props,twitter),
  16. Ori#user{ username = re:replace(UserName, "\\.", "_", [{return, list}]),
  17. display_name = proplists:get_value(<<"screen_name">>, Props),
  18. images = avz:update({tw_avatar,proplists:get_value(<<"profile_image_url">>, Props)},Ori#user.images),
  19. names = proplists:get_value(<<"name">>, Props),
  20. email = Email,
  21. surnames = [],
  22. tokens = avz:update({twitter,Id},Ori#user.tokens),
  23. register_date = os:timestamp(),
  24. status = ok }.
  25. index(K) -> wf:to_binary(K).
  26. email_prop(Props, twitter) -> proplists:get_value(<<"screen_name">>, Props).
  27. callback() ->
  28. Token = wf:q(<<"oauth_token">>),
  29. Verifier = wf:q(<<"oauth_verifier">>),
  30. case wf:user() of
  31. undefined ->
  32. if (Token /= undefined) andalso ( Verifier/= undefined) ->
  33. case get_access_token(binary_to_list(Token), binary_to_list(Verifier)) of
  34. not_authorized -> skip;
  35. Props -> UserData = show(Props), avz:login(twitter, UserData) end;
  36. true -> skip end;
  37. _ -> skip end.
  38. login_button() -> application:get_env(avz,twitter_button,#panel{class=["btn-group"], body=
  39. #link{id=twlogin, class=[btn, "btn-info", "btn-large", "btn-lg"],
  40. body=[#i{class=[fa,"fa-twitter","fa-lg","icon-twitter", "icon-large"]}, <<"Twitter">>],
  41. postback={twitter,logintwitter}}}).
  42. sdk() -> [].
  43. api_event(_,_,_) -> ok.
  44. event({twitter,logintwitter}) ->
  45. case get_request_token() of
  46. {RequestToken, _, _} -> wf:redirect(authenticate_url(RequestToken));
  47. {error, R} -> wf:info(?MODULE, "Twitter request failed:", [R]), [] end.
  48. get_request_token()->
  49. URL = "https://api.twitter.com/oauth/request_token",
  50. case oauth:get(URL, [], ?CONSUMER) of
  51. {ok, Response} ->
  52. % json response {"errors":[{"code": Code,"message":Message}]} should be handled here
  53. Params = oauth:params_decode(Response),
  54. RequestToken = oauth:token(Params),
  55. RequestTokenSecret = oauth:token_secret(Params),
  56. CallbackConfirmed = proplists:get_value("oauth_callback_confirmed", Params),
  57. {RequestToken, RequestTokenSecret, CallbackConfirmed};
  58. {error, E}-> {error, E}
  59. end.
  60. get_access_token(undefined, undefined)-> not_authorized;
  61. get_access_token(undefined, _)-> not_authorized;
  62. get_access_token(_, undefined)-> not_authorized;
  63. get_access_token(Token, Verifier)->
  64. URL = "https://api.twitter.com/oauth/access_token",
  65. Signed = oauth:sign("GET", URL, [{"oauth_verifier", Verifier}], ?CONSUMER, Token, ""),
  66. {OauthParams, QueryParams} = lists:partition(fun({K, _}) -> lists:prefix("oauth_", K) end, Signed),
  67. Request = {oauth:uri(URL, QueryParams), [oauth:header(OauthParams)]},
  68. {ok, Response} = httpc:request(get, Request, [{autoredirect, false}], []),
  69. case Response of
  70. {HttpResponse, _, _}->
  71. case HttpResponse of
  72. {"HTTP/1.1",200,"OK"}->
  73. Params = oauth:params_decode(Response),
  74. Params;
  75. _ -> not_authorized
  76. end;
  77. _ -> not_authorized
  78. end.
  79. authenticate_url(RequestToken)->
  80. oauth:uri("https://api.twitter.com/oauth/authenticate", [{"oauth_token", RequestToken}]).
  81. authorize_url(RequestToken)->
  82. oauth:uri("https://api.twitter.com/oauth/authorize", [{"oauth_token", RequestToken}]).
  83. show(Props)->
  84. URI = "https://api.twitter.com/1.1/users/show.json",
  85. {ok, Response} = oauth:get(URI, [{"user_id", proplists:get_value("user_id", Props)},
  86. {"include_entities", false}],
  87. ?CONSUMER, oauth:token(Props), oauth:token_secret(Props)),
  88. case Response of
  89. {HttpResponse, _, Body} -> case HttpResponse of
  90. {"HTTP/1.1", 200, "OK"} -> {Res} = ?AVZ_JSON:decode(list_to_binary(Body)), Res;
  91. _-> error end;
  92. _ -> error
  93. end.