This repository has been archived by the owner on Jul 24, 2023. It is now read-only.
forked from keybase/hubot-keybase
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
151 lines (129 loc) · 4.48 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
'use strict'
const Adapter = require.main.require('hubot/src/adapter')
const Response = require.main.require('hubot/src/response')
const msgs = require.main.require('hubot/src/message')
const Bot = require('keybase-bot')
const convertChannelToRoom = (x) => {
if (!x.topicName) {
return x.name
}
return x.name + '#' + x.topicName
}
const composeMessageID = (room, id) => {
return room + '@' + id
}
const membersCount = (name) => {
return name.split(',').length
}
const convertRoomToChannel = (name) => {
if (membersCount(name) > 1) {
// We're dealing with an impteamnative
return {
name: name,
public: false,
membersType: 'impteamnative',
topicType: 'chat',
}
}
// Otherwise it should be a team channel
const parts = name.split('#')
return {
name: parts[0],
public: false,
membersType: 'team',
topicType: 'chat',
topicName: parts[1],
}
}
/** Main API for Hubot on Keybase */
class KeybaseAdapter extends Adapter {
async run () {
// Overwrite Robot's response class with Keybase custom one
// this.robot.Response = RocketChatResponse
try {
this.robot.logger.info(`[startup] Keybase adapter in use`)
this.keybase = new Bot()
if (process.env.KB_USERNAME && process.env.KB_PAPERKEY) {
await this.keybase.init(
process.env.KB_USERNAME,
process.env.KB_PAPERKEY,
{verbose: false}
)
} else {
await this.keybase.initFromRunningService()
}
if (process.env.KB_UNFURL_MODE) {
await this.keybase.chat.setUnfurlSettings({
mode: process.env.KB_UNFURL_MODE,
})
this.robot.logger.info(`Changed unfurl settings: ${JSON.stringify(await this.keybase.chat.getUnfurlSettings())}`)
}
// Print logs with current configs
this.robot.logger.info(`[startup] Respond to name: ${this.robot.name}`)
if (this.robot.alias) {
this.robot.logger.info(`[startup] Respond to alias: ${this.robot.alias}`)
}
this.keybase.chat.watchAllChannelsForNewMessages(this.process.bind(this), (err) => {
throw err
})
this.emit('connected') // tells hubot to load scripts
} catch(err) {
this.robot.logger.error(`Unable to start ${JSON.stringify(err)}`)
throw err
}
}
/** Process every incoming message in subscription */
process (msg) {
const roomName = convertChannelToRoom(msg.channel)
const messageID = composeMessageID(roomName, msg.id)
const user = this.robot.brain.userForId(msg.sender.uid, {
name: msg.sender.username,
})
const isDM = (msg.channel.membersType === 'impteamnative' && membersCount(msg.channel.name) === 2)
user.roomID = roomName
user.roomType = msg.channel.membersType
user.room = roomName
if (msg.content.type === 'system') {
// "User Bob was added by Alice" messages are not supported because
// system messages don't include UIDs.
return
}
if (msg.content.type === 'join') {
this.robot.logger.debug('Received an EnterMessage')
return this.robot.receive(new msgs.EnterMessage(user, null, messageID))
}
if (msg.content.type === 'leave') {
this.robot.logger.debug('Received an LeaveMessage')
return this.robot.receive(new msgs.LeaveMessage(user, null, messageID))
}
// Direct messages prepend bot's name so Hubot can `.respond`
if (msg.content.type === 'text') {
let text = msg.content.text.body
const startOfText = (text.indexOf('@') === 0) ? 1 : 0
const robotIsNamed = text.indexOf(this.robot.name) === startOfText ||
text.indexOf(this.robot.alias) === startOfText
if (isDM && !robotIsNamed) {
text = `${this.robot.name} ${text}`
}
const textMessage = new msgs.TextMessage(user, text, messageID)
this.robot.logger.debug(`TextMessage: ${textMessage.toString()}`)
return this.robot.receive(textMessage)
}
}
/** Send messages to user addressed in envelope */
async send (envelope, ...strings) {
return await Promise.all(strings.map((text) => {
return this.keybase.chat.send(convertRoomToChannel(envelope.room), {
body: text,
})
}))
}
/** Reply to a user's message (mention them if not a DM) */
reply (envelope, ...strings) {
if (membersCount(envelope.room) === 2) {
strings = strings.map((s) => `@${envelope.user.name} ${s}`)
}
return this.send(envelope, ...strings)
}
}
exports.use = (robot) => new KeybaseAdapter(robot)