func serveUserTask(env *Environment, waitGroup *sync.WaitGroup, subscription *Subscription, userState *UserState) { email := subscription.GoogleUserInfo.Email slackUser := subscription.SlackUserInfo.User defer func() { if r := recover(); r != nil { env.Logger.Error("[%s/%s] removing handler. reason: %v", email, slackUser, r) env.DiscardChannel <- email } waitGroup.Done() }() var err error if userState.Gdrive.LargestChangeId == 0 { userState.GoogleAccessToken, err = google.DoWithAccessToken(env.Configuration.Google, env.HttpClient, subscription.GoogleRefreshToken, userState.GoogleAccessToken, func(at string) (google.StatusCode, error) { return drive.LargestChangeId(env.HttpClient, userState.Gdrive, at) }) if err != nil { env.Logger.Warning("[%s/%s] %s", email, slackUser, err) } return } userState.GoogleAccessToken, err = google.DoWithAccessToken(env.Configuration.Google, env.HttpClient, subscription.GoogleRefreshToken, userState.GoogleAccessToken, func(at string) (google.StatusCode, error) { return drive.DetectChanges(env.HttpClient, userState.Gdrive, at) }) if err != nil { env.Logger.Warning("[%s/%s] %s", email, slackUser, err) return } if len(userState.Gdrive.ChangeSet) == 0 { return } statusCode, err, folders := drive.FetchFolders(env.HttpClient, userState.GoogleAccessToken) if statusCode != google.Ok { env.Logger.Warning("[%s/%s] while fetching folders: %s", email, slackUser, err) return } message := CreateSlackMessage(subscription, userState, folders, env.Version) if len(message.Attachments) == 0 { return } env.Logger.Info("[%s/%s] @%v %v changes", email, slackUser, userState.Gdrive.LargestChangeId, len(message.Attachments)) status, err := slack.PostMessage(env.HttpClient, subscription.SlackAccessToken, message) if status == slack.NotAuthed || status == slack.InvalidAuth || status == slack.AccountInactive || status == slack.TokenRevoked { panic(err) } if status != slack.Ok { env.Logger.Warning("[%s/%s] %s", email, slackUser, err) } if status == slack.ChannelNotFound { status, err = slack.PostMessage(env.HttpClient, subscription.SlackAccessToken, CreateSlackUnknownChannelMessage(subscription, env.Configuration.Google.RedirectUri, message)) if status == slack.NotAuthed || status == slack.InvalidAuth || status == slack.AccountInactive || status == slack.TokenRevoked { panic(err) } if status != slack.Ok { env.Logger.Warning("[%s/%s] %s", email, slackUser, err) } } }
func handleSubscriptionRequest(env *Environment, renderer render.Render, req *http.Request) { decoder := json.NewDecoder(req.Body) var r Request err := decoder.Decode(&r) if err != nil { renderer.JSON(400, &ErrResponse{err.Error()}) return } if r.GoogleCode == "" { renderer.JSON(400, &ErrResponse{"Invalid oauth code for google"}) return } if r.SlackCode == "" { renderer.JSON(400, &ErrResponse{"Invalid oauth code for slack"}) return } if r.Channel == "" { r.Channel = "#general" } googleRefreshToken, googleAccessToken, status, err := google.NewAccessToken(env.Configuration.Google, env.HttpClient, r.GoogleCode) if status != google.Ok { renderer.JSON(500, &ErrResponse{err.Error()}) return } slackAccessToken, ostatus, err := slack.NewAccessToken(env.Configuration.Slack, env.HttpClient, r.SlackCode) if ostatus != slack.OauthOk { renderer.JSON(500, &ErrResponse{err.Error()}) return } gUserInfo, status, err := userinfo.GetUserInfo(env.HttpClient, googleAccessToken) if status != google.Ok { renderer.JSON(500, &ErrResponse{err.Error()}) return } sUserInfo, sstatus, err := slack.GetUserInfo(env.HttpClient, slackAccessToken) if sstatus != slack.Ok { renderer.JSON(500, &ErrResponse{err.Error()}) return } welcomeMessage := CreateSlackWelcomeMessage(r.Channel, env.Configuration.Google.RedirectUri, sUserInfo, env.Version) cstatus, err := slack.PostMessage(env.HttpClient, slackAccessToken, welcomeMessage) env.RegisterChannel <- &SubscriptionAndAccessToken{ Subscription: &Subscription{ r.Channel, slackAccessToken, googleRefreshToken, gUserInfo, sUserInfo, r.FolderIds, }, GoogleAccessToken: googleAccessToken, } renderer.JSON(200, map[string]interface{}{ "user": gUserInfo, "channelFound": cstatus == slack.Ok, }) }