First a couple of things you need to know. You'll need an iPhone app to receive push notifications, more about that later on. Furthermore, you'll need a server, which is able to host a Java-based IRC bot.
The bot is leveraging the famouse PircBot library, which unfortunately is based on inheritance:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Bot extends PircBot { | |
private boolean silentMode = false; | |
private Collection<NotificationService> notificationServices; | |
private Collection<String> messages; | |
private Timer messagesTimer; | |
static final int MESSAGE_BATCH_SIZE = 20; | |
static final int MESSAGE_BATCH_DELAY_MS = 60000; | |
@Override | |
protected void onMessage(String argChannel, String argSender, String argLogin, String argHostname, String argMessage) { | |
batchMessages(format(argSender, argMessage)); | |
} | |
@Override | |
protected void onJoin(String argChannel, String argSender, String argLogin, String argHostname) { | |
User[] users = super.getUsers(argChannel); | |
switchSilentMode(users); | |
} | |
@Override | |
protected void onQuit(String argChannel, String argSender, String argLogin, String argHostname) { | |
User[] users = super.getUsers(argChannel); | |
switchSilentMode(users); | |
} | |
private void switchSilentMode(User[] argUsers) { | |
for (int i = 0; i < argUsers.length; i++) { | |
User user = argUsers[i]; | |
if (user.getNick().equals(alterEgoName)) { | |
silentMode = true; | |
return; | |
} | |
} | |
silentMode = false; | |
} | |
private void batchMessages(String argMessage) { | |
if (messages.isEmpty()) { | |
messages.add(argMessage); | |
messagesTimer.schedule(new TimerTask() { | |
public void run() { | |
processMessages(); | |
messagesTimer.purge(); | |
} | |
}, MESSAGE_BATCH_DELAY_MS); | |
} else if (messages.size() < MESSAGE_BATCH_SIZE) { | |
messages.add(argMessage); | |
} else { | |
processMessages(); | |
messagesTimer.purge(); | |
} | |
} | |
private void processMessages() { | |
StringBuilder builder = new StringBuilder(); | |
for (String message : messages) { | |
builder.append(message).append("\n"); | |
} | |
sendToService("message", builder.toString()); | |
messages.clear(); | |
} | |
private void sendToService(String argTitle, String argMessage) { | |
for (NotificationService service : notificationServices) { | |
if (!silentMode) { | |
service.notify(argTitle, argMessage); | |
} | |
} | |
} | |
} |
The usage of PircBot, as you can see above (line 11, 16 and 22), is quite easy. You simply override the methods you want to hook into, and execute your code. That's pretty much all the magic that is to PircBot. In order to limit the notifications pushed to the iPhone, I batch a certain number of messages for a pre-configured time and eventually send them to a NotificationService. I'll come back to the NotificationService in a second, but there's another feature I'd like to point out - silent mode. I don't want to be notified on my iPhone, when I'm actually on IRC myself. So whenver a pre-configured user enters the channel, the Bot will switch to silent mode. As soon as the user leaves the channel, it'll switch back.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class AppNotificationService implements NotificationService { | |
private final String credentials; | |
public static final String USER_CREDENTIALS = "user_credentials"; | |
public static final String NOTIFICATION_LONG_MESSAGE = "notification[long_message]"; | |
public static final String NOTIFICATION_TITLE = "notification[title]"; | |
public static final String MESSAGE_LEVEL = "message_level"; | |
public static final String URL = "https://www.appnotifications.com/account/notifications.xml"; | |
public static final String HTTP_USERAGENT = "http.useragent"; | |
public AppNotificationService(String argCredentials) { | |
credentials = argCredentials; | |
} | |
public boolean notify(String argTitle, String argMessage) { | |
HttpClient client; | |
PostMethod method = null; | |
try { | |
client = setUp(); | |
method = setUp(argTitle, argMessage); | |
int returnCode = client.executeMethod(method); | |
if (returnCode > HttpStatus.SC_OK) { | |
return false; | |
} else { | |
logger.info("Sent notification!"); | |
return true; | |
} | |
} catch (Exception e) { | |
throw new AppNotificationException(); | |
} finally { | |
if (method != null) { | |
method.releaseConnection(); | |
} | |
} | |
} | |
HttpClient setUp() { | |
HttpClient client = new HttpClient(); | |
client.getParams().setParameter(HTTP_USERAGENT, "IRC Bot"); | |
return client; | |
} | |
PostMethod setUp(String argTitle, String argMessage) { | |
PostMethod method = new PostMethod(URL); | |
method.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); | |
method.addParameter(USER_CREDENTIALS, credentials); | |
method.addParameter(NOTIFICATION_LONG_MESSAGE, argMessage); | |
method.addParameter(NOTIFICATION_TITLE, argTitle); | |
method.addParameter(MESSAGE_LEVEL, "2"); | |
return method; | |
} | |
} |
I'm using Commons HttpClient to makes the Post request, since I have some experience with it. In order to use App Notifications, you'll need to setup an account. After the setup, you'll receive a credential String, which must be passed along with the Post request.
The only part missing is the iPhone app, that you need, in order to receive push notifications. The app is not free, but it's quite reasonable. Actually it's a good deal to pay for the app once and not on a request or monhtly bases. However, keep in mind, that the app can only receive push notifications - nothing else. If you that's what you need, this app is for you.
Putting together all parts of the puzzle, you'll get an IRC bot, which connects to the channel you want to be notified about. The bot batches messages and sends them to a service, which in turn pushes them to your iPhone. On your iPhone you have the notification app, which displays the messages from IRC.
The App Notification service is very reliable and super fast. However, there is one downside to the iPhoen app. You cannot switch off the notification sound without also switching off the vibration feedback. The App Notification developer told me, he'll address this issue in a future update.
I also had to play with the batch size and delay, since there are a lot of messages on the channel, I'm interested in and it got quite irratating getting pounded with notifications constantly.
Overall, I do admit, that this combination is quite adventurous, but it works very well. If you'd like to check it out, grab the code from GitHub and let me know what you think.
2 comments:
Or just buy Colloquy, it has PUSH support.
Sure, that's an option as well. I did look into it, but I just found App Notifications a more fexible approach.
Post a Comment