aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/user-guide/commands.xml40
-rw-r--r--protocols/twitter/twitter.c53
-rw-r--r--protocols/twitter/twitter_lib.c23
-rw-r--r--protocols/twitter/twitter_lib.h4
4 files changed, 105 insertions, 15 deletions
diff --git a/doc/user-guide/commands.xml b/doc/user-guide/commands.xml
index 982e122e..7cedffc3 100644
--- a/doc/user-guide/commands.xml
+++ b/doc/user-guide/commands.xml
@@ -494,6 +494,24 @@
</description>
</bitlbee-setting>
+ <bitlbee-setting name="auto_reply_timeout" type="integer" scope="account">
+ <default>10800</default>
+
+ <description>
+ <para>
+ For Twitter accounts: If you respond to Tweets IRC-style (like "nickname: reply"), this will automatically be converted to the usual Twitter format ("@screenname reply").
+ </para>
+
+ <para>
+ By default, BitlBee will then also add a reference to that person's most recent Tweet, unless that message is older than the value of this setting in seconds.
+ </para>
+
+ <para>
+ If you want to disable this feature, just set this to 0. Alternatively, if you want to write a message once that is <emphasis>not</emphasis> a reply, use the Twitter reply syntax (@screenname).
+ </para>
+ </description>
+ </bitlbee-setting>
+
<bitlbee-setting name="away" type="string" scope="both">
<description>
<para>
@@ -601,6 +619,28 @@
</description>
</bitlbee-setting>
+ <bitlbee-setting name="commands" type="boolean" scope="account">
+ <default>true</default>
+
+ <description>
+ <para>
+ With this setting enabled, you can use some commands in your Twitter channel/query. The commands are simple and not documented in too much detail:
+ </para>
+
+ <variablelist>
+ <varlistentry><term>undo [&lt;id&gt;]</term><listitem><para>Delete your last Tweet (or one with the given ID)</para></listitem></varlistentry>
+ <varlistentry><term>rt &lt;screenname|id&gt;</term><listitem><para>Retweet someone's last Tweet (or one with the given ID)</para></listitem></varlistentry>
+ <varlistentry><term>follow &lt;screenname&gt;</term><listitem><para>Start following a person</para></listitem></varlistentry>
+ <varlistentry><term>unfollow &lt;screenname&gt;</term><listitem><para>Stop following a person</para></listitem></varlistentry>
+ <varlistentry><term>post &lt;message&gt;</term><listitem><para>Post a tweet</para></listitem></varlistentry>
+ </variablelist>
+
+ <para>
+ Anything that doesn't look like a command will be treated as a tweet. Watch out for typos! :-)
+ </para>
+ </description>
+ </bitlbee-setting>
+
<bitlbee-setting name="debug" type="boolean" scope="global">
<default>false</default>
diff --git a/protocols/twitter/twitter.c b/protocols/twitter/twitter.c
index ca279b8f..a2f2325c 100644
--- a/protocols/twitter/twitter.c
+++ b/protocols/twitter/twitter.c
@@ -185,6 +185,8 @@ static void twitter_init( account_t *acc )
def_oauth = "false";
}
+ s = set_add( &acc->set, "auto_reply_timeout", "10800", set_eval_int, acc );
+
s = set_add( &acc->set, "base_url", def_url, NULL, acc );
s->flags |= ACC_SET_OFFLINE_ONLY;
@@ -426,13 +428,7 @@ static void twitter_handle_command( struct im_connection *ic, char *message )
guint64 id;
if( cmd[1] )
- {
- char *end = NULL;
-
- id = g_ascii_strtoull( cmd[1], &end, 10 );
- if( end == NULL )
- id = 0;
- }
+ id = g_ascii_strtoull( cmd[1], NULL, 10 );
else
id = td->last_status_id;
@@ -443,12 +439,44 @@ static void twitter_handle_command( struct im_connection *ic, char *message )
g_free( cmds );
return;
}
+ else if( g_strcasecmp( cmd[0], "follow" ) == 0 && cmd[1] )
+ {
+ twitter_add_buddy( ic, cmd[1], NULL );
+ g_free( cmds );
+ return;
+ }
+ else if( g_strcasecmp( cmd[0], "unfollow" ) == 0 && cmd[1] )
+ {
+ twitter_remove_buddy( ic, cmd[1], NULL );
+ g_free( cmds );
+ return;
+ }
+ else if( g_strcasecmp( cmd[0], "rt" ) == 0 && cmd[1] )
+ {
+ struct twitter_user_data *tud;
+ bee_user_t *bu;
+ guint64 id;
+
+ if( ( bu = bee_user_by_handle( ic->bee, ic, cmd[1] ) ) &&
+ ( tud = bu->data ) && tud->last_id )
+ id = tud->last_id;
+ else
+ id = g_ascii_strtoull( cmd[1], NULL, 10 );
+
+ td->last_status_id = 0;
+ if( id )
+ twitter_status_retweet( ic, id );
+
+ g_free( cmds );
+ return;
+ }
else if( g_strcasecmp( cmd[0], "post" ) == 0 )
{
message += 5;
}
{
+ guint64 in_reply_to = 0;
char *s, *new = NULL;
bee_user_t *bu;
@@ -465,13 +493,22 @@ static void twitter_handle_command( struct im_connection *ic, char *message )
if( ( bu = bee_user_by_handle( ic->bee, ic, cmd[0] ) ) )
{
+ struct twitter_user_data *tud = bu->data;
+
new = g_strdup_printf( "@%s %s", bu->handle,
message + ( s - cmd[0] ) + 2 );
message = new;
+
+ if( time( NULL ) < tud->last_time +
+ set_getint( &ic->acc->set, "auto_reply_timeout" ) )
+ in_reply_to = tud->last_id;
}
}
- twitter_post_status( ic, message );
+ /* If the user runs undo between this request and its response
+ this would delete the second-last Tweet. Prevent that. */
+ td->last_status_id = 0;
+ twitter_post_status( ic, message, in_reply_to );
g_free( new );
}
g_free( cmds );
diff --git a/protocols/twitter/twitter_lib.c b/protocols/twitter/twitter_lib.c
index 699558b2..f9e808f7 100644
--- a/protocols/twitter/twitter_lib.c
+++ b/protocols/twitter/twitter_lib.c
@@ -783,13 +783,16 @@ static void twitter_http_post(struct http_request *req)
/**
* Function to POST a new status to twitter.
*/
-void twitter_post_status(struct im_connection *ic, char* msg)
+void twitter_post_status(struct im_connection *ic, char *msg, guint64 in_reply_to)
{
- char* args[2];
- args[0] = "status";
- args[1] = msg;
- twitter_http(ic, TWITTER_STATUS_UPDATE_URL, twitter_http_post, ic, 1, args, 2);
-// g_free(args[1]);
+ char* args[4] = {
+ "status", msg,
+ "in_reply_to_status_id",
+ g_strdup_printf("%llu", (unsigned long long) in_reply_to)
+ };
+ twitter_http(ic, TWITTER_STATUS_UPDATE_URL, twitter_http_post, ic, 1,
+ args, in_reply_to ? 4 : 2);
+ g_free(args[3]);
}
@@ -824,3 +827,11 @@ void twitter_status_destroy(struct im_connection *ic, guint64 id)
twitter_http(ic, url, twitter_http_post, ic, 1, NULL, 0);
g_free(url);
}
+
+void twitter_status_retweet(struct im_connection *ic, guint64 id)
+{
+ char *url;
+ url = g_strdup_printf("%s%llu%s", TWITTER_STATUS_RETWEET_URL, (unsigned long long) id, ".xml");
+ twitter_http(ic, url, twitter_http_post, ic, 1, NULL, 0);
+ g_free(url);
+}
diff --git a/protocols/twitter/twitter_lib.h b/protocols/twitter/twitter_lib.h
index 4f3b16c7..24b4a089 100644
--- a/protocols/twitter/twitter_lib.h
+++ b/protocols/twitter/twitter_lib.h
@@ -35,6 +35,7 @@
#define TWITTER_STATUS_UPDATE_URL "/statuses/update.xml"
#define TWITTER_STATUS_SHOW_URL "/statuses/show/"
#define TWITTER_STATUS_DESTROY_URL "/statuses/destroy/"
+#define TWITTER_STATUS_RETWEET_URL "/statuses/retweet/"
/* Timeline URLs */
#define TWITTER_PUBLIC_TIMELINE_URL "/statuses/public_timeline.xml"
@@ -80,10 +81,11 @@ void twitter_get_friends_ids(struct im_connection *ic, gint64 next_cursor);
void twitter_get_home_timeline(struct im_connection *ic, gint64 next_cursor);
void twitter_get_statuses_friends(struct im_connection *ic, gint64 next_cursor);
-void twitter_post_status(struct im_connection *ic, char *msg);
+void twitter_post_status(struct im_connection *ic, char *msg, guint64 in_reply_to);
void twitter_direct_messages_new(struct im_connection *ic, char *who, char *message);
void twitter_friendships_create_destroy(struct im_connection *ic, char *who, int create);
void twitter_status_destroy(struct im_connection *ic, guint64 id);
+void twitter_status_retweet(struct im_connection *ic, guint64 id);
#endif //_TWITTER_LIB_H