Skip to content

Commit

Permalink
Merge pull request #49 from CharlieHess/strike-three-dms
Browse files Browse the repository at this point in the history
Open DM's, Third Time's the Charm
  • Loading branch information
CharlieHess committed Oct 1, 2015
2 parents 6442d9f + c678e7f commit 19fcda9
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 22 deletions.
76 changes: 55 additions & 21 deletions src/slack-api-rx.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module.exports = class SlackApiRx {
// Returns an {Observable} that signals completion
static openDms(slackApi, users) {
let ret = rx.Observable.fromArray(users)
.flatMap(user => SlackApiRx.getOrOpenDm(slackApi, user))
.flatMap((user) => SlackApiRx.getOrOpenDm(slackApi, user))
.reduce((acc, x) => {
acc[x.id] = x.dm;
return acc;
Expand All @@ -21,33 +21,67 @@ module.exports = class SlackApiRx {
return ret;
}

// Private: Checks for the existence of an open DM channel for the user, and
// opens one if necessary.
// Private: Checks for the existence of an open DM channel for the user,
// opens one if necessary, then waits for the `im_open` event and retrieves
// the DM channel.
//
// slackApi - An instance of the Slack client
// user - The user we are trying to DM with
//
// Returns an {Observable} of the opened DM channel
// Returns an {Observable} representing the opened channel. This will be an
// object with two keys: `id` and `dm`. DM will be null if the API call
// failed for some reason (e.g., an invalid user).
static getOrOpenDm(slackApi, user) {
let readySubj = new rx.AsyncSubject();
console.log(`Getting DM channel for ${user.name}`);
let dm = slackApi.getDMByName(user.name);
console.log(`Opening DM channel for ${user.name}`);

if (!dm || !dm.is_open) {
slackApi.openDM(user.id, (result) => {
if (result.ok) {
dm = slackApi.getDMByName(user.name);
readySubj.onNext({id: user.id, dm: dm});
readySubj.onCompleted();
} else {
console.log(`Unable to open DM for ${user.name}: ${result.error}`);
readySubj.onCompleted();
}
});
} else {
readySubj.onNext({id: user.id, dm: dm});
readySubj.onCompleted();
// Bot players don't need DM channels; we only talk to humans
if ((dm && dm.is_open) || user.isBot) {
return rx.Observable.return({id: user.id, dm: dm});
}
return readySubj;

console.log(`No open channel found, opening one using ${user.id}`);

return SlackApiRx.openDm(slackApi, user)
.flatMap(() => SlackApiRx.waitForDmToOpen(slackApi, user))
.flatMap((dm) => rx.Observable.return({id: user.id, dm: dm}))
.catch(rx.Observable.return({id: user.id, dm: null}));
}

// Private: Maps the `im.open` API call into an {Observable}.
//
// Returns an {Observable} that signals completion, or an error if the API
// call fails
static openDm(slackApi, user) {
let calledOpen = new rx.AsyncSubject();

slackApi.openDM(user.id, (result) => {
if (result.ok) {
calledOpen.onNext(user.name);
calledOpen.onCompleted();
} else {
console.log(`Unable to open DM for ${user.name}: ${result.error}`);
calledOpen.onError(new Error(result.error));
}
})

return calledOpen;
}

// Private: The `im.open` callback is still not late enough; we need to wait
// for the client's underlying list of DM's to be updated. When that occurs
// we can retrieve the DM.
//
// Returns a replayable {Observable} containing the opened DM channel
static waitForDmToOpen(slackApi, user) {
let ret = rx.DOM.fromEvent(slackApi, 'raw_message')
.where((m) => m.type === 'im_open' && m.user === user.id)
.take(1)
.flatMap(() => rx.Observable.timer(100).map(() =>
slackApi.getDMByName(user.name)))
.publishLast();

ret.connect();
return ret;
}
};
10 changes: 9 additions & 1 deletion src/texas-holdem.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const _ = require('underscore-plus');

const Deck = require('./deck');
const PotManager = require('./pot-manager');
const SlackApiRx = require('./slack-api-rx');
const PlayerOrder = require('./player-order');
const PlayerStatus = require('./player-status');
const ImageHelpers = require('./image-helpers');
Expand Down Expand Up @@ -486,7 +487,14 @@ class TexasHoldem {

if (!player.isBot) {
let dm = this.playerDms[player.id];
dm.send(`Your hand is: ${this.playerHands[player.id]}`);
if (!dm) {
SlackApiRx.getOrOpenDm.subscribe(({dm}) => {
this.playerDms[player.id] = dm;
dm.send(`Your hand is: ${this.playerHands[player.id]}`);
});
} else {
dm.send(`Your hand is: ${this.playerHands[player.id]}`);
}
} else {
player.holeCards = this.playerHands[player.id];
}
Expand Down

0 comments on commit 19fcda9

Please sign in to comment.