Example #1
0
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)
		}
	}
}
Example #2
0
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,
	})

}