This repository has been archived by the owner on Jan 24, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmain.go
112 lines (95 loc) · 3.01 KB
/
main.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package main // import "github.com/regiohelden/innovazammad"
import (
"context"
"expvar"
"fmt"
"net/http"
"os"
"time"
"github.com/regiohelden/innovazammad/config"
"github.com/regiohelden/innovazammad/innovaphone"
"github.com/regiohelden/innovazammad/zammad"
"github.com/sirupsen/logrus"
"github.com/stevenroose/gonfig"
)
var version = "dev"
func init() {
err := gonfig.Load(&config.Global, gonfig.Conf{
ConfigFileVariable: "confpath",
FileDefaultFilename: "/etc/innovazammad.yaml",
EnvPrefix: "INNOVAZAMMAD_",
})
if err != nil {
logrus.Fatalf("could not parse config: %s", err)
}
}
func main() {
if config.Global.Version {
fmt.Println(version)
os.Exit(0)
}
// used by expvars; exported on localhost because we also publish config (with passwords)
go http.ListenAndServe("localhost:8080", nil)
expvar.Publish("config", &config.Global)
expvar.NewString("version").Set(version)
logLevel, err := logrus.ParseLevel(config.Global.LogLevel)
if err != nil {
logrus.Fatalf("could not parse loglevel: %s", err)
}
logrus.SetLevel(logLevel)
logrus.Debugf("Config: %s", config.Global.String())
// sanity-check options
// see https://github.com/stevenroose/gonfig/issues/23
switch "" {
case config.Global.PBX.URL:
logrus.Fatal("must provide PBX URL")
case config.Global.PBX.User:
logrus.Fatal("must provide PBX auth user")
case config.Global.PBX.Pass:
logrus.Fatal("must provide PBX auth password")
case config.Global.PBX.MonitorUser:
logrus.Fatal("must provide PBX monitor user")
case config.Global.Zammad.EndpointURL:
logrus.Fatal("must provide Zammad CTI Endpoint")
}
logrus.Infof("starting innovaphone-zammad bridge")
connectionStats := expvar.NewMap("connection_stats")
shutdownCtx := GracefulShutdownContext(context.Background(), GracefulShutdownOpts{
Timeout: time.Duration(*config.Global.GracePeriod),
})
// single use short-circuit var; see 'select' below
shutdown := shutdownCtx.Done()
// shutdownCtx signals the zammad side to finish processing existing calls, and it in turn signals the innovaphone
// side when it's done via callHandlingCtx to stop polling.
zammadSession, callHandlingCtx := zammad.NewSession()
for {
innovaphoneSession := innovaphone.NewSession(callHandlingCtx)
connectionStats.Set("on_since", timeString(time.Now().Format(time.RFC3339)))
calls, errs := innovaphoneSession.PollForever()
handling:
for {
select {
case call := <-calls:
if err := zammadSession.Submit(shutdownCtx, call); err != nil {
logrus.WithFields(logrus.Fields{
"call": call,
}).Warn(err)
}
case err := <-errs:
logrus.Errorf("error while polling: %s", err)
connectionStats.Add("errors", 1)
break handling
case <-shutdown:
// do a one-time check if we actually have any calls being handled; otherwise we can just quit
shutdown = nil
zammadSession.ShutdownIfEmpty()
case <-callHandlingCtx.Done():
return
}
}
}
}
type timeString string
func (ts timeString) String() string {
return fmt.Sprintf("\"%s\"", string(ts))
}