Skip to content

Commit ab15288

Browse files
committed
Assorted fixes when trying a real deploy on AWS
1 parent 7deb66e commit ab15288

File tree

9 files changed

+63
-9
lines changed

9 files changed

+63
-9
lines changed

__mocks__/@slack/web-api.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
/* global jest */
22

33
const mockAccess = jest.fn()
4+
const mockJoin = jest.fn()
45
const mockOpen = jest.fn()
56
const mockPostMessage = jest.fn()
6-
const mockScheduleMessage = jest.fn()
7+
const mockScheduleMessage = jest.fn(async () => ({
8+
ok: true,
9+
scheduled_message_id: 'Q1298393284'
10+
}))
711

812
const mock = jest.fn().mockImplementation(() => {
913
return {
@@ -12,6 +16,7 @@ const mock = jest.fn().mockImplementation(() => {
1216
scheduleMessage: mockScheduleMessage
1317
},
1418
conversations: {
19+
join: mockJoin,
1520
open: mockOpen
1621
},
1722
oauth: {
@@ -25,6 +30,7 @@ const mock = jest.fn().mockImplementation(() => {
2530
module.exports = {
2631
WebClient: mock,
2732
mockAccess,
33+
mockJoin,
2834
mockOpen,
2935
mockPostMessage,
3036
mockScheduleMessage

announces.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ async function hourlyCheck () {
1717
const now = DateTime.local()
1818
const timestamp = await nextAnnounce(instance, now)
1919

20-
const { scheduled_message_id: messageId } = await slack.scheduleMessage(instance, button(timestamp))
20+
const { scheduled_message_id: messageId } = await slack.scheduleMessage(instance, timestamp, button(timestamp))
2121
await db.storeScheduled(instanceRef, timestamp, messageId)
2222
}
2323
}

announces.test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
const { hourlyCheck, nextAnnounce } = require('./announces')
44
const { DateTime } = require('luxon')
55

6+
const button = require('./button')
67
const db = require('./db')
78
const slack = require('./slack')
89

910
const { Instance } = require('./instance')
1011

12+
jest.mock('./button')
1113
jest.mock('./db')
1214
jest.mock('./instance')
1315
jest.mock('./slack')
@@ -67,9 +69,17 @@ describe('hourly check', () => {
6769
post_at: '1562180400'
6870
}))
6971

72+
button.mockImplementation(() => ({
73+
text: 'test'
74+
}))
75+
7076
await hourlyCheck()
7177
expect(slack.scheduleMessage.mock.calls.length).toBe(1)
7278
expect(slack.scheduleMessage.mock.calls[0][0]).toHaveProperty('channel', testInstance.channel)
79+
expect(slack.scheduleMessage.mock.calls[0][1]).toHaveProperty('isLuxonDateTime', true)
80+
expect(slack.scheduleMessage.mock.calls[0][2]).toHaveProperty('text', 'test')
81+
82+
expect(button).toHaveBeenCalledTimes(1)
7383

7484
expect(db.storeScheduled.mock.calls.length).toBe(1)
7585
expect(db.storeScheduled.mock.calls[0][0]).toBe('T00000000')

button.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ module.exports = (timestamp) => {
1818
emoji: true
1919
},
2020
action_id: 'wild_button',
21-
value: timestamp.toISO(),
21+
value: timestamp.toUTC().toISO(),
2222
style: 'primary'
2323
}
2424
]

db.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,8 @@ module.exports = {
297297
const timestamp = dateTime.toUTC().toBSON()
298298
const collection = await instanceCollection()
299299

300+
console.debug(`Storing scheduled time ${dateTime} for instance ${instanceRef}`)
301+
300302
const result = await collection.updateOne({ 'team.id': instanceRef }, {
301303
$set: {
302304
scheduled: {

routes.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ module.exports = (app) => {
6363
// Will handle direct installation of app to workspace
6464
app.get('/install', async (req, res) => {
6565
const clientId = process.env.SLACK_CLIENT_ID
66-
const scopes = 'channels:read,groups:read,im:read,chat:write,im:write,commands'
66+
const scopes = 'channels:read,channels:join,groups:read,im:read,chat:write,chat:write.public,im:write,commands'
6767
const redirectUri = process.env.SLACK_REDIRECT_URI
6868
res.redirect(`https://slack.com/oauth/v2/authorize?client_id=${clientId}&scope=${scopes}&redirect_uri=${redirectUri}`)
6969
})

serverless.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ functions:
4343
handler: handler-serverless.hourly
4444
events:
4545
- schedule:
46-
rate: rate(1 minute)
46+
rate: rate(1 hour)
4747
enabled: true
4848

4949
plugins:

slack.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,22 @@ module.exports = {
1616
channel: instance.channel,
1717
post_at: Math.floor(timestamp.toSeconds())
1818
}
19-
await web.chat.scheduleMessage(object)
19+
20+
try {
21+
return await web.chat.scheduleMessage(object)
22+
} catch (e) {
23+
// If we fail because we're not in the channel we're trying to post to, join it
24+
// first, then try again.
25+
if (e.data.error === 'not_in_channel') {
26+
await web.conversations.join({
27+
channel: instance.channel
28+
})
29+
30+
return web.chat.scheduleMessage(object)
31+
} else {
32+
throw e
33+
}
34+
}
2035
},
2136

2237
async sendImToUser (instance, user, data) {

slack.test.js

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const slack = require('./slack')
55
const { Instance } = require('./instance')
66

77
const { DateTime } = require('luxon')
8-
const { WebClient, mockOpen, mockPostMessage, mockScheduleMessage } = require('@slack/web-api')
8+
const { WebClient, mockJoin, mockOpen, mockPostMessage, mockScheduleMessage } = require('@slack/web-api')
99
const { IncomingWebhook, mockSend } = require('@slack/webhook')
1010

1111
jest.mock('./instance')
@@ -17,18 +17,20 @@ beforeEach(() => {
1717
// Clear all instances and calls to constructor and all methods
1818
IncomingWebhook.mockClear()
1919
WebClient.mockClear()
20+
mockJoin.mockClear()
2021
mockOpen.mockClear()
2122
mockPostMessage.mockClear()
2223
mockScheduleMessage.mockClear()
2324
})
2425

2526
describe('slack api', () => {
26-
test('schedules a message', async () => {
27+
test('schedules a message and returns scheduled message id', async () => {
2728
const t = DateTime.local()
2829
const data = {}
29-
await slack.scheduleMessage(testInstance, t, data)
30+
const result = await slack.scheduleMessage(testInstance, t, data)
3031
expect(WebClient).toHaveBeenCalledTimes(1)
3132
expect(mockScheduleMessage.mock.calls.length).toBe(1)
33+
expect(result).toHaveProperty('scheduled_message_id')
3234
})
3335

3436
test('schedules a message with a channel parameter', async () => {
@@ -49,6 +51,25 @@ describe('slack api', () => {
4951
expect(mockScheduleMessage.mock.calls[0][0]).toHaveProperty('post_at', Math.floor(t.toSeconds()))
5052
})
5153

54+
test('schedules a message to a channel bot is not in', async () => {
55+
mockScheduleMessage.mockRejectedValueOnce({ data: { ok: false, error: 'not_in_channel' } })
56+
57+
const t = DateTime.local()
58+
const data = {}
59+
try {
60+
await slack.scheduleMessage(testInstance, t, data)
61+
} catch (err) {
62+
console.log(`should not throw ${err} JSON: ${JSON.stringify(err)}`)
63+
expect(err).toBe(undefined)
64+
}
65+
expect(WebClient).toHaveBeenCalledTimes(1)
66+
expect(mockJoin).toHaveBeenCalledTimes(1)
67+
expect(mockJoin.mock.calls[0][0]).toHaveProperty('channel', testInstance.channel)
68+
expect(mockScheduleMessage).toHaveBeenCalledTimes(2)
69+
expect(mockScheduleMessage.mock.calls[0][0]).toHaveProperty('post_at', Math.floor(t.toSeconds()))
70+
expect(mockScheduleMessage.mock.calls[1][0]).toHaveProperty('post_at', Math.floor(t.toSeconds()))
71+
})
72+
5273
test('replacing response has replace_original set', async () => {
5374
const url = 'https://test.example.com/hook'
5475
const data = {}

0 commit comments

Comments
 (0)