Skip to content

Commit af0b813

Browse files
harrisonhjonesbmoffatt
authored andcommitted
Add Chime Bot event (#201)
* Add Chime Bot event * go fmt ./...
1 parent 4c210d7 commit af0b813

File tree

4 files changed

+238
-0
lines changed

4 files changed

+238
-0
lines changed

events/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ This package provides input types for Lambda functions that process AWS events.
1414

1515
[CloudFormation Events](../cfn/README.md)
1616

17+
[Chime Bot Events](README_Chime_Bots.md)
18+
1719
[Code Commit Events](README_CodeCommit.md)
1820

1921
[Cognito Events](README_Cognito.md)

events/README_Chime_Bots.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Sample Function
2+
3+
The following is a sample class and Lambda function that receives a Amazon Chime Bot event and handles the various event types accordingly.
4+
5+
```go
6+
7+
package main
8+
9+
import (
10+
"fmt"
11+
"context"
12+
"net/http"
13+
"bytes"
14+
"encoding/json"
15+
"errors"
16+
"strconv"
17+
18+
"github.com/aws/aws-lambda-go/events"
19+
)
20+
21+
func handler(_ context.Context, chimeBotEvent events.ChimeBotEvent) error {
22+
switch chimeBotEvent.EventType {
23+
case "Invite":
24+
if err := message(chimeBotEvent.InboundHTTPSEndpoint.URL, "Thanks for inviting me to this room " + chimeBotEvent.Sender.SenderID); err != nil {
25+
return fmt.Errorf("failed to send webhook message: %v", err)
26+
}
27+
return nil
28+
case "Mention":
29+
if err := message(chimeBotEvent.InboundHTTPSEndpoint.URL, "Thanks for mentioning me " + chimeBotEvent.Sender.SenderID); err != nil {
30+
return fmt.Errorf("failed to send webhook message: %v", err)
31+
}
32+
return nil
33+
case "Remove":
34+
fmt.Printf("I have been removed from %q by %q", chimeBotEvent.Discussion.DiscussionType, chimeBotEvent.Sender.SenderID)
35+
return nil
36+
default:
37+
return fmt.Errorf("event type %q is unsupported", chimeBotEvent.EventType)
38+
}
39+
}
40+
41+
func message(url, content string) (error) {
42+
input := &bytes.Buffer{}
43+
if err := json.NewEncoder(input).Encode(webhookInput{Content:content}); err != nil {
44+
return errors.New("failed to marshal request: " + err.Error())
45+
}
46+
47+
resp, err := http.Post("POST", url, input)
48+
if err != nil {
49+
return errors.New("failed to execute post http request: " + err.Error())
50+
}
51+
52+
if resp != nil && resp.Body != nil {
53+
defer resp.Body.Close()
54+
}
55+
56+
if resp.StatusCode != http.StatusOK {
57+
return errors.New("bad response: status code not is " + strconv.Itoa(http.StatusOK) + " not " + strconv.Itoa(resp.StatusCode))
58+
}
59+
60+
return nil
61+
}
62+
63+
type webhookInput struct {
64+
Content string `json:"Content"`
65+
}
66+
67+
```

events/chime_bot.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
3+
package events
4+
5+
import (
6+
"time"
7+
)
8+
9+
type ChimeBotEvent struct {
10+
Sender ChimeBotEventSender `json:"Sender"`
11+
Discussion ChimeBotEventDiscussion `json:"Discussion"`
12+
EventType string `json:"EventType"`
13+
InboundHTTPSEndpoint *ChimeBotEventInboundHTTPSEndpoint `json:"InboundHttpsEndpoint,omitempty"`
14+
EventTimestamp time.Time `json:"EventTimestamp"`
15+
Message string `json:"Message,omitempty"`
16+
}
17+
18+
type ChimeBotEventSender struct {
19+
SenderID string `json:"SenderId"`
20+
SenderIDType string `json:"SenderIdType"`
21+
}
22+
23+
type ChimeBotEventDiscussion struct {
24+
DiscussionID string `json:"DiscussionId"`
25+
DiscussionType string `json:"DiscussionType"`
26+
}
27+
28+
type ChimeBotEventInboundHTTPSEndpoint struct {
29+
EndpointType string `json:"EndpointType"`
30+
URL string `json:"Url"`
31+
}

events/chime_bot_test.go

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
package events
3+
4+
import (
5+
"encoding/json"
6+
"testing"
7+
8+
"github.com/aws/aws-lambda-go/events/test"
9+
"github.com/stretchr/testify/assert"
10+
"time"
11+
)
12+
13+
func TestChimeBotEventMarshaling(t *testing.T) {
14+
// From https://docs.aws.amazon.com/chime/latest/ag/manage-chat-bots.html
15+
tests := map[string]struct {
16+
inputJSON string
17+
expectedEvent ChimeBotEvent
18+
}{
19+
"Example Invite Event": {
20+
inputJSON: ` {
21+
"Sender": {
22+
"SenderId": "[email protected]",
23+
"SenderIdType": "EmailId"
24+
},
25+
"Discussion": {
26+
"DiscussionId": "abcdef12-g34h-56i7-j8kl-mn9opqr012st",
27+
"DiscussionType": "Room"
28+
},
29+
"EventType": "Invite",
30+
"InboundHttpsEndpoint": {
31+
"EndpointType": "Persistent",
32+
"Url": "https://hooks.a.chime.aws/incomingwebhooks/a1b2c34d-5678-90e1-f23g-h45i67j8901k?token=ABCDefGHiJK1LMnoP2Q3RST4uvwxYZAbC56DeFghIJkLM7N8OP9QRsTuV0WXYZABcdefgHiJ"
33+
},
34+
"EventTimestamp": "2019-04-04T21:27:52.736Z"
35+
}`,
36+
expectedEvent: ChimeBotEvent{
37+
Sender: ChimeBotEventSender{
38+
SenderID: "[email protected]",
39+
SenderIDType: "EmailId",
40+
},
41+
Discussion: ChimeBotEventDiscussion{
42+
DiscussionID: "abcdef12-g34h-56i7-j8kl-mn9opqr012st",
43+
DiscussionType: "Room",
44+
},
45+
EventType: "Invite",
46+
InboundHTTPSEndpoint: &ChimeBotEventInboundHTTPSEndpoint{
47+
EndpointType: "Persistent",
48+
URL: "https://hooks.a.chime.aws/incomingwebhooks/a1b2c34d-5678-90e1-f23g-h45i67j8901k?token=ABCDefGHiJK1LMnoP2Q3RST4uvwxYZAbC56DeFghIJkLM7N8OP9QRsTuV0WXYZABcdefgHiJ",
49+
},
50+
EventTimestamp: time.Date(2019, 04, 04, 21, 27, 52, 736000000, time.UTC),
51+
Message: "",
52+
},
53+
},
54+
"Example Mention Event": {
55+
inputJSON: `{
56+
"Sender": {
57+
"SenderId": "[email protected]",
58+
"SenderIdType": "EmailId"
59+
},
60+
"Discussion": {
61+
"DiscussionId": "abcdef12-g34h-56i7-j8kl-mn9opqr012st",
62+
"DiscussionType": "Room"
63+
},
64+
"EventType": "Mention",
65+
"InboundHttpsEndpoint": {
66+
"EndpointType": "ShortLived",
67+
"Url": "https://hooks.a.chime.aws/incomingwebhooks/a1b2c34d-5678-90e1-f23g-h45i67j8901k?token=ABCDefGHiJK1LMnoP2Q3RST4uvwxYZAbC56DeFghIJkLM7N8OP9QRsTuV0WXYZABcdefgHiJ"
68+
},
69+
"EventTimestamp": "2019-04-04T21:30:43.181Z",
70+
"Message": "@[email protected] Hello Chatbot"
71+
}`,
72+
expectedEvent: ChimeBotEvent{
73+
Sender: ChimeBotEventSender{
74+
SenderID: "[email protected]",
75+
SenderIDType: "EmailId",
76+
},
77+
Discussion: ChimeBotEventDiscussion{
78+
DiscussionID: "abcdef12-g34h-56i7-j8kl-mn9opqr012st",
79+
DiscussionType: "Room",
80+
},
81+
EventType: "Mention",
82+
InboundHTTPSEndpoint: &ChimeBotEventInboundHTTPSEndpoint{
83+
EndpointType: "ShortLived",
84+
URL: "https://hooks.a.chime.aws/incomingwebhooks/a1b2c34d-5678-90e1-f23g-h45i67j8901k?token=ABCDefGHiJK1LMnoP2Q3RST4uvwxYZAbC56DeFghIJkLM7N8OP9QRsTuV0WXYZABcdefgHiJ",
85+
},
86+
EventTimestamp: time.Date(2019, 04, 04, 21, 30, 43, 181000000, time.UTC),
87+
Message: "@[email protected] Hello Chatbot",
88+
},
89+
},
90+
"Example Remove Event": {
91+
inputJSON: `{
92+
"Sender": {
93+
"SenderId": "[email protected]",
94+
"SenderIdType": "EmailId"
95+
},
96+
"Discussion": {
97+
"DiscussionId": "abcdef12-g34h-56i7-j8kl-mn9opqr012st",
98+
"DiscussionType": "Room"
99+
},
100+
"EventType": "Remove",
101+
"EventTimestamp": "2019-04-04T21:27:29.626Z"
102+
}`,
103+
expectedEvent: ChimeBotEvent{
104+
Sender: ChimeBotEventSender{
105+
SenderID: "[email protected]",
106+
SenderIDType: "EmailId",
107+
},
108+
Discussion: ChimeBotEventDiscussion{
109+
DiscussionID: "abcdef12-g34h-56i7-j8kl-mn9opqr012st",
110+
DiscussionType: "Room",
111+
},
112+
EventType: "Remove",
113+
EventTimestamp: time.Date(2019, 04, 04, 21, 27, 29, 626000000, time.UTC),
114+
},
115+
},
116+
}
117+
118+
for name, test := range tests {
119+
t.Run(name, func(t *testing.T) {
120+
var testEvent ChimeBotEvent
121+
if err := json.Unmarshal([]byte(test.inputJSON), &testEvent); err != nil {
122+
t.Errorf("could not unmarshal event. details: %v", err)
123+
}
124+
125+
assert.Equal(t, testEvent, test.expectedEvent)
126+
127+
outputJSON, err := json.Marshal(testEvent)
128+
if err != nil {
129+
t.Errorf("could not marshal event. details: %v", err)
130+
}
131+
assert.JSONEq(t, test.inputJSON, string(outputJSON))
132+
})
133+
}
134+
}
135+
136+
func TestChimeBotMarshalingMalformedJSON(t *testing.T) {
137+
test.TestMalformedJson(t, ChimeBotEvent{})
138+
}

0 commit comments

Comments
 (0)