{"action":"created","comment":{"url":"https://api.github.com/repos/semifor/twirc/pulls/comments/23860322","id":23860322,"diff_hunk":"@@ -1150,28 +1150,76 @@ event cmd_whois => sub {\n     }\n };\n \n-=item notify I<on|off> I<id ...>\n+=item notify I<on|off> I<screen_name ...>\n \n-Turns device notifications on or off for the list of Twitter IDs.\n+Turns mobile device notifications on or off for the list of I<screen_name>s.\n \n =cut\n \n event cmd_notify => sub {\n-    my ($self, $channel, $argstr) = @_[OBJECT, ARG0, ARG1];\n+    my $self = $_[OBJECT];\n+    $self->_update_fship('device', @_[ARG0, ARG1]);\n+};\n+\n+=item retweets I<on|off> I<screen_name ...>\n+\n+Turns retweet display on your timeline on or off for the list of\n+I<screen_name>s.\n+\n+=cut\n+\n+event cmd_retweets => sub {\n+    my $self = $_[OBJECT];\n+    $self->_update_fship('retweets', @_[ARG0, ARG1]);\n+};\n+\n+# Call update_friendships\n+# All settings updated at once so existing must be preserved\n+sub _update_fship {\n+    my ($self, $command, $channel, $argstr) = @_;\n \n     my @nicks = split /\\s+/, $argstr;\n     my $onoff = shift @nicks;\n \n-    unless ( $onoff && $onoff =~ /^on|off$/ ) {\n-        $self->bot_says($channel, \"Usage: notify on|off nick[ nick [...]]\");\n+    unless ( $onoff && $onoff =~ /^on$|^off$/ ) {\n+        $self->bot_says($channel, \"Usage: $command on|off nick[ nick [...]]\");\n         return;\n     }\n \n-    my $method = $onoff eq 'on' ? 'enable_notifications' : 'disable_notifications';\n+    my $setting = $onoff eq 'on' ? 1 : 0;\n     for my $nick ( @nicks ) {\n-        $self->twitter($method => { id => $nick });\n+        # Fetch existing values\n+        my %prev_vals = $self->_fetch_prev_setts($nick);\n+\n+        # Skip unnecessary updates\n+        if ($prev_vals{$command} == $setting) {\n+            $self->bot_says($channel, \"No need to update $nick\");\n+            next;\n+        }\n+\n+        # Update\n+        $self->twitter(update_friendship =>\n+                       { screen_name => $nick,\n+                         # previous values as default\n+                         device   => \"$prev_vals{device}\",\n+                         retweets => \"$prev_vals{retweets}\",\n+                         # override with new value\n+                         $command => $setting\n+                       });\n     }\n-};\n+}\n+\n+# Fetch previous notify / retweet settings\n+sub _fetch_prev_setts {\n+    my ($self, $nick) = @_;\n+    # Dig through twitter info\n+    my $twit_data = $self->twitter(show_friendship =>\n+                                  { target_screen_name => $nick })\n+                        ->{relationship}{source};\n+    # Pull out existing settings\n+    return device   => $twit_data->{notifications_enabled},","path":"lib/POE/Component/Server/Twirc.pm","position":97,"original_position":97,"commit_id":"27afb9c802bf5301e6556b47e51c107ac47b704b","original_commit_id":"27afb9c802bf5301e6556b47e51c107ac47b704b","user":{"login":"semifor","id":37519,"avatar_url":"https://avatars.githubusercontent.com/u/37519?v=3","gravatar_id":"","url":"https://api.github.com/users/semifor","html_url":"https://github.com/semifor","followers_url":"https://api.github.com/users/semifor/followers","following_url":"https://api.github.com/users/semifor/following{/other_user}","gists_url":"https://api.github.com/users/semifor/gists{/gist_id}","starred_url":"https://api.github.com/users/semifor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/semifor/subscriptions","organizations_url":"https://api.github.com/users/semifor/orgs","repos_url":"https://api.github.com/users/semifor/repos","events_url":"https://api.github.com/users/semifor/events{/privacy}","received_events_url":"https://api.github.com/users/semifor/received_events","type":"User","site_admin":false},"body":"Because of perl's list context, my personal preference is to return hashrefs instead of flattened hashes. There's less risk of the caller doing the wrong thing, accidentally. It's not an efficiency concern. I'm happy to accept this as is. It's good, working code. But I'm likely to change it if/when I run across it again. ;-)","created_at":"2015-01-30T18:16:50Z","updated_at":"2015-01-30T18:16:50Z","html_url":"https://github.com/semifor/twirc/pull/11#discussion_r23860322","pull_request_url":"https://api.github.com/repos/semifor/twirc/pulls/11","_links":{"self":{"href":"https://api.github.com/repos/semifor/twirc/pulls/comments/23860322"},"html":{"href":"https://github.com/semifor/twirc/pull/11#discussion_r23860322"},"pull_request":{"href":"https://api.github.com/repos/semifor/twirc/pulls/11"}}},"pull_request":{"url":"https://api.github.com/repos/semifor/twirc/pulls/11","id":28338233,"html_url":"https://github.com/semifor/twirc/pull/11","diff_url":"https://github.com/semifor/twirc/pull/11.diff","patch_url":"https://github.com/semifor/twirc/pull/11.patch","issue_url":"https://api.github.com/repos/semifor/twirc/issues/11","number":11,"state":"open","locked":false,"title":"Twitter enable/disable_notifications calls are deprecated","user":{"login":"pwr22","id":805424,"avatar_url":"https://avatars.githubusercontent.com/u/805424?v=3","gravatar_id":"","url":"https://api.github.com/users/pwr22","html_url":"https://github.com/pwr22","followers_url":"https://api.github.com/users/pwr22/followers","following_url":"https://api.github.com/users/pwr22/following{/other_user}","gists_url":"https://api.github.com/users/pwr22/gists{/gist_id}","starred_url":"https://api.github.com/users/pwr22/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pwr22/subscriptions","organizations_url":"https://api.github.com/users/pwr22/orgs","repos_url":"https://api.github.com/users/pwr22/repos","events_url":"https://api.github.com/users/pwr22/events{/privacy}","received_events_url":"https://api.github.com/users/pwr22/received_events","type":"User","site_admin":false},"body":"Switches notify to use 1.1 calls, adds the ability to set retweet preferences, doesn't update unless necessary and fixes an old bug","created_at":"2015-01-30T04:58:24Z","updated_at":"2015-01-30T18:16:50Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2eda3f6ba28dae3212c65d050c8eb1214e8c9095","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/semifor/twirc/pulls/11/commits","review_comments_url":"https://api.github.com/repos/semifor/twirc/pulls/11/comments","review_comment_url":"https://api.github.com/repos/semifor/twirc/pulls/comments/{number}","comments_url":"https://api.github.com/repos/semifor/twirc/issues/11/comments","statuses_url":"https://api.github.com/repos/semifor/twirc/statuses/27afb9c802bf5301e6556b47e51c107ac47b704b","head":{"label":"pwr22:notify-deprecated","ref":"notify-deprecated","sha":"27afb9c802bf5301e6556b47e51c107ac47b704b","user":{"login":"pwr22","id":805424,"avatar_url":"https://avatars.githubusercontent.com/u/805424?v=3","gravatar_id":"","url":"https://api.github.com/users/pwr22","html_url":"https://github.com/pwr22","followers_url":"https://api.github.com/users/pwr22/followers","following_url":"https://api.github.com/users/pwr22/following{/other_user}","gists_url":"https://api.github.com/users/pwr22/gists{/gist_id}","starred_url":"https://api.github.com/users/pwr22/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pwr22/subscriptions","organizations_url":"https://api.github.com/users/pwr22/orgs","repos_url":"https://api.github.com/users/pwr22/repos","events_url":"https://api.github.com/users/pwr22/events{/privacy}","received_events_url":"https://api.github.com/users/pwr22/received_events","type":"User","site_admin":false},"repo":{"id":29943072,"name":"twirc","full_name":"pwr22/twirc","owner":{"login":"pwr22","id":805424,"avatar_url":"https://avatars.githubusercontent.com/u/805424?v=3","gravatar_id":"","url":"https://api.github.com/users/pwr22","html_url":"https://github.com/pwr22","followers_url":"https://api.github.com/users/pwr22/followers","following_url":"https://api.github.com/users/pwr22/following{/other_user}","gists_url":"https://api.github.com/users/pwr22/gists{/gist_id}","starred_url":"https://api.github.com/users/pwr22/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pwr22/subscriptions","organizations_url":"https://api.github.com/users/pwr22/orgs","repos_url":"https://api.github.com/users/pwr22/repos","events_url":"https://api.github.com/users/pwr22/events{/privacy}","received_events_url":"https://api.github.com/users/pwr22/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/pwr22/twirc","description":"Twitter / IRC gateway in perl","fork":true,"url":"https://api.github.com/repos/pwr22/twirc","forks_url":"https://api.github.com/repos/pwr22/twirc/forks","keys_url":"https://api.github.com/repos/pwr22/twirc/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pwr22/twirc/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pwr22/twirc/teams","hooks_url":"https://api.github.com/repos/pwr22/twirc/hooks","issue_events_url":"https://api.github.com/repos/pwr22/twirc/issues/events{/number}","events_url":"https://api.github.com/repos/pwr22/twirc/events","assignees_url":"https://api.github.com/repos/pwr22/twirc/assignees{/user}","branches_url":"https://api.github.com/repos/pwr22/twirc/branches{/branch}","tags_url":"https://api.github.com/repos/pwr22/twirc/tags","blobs_url":"https://api.github.com/repos/pwr22/twirc/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pwr22/twirc/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pwr22/twirc/git/refs{/sha}","trees_url":"https://api.github.com/repos/pwr22/twirc/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pwr22/twirc/statuses/{sha}","languages_url":"https://api.github.com/repos/pwr22/twirc/languages","stargazers_url":"https://api.github.com/repos/pwr22/twirc/stargazers","contributors_url":"https://api.github.com/repos/pwr22/twirc/contributors","subscribers_url":"https://api.github.com/repos/pwr22/twirc/subscribers","subscription_url":"https://api.github.com/repos/pwr22/twirc/subscription","commits_url":"https://api.github.com/repos/pwr22/twirc/commits{/sha}","git_commits_url":"https://api.github.com/repos/pwr22/twirc/git/commits{/sha}","comments_url":"https://api.github.com/repos/pwr22/twirc/comments{/number}","issue_comment_url":"https://api.github.com/repos/pwr22/twirc/issues/comments/{number}","contents_url":"https://api.github.com/repos/pwr22/twirc/contents/{+path}","compare_url":"https://api.github.com/repos/pwr22/twirc/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pwr22/twirc/merges","archive_url":"https://api.github.com/repos/pwr22/twirc/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pwr22/twirc/downloads","issues_url":"https://api.github.com/repos/pwr22/twirc/issues{/number}","pulls_url":"https://api.github.com/repos/pwr22/twirc/pulls{/number}","milestones_url":"https://api.github.com/repos/pwr22/twirc/milestones{/number}","notifications_url":"https://api.github.com/repos/pwr22/twirc/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pwr22/twirc/labels{/name}","releases_url":"https://api.github.com/repos/pwr22/twirc/releases{/id}","created_at":"2015-01-28T00:47:21Z","updated_at":"2015-01-30T00:00:44Z","pushed_at":"2015-01-30T04:55:44Z","git_url":"git://github.com/pwr22/twirc.git","ssh_url":"git@github.com:pwr22/twirc.git","clone_url":"https://github.com/pwr22/twirc.git","svn_url":"https://github.com/pwr22/twirc","homepage":"http://search.cpan.org/dist/POE-Component-Server-Twirc/","size":331,"stargazers_count":0,"watchers_count":0,"language":"Prolog","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"semifor:master","ref":"master","sha":"685deb304ed32e4ecabe08c597900afbaf241bf4","user":{"login":"semifor","id":37519,"avatar_url":"https://avatars.githubusercontent.com/u/37519?v=3","gravatar_id":"","url":"https://api.github.com/users/semifor","html_url":"https://github.com/semifor","followers_url":"https://api.github.com/users/semifor/followers","following_url":"https://api.github.com/users/semifor/following{/other_user}","gists_url":"https://api.github.com/users/semifor/gists{/gist_id}","starred_url":"https://api.github.com/users/semifor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/semifor/subscriptions","organizations_url":"https://api.github.com/users/semifor/orgs","repos_url":"https://api.github.com/users/semifor/repos","events_url":"https://api.github.com/users/semifor/events{/privacy}","received_events_url":"https://api.github.com/users/semifor/received_events","type":"User","site_admin":false},"repo":{"id":86232,"name":"twirc","full_name":"semifor/twirc","owner":{"login":"semifor","id":37519,"avatar_url":"https://avatars.githubusercontent.com/u/37519?v=3","gravatar_id":"","url":"https://api.github.com/users/semifor","html_url":"https://github.com/semifor","followers_url":"https://api.github.com/users/semifor/followers","following_url":"https://api.github.com/users/semifor/following{/other_user}","gists_url":"https://api.github.com/users/semifor/gists{/gist_id}","starred_url":"https://api.github.com/users/semifor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/semifor/subscriptions","organizations_url":"https://api.github.com/users/semifor/orgs","repos_url":"https://api.github.com/users/semifor/repos","events_url":"https://api.github.com/users/semifor/events{/privacy}","received_events_url":"https://api.github.com/users/semifor/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/semifor/twirc","description":"Twitter / IRC gateway in perl","fork":false,"url":"https://api.github.com/repos/semifor/twirc","forks_url":"https://api.github.com/repos/semifor/twirc/forks","keys_url":"https://api.github.com/repos/semifor/twirc/keys{/key_id}","collaborators_url":"https://api.github.com/repos/semifor/twirc/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/semifor/twirc/teams","hooks_url":"https://api.github.com/repos/semifor/twirc/hooks","issue_events_url":"https://api.github.com/repos/semifor/twirc/issues/events{/number}","events_url":"https://api.github.com/repos/semifor/twirc/events","assignees_url":"https://api.github.com/repos/semifor/twirc/assignees{/user}","branches_url":"https://api.github.com/repos/semifor/twirc/branches{/branch}","tags_url":"https://api.github.com/repos/semifor/twirc/tags","blobs_url":"https://api.github.com/repos/semifor/twirc/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/semifor/twirc/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/semifor/twirc/git/refs{/sha}","trees_url":"https://api.github.com/repos/semifor/twirc/git/trees{/sha}","statuses_url":"https://api.github.com/repos/semifor/twirc/statuses/{sha}","languages_url":"https://api.github.com/repos/semifor/twirc/languages","stargazers_url":"https://api.github.com/repos/semifor/twirc/stargazers","contributors_url":"https://api.github.com/repos/semifor/twirc/contributors","subscribers_url":"https://api.github.com/repos/semifor/twirc/subscribers","subscription_url":"https://api.github.com/repos/semifor/twirc/subscription","commits_url":"https://api.github.com/repos/semifor/twirc/commits{/sha}","git_commits_url":"https://api.github.com/repos/semifor/twirc/git/commits{/sha}","comments_url":"https://api.github.com/repos/semifor/twirc/comments{/number}","issue_comment_url":"https://api.github.com/repos/semifor/twirc/issues/comments/{number}","contents_url":"https://api.github.com/repos/semifor/twirc/contents/{+path}","compare_url":"https://api.github.com/repos/semifor/twirc/compare/{base}...{head}","merges_url":"https://api.github.com/repos/semifor/twirc/merges","archive_url":"https://api.github.com/repos/semifor/twirc/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/semifor/twirc/downloads","issues_url":"https://api.github.com/repos/semifor/twirc/issues{/number}","pulls_url":"https://api.github.com/repos/semifor/twirc/pulls{/number}","milestones_url":"https://api.github.com/repos/semifor/twirc/milestones{/number}","notifications_url":"https://api.github.com/repos/semifor/twirc/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/semifor/twirc/labels{/name}","releases_url":"https://api.github.com/repos/semifor/twirc/releases{/id}","created_at":"2008-12-06T22:20:46Z","updated_at":"2015-01-30T02:48:34Z","pushed_at":"2015-01-30T02:48:34Z","git_url":"git://github.com/semifor/twirc.git","ssh_url":"git@github.com:semifor/twirc.git","clone_url":"https://github.com/semifor/twirc.git","svn_url":"https://github.com/semifor/twirc","homepage":"http://search.cpan.org/dist/POE-Component-Server-Twirc/","size":435,"stargazers_count":27,"watchers_count":27,"language":"Prolog","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":10,"mirror_url":null,"open_issues_count":4,"forks":10,"open_issues":4,"watchers":27,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/semifor/twirc/pulls/11"},"html":{"href":"https://github.com/semifor/twirc/pull/11"},"issue":{"href":"https://api.github.com/repos/semifor/twirc/issues/11"},"comments":{"href":"https://api.github.com/repos/semifor/twirc/issues/11/comments"},"review_comments":{"href":"https://api.github.com/repos/semifor/twirc/pulls/11/comments"},"review_comment":{"href":"https://api.github.com/repos/semifor/twirc/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/semifor/twirc/pulls/11/commits"},"statuses":{"href":"https://api.github.com/repos/semifor/twirc/statuses/27afb9c802bf5301e6556b47e51c107ac47b704b"}}}}