Skip to content

Instantly share code, notes, and snippets.

@dnet
Last active December 19, 2015 18:49
Show Gist options
  • Save dnet/6001554 to your computer and use it in GitHub Desktop.
Save dnet/6001554 to your computer and use it in GitHub Desktop.
Twitter module for Erlang IRC bot
% depends: https://github.com/dnet/erlang-oauth
% depends: https://github.com/talentdeficit/jsx
-module(tweet).
-export([ircmain/1, ircproc/1, reload/2]).
-define(CONSUMER_KEY, "...").
-define(CONSUMER_SECRET, "...").
-define(ACCESS_TOKEN, "...").
-define(TOKEN_SECRET, "...").
-define(CONSUMER, {?CONSUMER_KEY, ?CONSUMER_SECRET, hmac_sha1}).
-define(URL, "https://api.twitter.com/1.1/statuses/update.json").
-define(ERROR_MSG, "and by the way, your message 'Niggerek vagytok mind' "
"never reach mars i'm sorry \x0310http://bash.hu/1271").
-define(SUCCESS_MSG, "\x16(π)\x16 Grand succès !").
tweet(Status) ->
decode_response(oauth:post(?URL, [{"status", Status}],
?CONSUMER, ?ACCESS_TOKEN, ?TOKEN_SECRET)).
decode_response({ok, Details}) -> decode_details(Details);
decode_response(Info) ->
io:format("Tweet error: ~p~n", [Info]),
<<?ERROR_MSG/utf8>>.
decode_details({{_, 200, _}, _, _}) -> <<?SUCCESS_MSG/utf8>>;
decode_details({_, Headers, Payload}) ->
case is_json(Headers) of
true -> decode_json(Payload);
_ -> Payload
end.
is_json(Headers) ->
ContentType = proplists:get_value("content-type", Headers),
string:str(ContentType, "json") =/= 0.
decode_json(Payload) ->
Errors = maps:get(<<"errors">>, jsx:decode(list_to_binary(Payload), [return_maps])),
string:join(lists:map(fun error_to_str/1, Errors), ", ").
error_to_str(Error) ->
binary_to_list(maps:get(<<"message">>, Error)).
recognize_cmd(Input) ->
{match, [Status]} = re:run(Input,
"-tweet ([^\r]+)",
[{capture, all_but_first, list}, caseless]),
tweet(Status).
ircmain(Contact) ->
ssl:start(),
Pid = spawn(?MODULE, ircproc, [Contact]),
Contact ! {subscribe, Pid},
Pid.
reload(Contact, Pid) ->
Pid ! reloaded,
ircproc(Contact).
ircproc(Contact) ->
receive
quit -> quit;
{incoming, Data} ->
S = binary_to_list(Data),
case string:str(S, "-tweet") of
0 -> nop;
_ -> spawn(fun() ->
Contact ! {announce, recognize_cmd(S)} end)
end,
ircproc(Contact);
{ident, Pid} ->
Pid ! {ident, "tweet (using consumer key \"" ?CONSUMER_KEY "\")"},
ircproc(Contact);
{reload, Pid} ->
?MODULE:reload(Contact, Pid);
_ -> ircproc(Contact)
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment