comparison weechat/perl/pushover.pl @ 259:726728f13152

More Weechat plugins and config.
author Ludovic Chabant <ludovic@chabant.com>
date Wed, 21 Jan 2015 16:45:26 -0800
parents
children 0a7142b8ab95
comparison
equal deleted inserted replaced
258:abb94e9f28d2 259:726728f13152
1 #
2 # Copyright (C) 2013-2014 stfn <stfnmd@gmail.com>
3 # https://github.com/stfnm/weechat-scripts
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #
18
19 use strict;
20 use warnings;
21
22 my %SCRIPT = (
23 name => 'pushover',
24 author => 'stfn <stfnmd@gmail.com>',
25 version => '1.2',
26 license => 'GPL3',
27 desc => 'Send push notifications to your mobile devices using Pushover, NMA or Pushbullet',
28 opt => 'plugins.var.perl',
29 );
30 my %OPTIONS_DEFAULT = (
31 'enabled' => ['on', "Turn script on or off"],
32 'service' => ['pushover', 'Notification service to use. Multiple services may be supplied as comma separated list. (supported services: pushover, nma, pushbullet)'],
33 'token' => ['ajEX9RWhxs6NgeXFJxSK2jmpY54C9S', 'pushover API token/key (You may feel free to use your own token, so you get your own monthly quota of messages without being affected by other users. See also: https://pushover.net/faq#overview-distribution )'],
34 'user' => ['', "pushover user key"],
35 'nma_apikey' => ['', "nma API key"],
36 'pb_apikey' => ['', "Pushbullet API key"],
37 'pb_device_iden' => ['', "Device Iden of pushbullet device"],
38 'sound' => ['', "Sound (empty for default)"],
39 'priority' => ['', "priority (empty for default)"],
40 'show_highlights' => ['on', 'Notify on highlights'],
41 'show_priv_msg' => ['on', 'Notify on private messages'],
42 'redact_priv_msg' => ['off', 'When receiving private message notifications, hide the actual message text'],
43 'only_if_away' => ['off', 'Notify only if away status is active'],
44 'only_if_inactive' => ['off', 'Notify only if buffer is not the active (current) buffer'],
45 'blacklist' => ['', 'Comma separated list of buffers (full name) to blacklist for notifications (wildcard "*" is allowed, name beginning with "!" is excluded)'],
46 'verbose' => ['1', 'Verbosity level (0 = silently ignore any errors, 1 = display brief error, 2 = display full server response)'],
47 );
48 my %OPTIONS = ();
49 my $TIMEOUT = 30 * 1000;
50
51 my $DEBUG = 0;
52
53 # Register script and initialize config
54 weechat::register($SCRIPT{"name"}, $SCRIPT{"author"}, $SCRIPT{"version"}, $SCRIPT{"license"}, $SCRIPT{"desc"}, "", "");
55 init_config();
56
57 # Setup hooks
58 weechat::hook_print("", "notify_message,notify_private,notify_highlight", "", 1, "print_cb", "");
59 weechat::hook_command($SCRIPT{"name"}, "send custom push notification",
60 "<text>",
61 "text: notification text to send",
62 "", "pushover_cb", "");
63
64 #
65 # Handle config stuff
66 #
67 sub init_config
68 {
69 weechat::hook_config("$SCRIPT{'opt'}.$SCRIPT{'name'}.*", "config_cb", "");
70 my $version = weechat::info_get("version_number", "") || 0;
71 foreach my $option (keys %OPTIONS_DEFAULT) {
72 if (!weechat::config_is_set_plugin($option)) {
73 weechat::config_set_plugin($option, $OPTIONS_DEFAULT{$option}[0]);
74 $OPTIONS{$option} = $OPTIONS_DEFAULT{$option}[0];
75 } else {
76 $OPTIONS{$option} = weechat::config_get_plugin($option);
77 }
78 if ($version >= 0x00030500) {
79 weechat::config_set_desc_plugin($option, $OPTIONS_DEFAULT{$option}[1]." (default: \"".$OPTIONS_DEFAULT{$option}[0]."\")");
80 }
81 }
82 }
83 sub config_cb
84 {
85 my ($pointer, $name, $value) = @_;
86 $name = substr($name, length("$SCRIPT{opt}.$SCRIPT{name}."), length($name));
87 $OPTIONS{$name} = $value;
88 return weechat::WEECHAT_RC_OK;
89 }
90
91 #
92 # Case insensitive search for element in comma separated list
93 #
94 sub grep_list($$)
95 {
96 my ($str, $list) = @_;
97 my @array = split(/,/, $list);
98 return grep(/^\Q$str\E$/i, @array) ? 1 : 0;
99 }
100
101 #
102 # URL escape (percent encoding)
103 #
104 sub url_escape($)
105 {
106 my $toencode = $_[0];
107 return undef unless (defined($toencode));
108 utf8::encode($toencode) if (utf8::is_utf8($toencode));
109 $toencode =~ s/([^a-zA-Z0-9_.~-])/uc sprintf("%%%02x",ord($1))/eg;
110 return $toencode;
111 }
112
113 #
114 # Catch printed messages
115 #
116 sub print_cb
117 {
118 my ($data, $buffer, $date, $tags, $displayed, $highlight, $prefix, $message) = @_;
119
120 my $buffer_type = weechat::buffer_get_string($buffer, "localvar_type");
121 my $buffer_full_name = weechat::buffer_get_string($buffer, "full_name");
122 my $away_msg = weechat::buffer_get_string($buffer, "localvar_away");
123 my $away = ($away_msg && length($away_msg) > 0) ? 1 : 0;
124
125 if ($OPTIONS{enabled} ne "on" ||
126 $displayed == 0 ||
127 ($OPTIONS{only_if_away} eq "on" && $away == 0) ||
128 ($OPTIONS{only_if_inactive} eq "on" && $buffer eq weechat::current_buffer()) ||
129 weechat::buffer_match_list($buffer, $OPTIONS{blacklist})) {
130 return weechat::WEECHAT_RC_OK;
131 }
132
133 my $msg = "[$buffer_full_name] <$prefix> ";
134
135 if ($buffer_type eq "private" && $OPTIONS{redact_priv_msg} eq "on") {
136 $msg .= "...";
137 } else {
138 $msg .= "$message";
139 }
140
141 # Notify!
142 if ($OPTIONS{show_highlights} eq "on" && $highlight == 1) {
143 # Message with highlight
144 notify($msg);
145 } elsif ($OPTIONS{show_priv_msg} eq "on" && $buffer_type eq "private") {
146 # Private message
147 notify($msg);
148 }
149
150 return weechat::WEECHAT_RC_OK;
151 }
152
153 #
154 # /pushover
155 #
156 sub pushover_cb
157 {
158 my ($data, $buffer, $args) = @_;
159
160 if (length($args) > 0) {
161 notify($args);
162 }
163
164 return weechat::WEECHAT_RC_OK;
165 }
166
167 #
168 # Catch API responses
169 #
170 sub url_cb
171 {
172 my ($data, $command, $return_code, $out, $err) = @_;
173 my $msg = "[$SCRIPT{name}] Error: ";
174
175 # Check verbosity level
176 if ($OPTIONS{verbose} == 0) {
177 return weechat::WEECHAT_RC_OK; # Don't display anything
178 } elsif ($OPTIONS{verbose} == 1) {
179 $msg .= "API call failed. (Most likely the service is having trouble.)";
180
181 } elsif ($OPTIONS{verbose} == 2) {
182 $msg .= "@_";
183 }
184
185 # Check server response and display error message if NOT successful
186 if ($command =~ /pushover/ && $return_code == 0 && !($out =~ /\"status\":1/)) {
187 weechat::print("", $msg);
188 } elsif ($command =~ /notifymyandroid/ && $return_code == 0 && !($out =~ /success code=\"200\"/)) {
189 weechat::print("", $msg);
190 } elsif ($command =~ /pushbullet/ && $return_code == 0 && !($out =~ /\"iden\"/)) {
191 weechat::print("", $msg);
192 }
193
194 return weechat::WEECHAT_RC_OK;
195 }
196
197 #
198 # Notify wrapper (decides which service to use)
199 #
200 sub notify($)
201 {
202 my $message = $_[0];
203
204 # Notify services
205 if (grep_list("pushover", $OPTIONS{service})) {
206 notify_pushover($OPTIONS{token}, $OPTIONS{user}, $message, "weechat", $OPTIONS{priority}, $OPTIONS{sound});
207 }
208 if (grep_list("nma", $OPTIONS{service})) {
209 notify_nma($OPTIONS{nma_apikey}, "weechat", "$SCRIPT{name}.pl", $message, $OPTIONS{priority});
210 }
211 if (grep_list("pushbullet", $OPTIONS{service})) {
212 notify_pushbullet($OPTIONS{pb_apikey}, $OPTIONS{pb_device_iden}, "weechat", $message);
213 }
214 }
215
216 #
217 # https://pushover.net/api
218 #
219 sub notify_pushover($$$$$$)
220 {
221 my ($token, $user, $message, $title, $priority, $sound) = @_;
222
223 # Required API arguments
224 my @post = (
225 "token=" . url_escape($token),
226 "user=" . url_escape($user),
227 "message=" . url_escape($message),
228 );
229
230 # Optional API arguments
231 push(@post, "title=" . url_escape($title)) if ($title && length($title) > 0);
232 push(@post, "priority=" . url_escape($priority)) if ($priority && length($priority) > 0);
233 push(@post, "sound=" . url_escape($sound)) if ($sound && length($sound) > 0);
234
235 # Send HTTP POST
236 my $hash = { "post" => 1, "postfields" => join(";", @post) };
237 if ($DEBUG) {
238 weechat::print("", "[$SCRIPT{name}] Debug: msg -> `$message' HTTP POST -> @post");
239 } else {
240 weechat::hook_process_hashtable("url:https://api.pushover.net/1/messages.json", $hash, $TIMEOUT, "url_cb", "");
241 }
242
243 return weechat::WEECHAT_RC_OK;
244 }
245
246 #
247 # https://www.notifymyandroid.com/api.jsp
248 #
249 sub notify_nma($$$$$)
250 {
251 my ($apikey, $application, $event, $description, $priority) = @_;
252
253 # Required API arguments
254 my @post = (
255 "apikey=" . url_escape($apikey),
256 "application=" . url_escape($application),
257 "event=" . url_escape($event),
258 "description=" . url_escape($description),
259 );
260
261 # Optional API arguments
262 push(@post, "priority=" . url_escape($priority)) if ($priority && length($priority) > 0);
263
264 # Send HTTP POST
265 my $hash = { "post" => 1, "postfields" => join("&", @post) };
266 if ($DEBUG) {
267 weechat::print("", "[$SCRIPT{name}] Debug: msg -> `$description' HTTP POST -> @post");
268 } else {
269 weechat::hook_process_hashtable("url:https://www.notifymyandroid.com/publicapi/notify", $hash, $TIMEOUT, "url_cb", "");
270 }
271
272 return weechat::WEECHAT_RC_OK;
273 }
274
275 #
276 # https://docs.pushbullet.com/v2/pushes/
277 #
278 sub notify_pushbullet($$$$)
279 {
280 my ($apikey, $device_iden, $title, $body) = @_;
281
282 # Required API arguments
283 my $apiurl = "https://$apikey\@api.pushbullet.com/v2/pushes";
284 my @post = (
285 "type=note",
286 );
287
288 # Optional API arguments
289 push(@post, "device_iden=" . url_escape($device_iden)) if ($device_iden && length($device_iden) > 0);
290 push(@post, "title=" . url_escape($title)) if ($title && length($title) > 0);
291 push(@post, "body=" . url_escape($body)) if ($body && length($body) > 0);
292
293 # Send HTTP POST
294 my $hash = { "post" => 1, "postfields" => join("&", @post) };
295 if ($DEBUG) {
296 weechat::print("", "$apiurl [$SCRIPT{name}] Debug: msg -> `$body' HTTP POST -> @post");
297 } else {
298 weechat::hook_process_hashtable("url:$apiurl", $hash, $TIMEOUT, "url_cb", "");
299 }
300
301 return weechat::WEECHAT_RC_OK;
302 }