-
-
Save OpakAlex/4d7a9a1860586952f3abfaf316ab7fa0 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
import XMPP from 'stanza.io' | |
import Actions from './actions'; | |
import { | |
buildRoomJid, | |
buildJid, | |
buildConfig, | |
buildMessagesHistory, | |
createLogger | |
} from './utils'; | |
const defaultConfig = { | |
sasl: 'plain', | |
resource: 'browser', | |
} | |
class Mongooseim { | |
static instance; | |
constructor({ auth, config, dispatch, onSessionStarted, kind, usersSelector }) { | |
if (!auth || !auth.id || !auth.token) { | |
throw new Error("Invalid auth passed to Provider") | |
} | |
if (!kind) { | |
throw new Error("Kind prop is required") | |
} | |
if (!config.domain || !config.host || !config.ports) { | |
throw new Error("Invalid config prop is passed") | |
} | |
if (this.instance) { | |
return this.instance; | |
} | |
this.domain = config.domain | |
this.muc = config.muc | |
this.auth = auth | |
this.kind = kind | |
this.dispatch = dispatch | |
this.usersSelector = usersSelector | |
this.config = config | |
this.logger = createLogger(config) | |
this.jid = this.buildJid(kind, auth.id) | |
const client = XMPP.createClient({ | |
jid: this.jid, | |
password: auth.token, | |
...buildConfig(config, defaultConfig), | |
}); | |
client.on('session:started', (data) => { | |
this.logger('session:started', data) | |
this.isConnected = true | |
client.sendPresence(); | |
dispatch(Actions.sessionStarted()) | |
if (onSessionStarted) { | |
onSessionStarted(this) | |
} | |
}) | |
client.on('session:error', (error) => { | |
this.logger('session error', error) | |
dispatch(Actions.sessionError(error)) | |
}); | |
const retryAfter = config.retryAfter || 500 | |
client.on('auth:failed', (error) => { | |
this.logger('auth error', error) | |
dispatch(Actions.authFailed(true)) | |
setTimeout(() => { | |
this.logger('try to reconnect') | |
client.connect() | |
}, retryAfter) | |
}); | |
client.on('auth:success', (data) => { | |
this.logger('auth success', data) | |
dispatch(Actions.authSuccess(data)) | |
}); | |
client.on('message:error', (data) => { | |
this.logger('message error', data) | |
}); | |
client.on('message', (data) => { | |
this.logger('message', data) | |
if (data.id) { | |
dispatch(Actions.message({ ...data, stamp: (new Date()).toString()})) | |
} | |
}); | |
client.on('presence', (data) => { | |
this.logger('presence', data) | |
if (data.type === 'subscribe') { | |
client.acceptSubscription(data.from) | |
} | |
if (data.from.bare !== this.jid) { | |
if (data.type === 'available') { | |
dispatch(Actions.presenceAvailable(data.from.bare)) | |
} | |
if (data.type === 'unavailable') { | |
dispatch(Actions.presenceUnavailable(data.from.bare)) | |
} | |
} | |
}); | |
client.on('presence:error', (data) => { | |
this.logger('presence error', data) | |
}); | |
this.client = client | |
this.instance = this; | |
} | |
connect = () => { | |
if (!this.isConnected) { | |
this.client.enableKeepAlive() | |
this.client.connect() | |
} | |
} | |
disconnect = () => { | |
if (this.isConnected) { | |
this.client.disableKeepAlive() | |
this.client.disconnect() | |
this.isConnected = false | |
} | |
} | |
buildRoomJid = (roomName) => buildRoomJid(this.domain, this.muc, roomName) | |
buildActiveRoomJid = () => this.activeRoom ? this.buildRoomJid(this.activeRoom) : null | |
buildJid = (type, id) => buildJid(type, id, this.domain) | |
sendMessage = ({ to, body, type }) => { | |
let recepient = buildJid(to) | |
let kind = type || 'normal' | |
if (this.activeRoom) { | |
recepient = this.buildRoomJid(this.activeRoom) | |
kind = 'groupchat' | |
} | |
this.client.sendMessage({ | |
to: recepient, | |
type: kind, | |
body, | |
}) | |
} | |
joinRoom = (roomName, options = {}) => { | |
const roomJid = this.buildRoomJid(roomName) | |
this.activeRoom = roomName.toString() | |
this.dispatch(Actions.joinRoom(roomName.toString())) | |
this.client.joinRoom(roomJid, this.auth.id, options) | |
this.client.configureRoom(roomJid, { | |
fields: [ | |
{ name: 'FORM_TYPE', value: 'http://jabber.org/protocol/muc#roomconfig' }, | |
{ name: 'muc#roomconfig_persistentroom', value: '1'} | |
] | |
}, (err, data) => { | |
this.logger('configure room', data) | |
this.logger('configure room error', err) | |
}); | |
this.client.searchHistory() | |
} | |
closeRoom = () => { | |
this.activeRoom = null | |
this.dispatch(Actions.closeRoom()) | |
} | |
searchHistory = (options = {}) => { | |
let params = { | |
...options, | |
jid: this.auth.jid, | |
} | |
if (this.activeRoom) { | |
params = { | |
...params, | |
with: this.buildActiveRoomJid(), | |
} | |
} | |
return this.client.searchHistory(params, (err, data) => { | |
if (err) { | |
return this.dispatch(Actions.searchHistoryError(err)) | |
} | |
const messages = buildMessagesHistory(data) | |
this.dispatch(Actions.searchHistory(messages)) | |
}) | |
} | |
subscribe = (type, id) => this.client.subscribe(this.buildJid(type, id)) | |
} | |
export default Mongooseim |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment