forked from nilslice/streamroller
/
facebook.go
92 lines (78 loc) · 2.49 KB
/
facebook.go
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
package services
import (
"errors"
"strings"
"time"
"github.com/dustinblackman/joy4/format/rtmp"
"github.com/dustinblackman/streamroller/logger"
"github.com/dustinblackman/streamroller/sockets"
"github.com/parnurzeal/gorequest"
"github.com/spf13/viper"
"github.com/tidwall/gjson"
)
// FacebookService handles RTMP and chat for Facebook
type FacebookService struct {
name string
}
// Name returns the name of the service
func (f *FacebookService) Name() string {
return f.name
}
// CanConnect returns a bool whether all configuration is available to connect to RTMP
func (f *FacebookService) CanConnect() bool {
return viper.GetViper().GetString("facebook-livekey") != ""
}
// ConnectRTMP connects to RTMP server
func (f *FacebookService) ConnectRTMP() *rtmp.Conn {
logger.Log.Info("Connecting to Facebook RTMP")
return connectRTMP("rtmp://rtmp-api.facebook.com:80/rtmp/" + viper.GetViper().GetString("facebook-livekey"))
}
func (f *FacebookService) connectChat(videoID, accessToken string) {
logger.Log.Info("Starting facebook chat monitor")
var lastID string
sleepDuration := 3000 * time.Millisecond
for {
// TODO Handle error codes
_, body, _ := gorequest.New().
Get("https://graph.facebook.com/v2.8/" + videoID + "/comments").
Query(`{"order": "reverse_chronological", "access_token": "` + accessToken + `"}`).
End()
newMessages := []sockets.SocketMessage{}
var nextLastID string
for idx, entry := range gjson.Get(body, "data").Array() {
name := gjson.Get(entry.Raw, "from.name").String()
message := gjson.Get(entry.Raw, "message").String()
createdAt := gjson.Get(entry.Raw, "created_time").String()
id := name + message + createdAt
if idx == 0 {
nextLastID = string(id)
}
if lastID == id {
break
}
newMessages = append(newMessages, sockets.SocketMessage{
Message: message,
Source: f.name,
User: name,
})
}
lastID = string(nextLastID)
for _, socketMessage := range newMessages {
sockets.SocketChannel <- &socketMessage
}
time.Sleep(sleepDuration)
}
}
// ConnectChat connects to chat service if available
func (f *FacebookService) ConnectChat() error {
viper := viper.GetViper()
if viper.GetString("facebook-livekey") != "" && viper.GetString("facebook-token") != "" {
videoID := strings.Split(viper.GetString("facebook-livekey"), "?")[0]
go f.connectChat(videoID, viper.GetString("facebook-token"))
return nil
}
return errors.New("Missing keys")
}
func init() {
RegisterService(&FacebookService{name: "facebook"})
}