// Do sends an HTTP request with the provided http.Client and returns an HTTP response. // If the client is nil, http.DefaultClient is used. // If the context is canceled or times out, ctx.Err() will be returned. func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { if client == nil { client = http.DefaultClient } // Request cancelation changed in Go 1.5, see cancelreq.go and cancelreq_go14.go. cancel := canceler(client, req) type responseAndError struct { resp *http.Response err error } result := make(chan responseAndError, 1) go func() { resp, err := client.Do(req) result <- responseAndError{resp, err} }() select { case <-ctx.Done(): cancel() return nil, ctx.Err() case r := <-result: return r.resp, r.err } }
// Handle a new source of messages func (h *Handler) Handle(ctx context.Context, in chan dispatch.Message) { h.logger.Debug("handling new events") for { select { case <-ctx.Done(): h.logger.Info("shutting down") return case event := <-in: switch event.Tag { case "github:opened": issue, ok := event.Payload.(*github.IssueEvent) if !ok { h.logger.Warn("failed to convert to *github.Issue") continue } // figure out which project to add to _, projectsBody, errs := h.Asana.Client().Get(fmt.Sprintf("https://app.asana.com/api/1.0/teams/%d/projects", h.Team)).End() if errs != nil { for _, err := range errs { h.logger.WithField("error", err).Error("error retrieving projects") } continue } projects := &WrappedNameIDs{} err := json.Unmarshal([]byte(projectsBody), projects) if err != nil { h.logger.WithField("error", err).Error("error parsing projects") continue } h.logger.WithField("projects", projects).Debug("got projects") var ( project NameID foundProject = false ) for _, potential := range projects.Data { if potential.Name == issue.Repository.Name { project = potential foundProject = true break } } if !foundProject { h.logger.WithField("project", issue.Repository.Name).Debug("destination project not found") continue } // get users _, usersBody, errs := h.Asana.Client().Get(fmt.Sprintf("https://app.asana.com/api/1.0/teams/%d/users", h.Team)).End() if errs != nil { for _, err := range errs { h.logger.WithField("error", err).Error("error retrieving users") } continue } users := &WrappedNameIDs{} err = json.Unmarshal([]byte(usersBody), users) if err != nil { h.logger.WithField("error", err).Error("error parsing users") continue } h.logger.WithField("users", users).Debug("got users") user := users.Data[rand.Intn(len(users.Data))] // prepare request task := createTask{ Assignee: user.ID, Name: fmt.Sprintf("%s (#%d)", issue.Issue.Title, issue.Issue.Number), Notes: fmt.Sprintf("%s\n\nOpened by %s at %s\n\n%s", issue.Issue.URL, issue.Issue.User.Login, issue.Issue.CreatedAt, issue.Issue.Body), Projects: []int{project.ID}, Workspace: h.Organization, } h.logger.WithField("task", task).Debug("task") taskJSON, err := json.Marshal(dataWrapper{task}) if err != nil { h.logger.WithField("error", err).Error("error marshalling task JSON") continue } _, body, errs := h.Asana.Client(). SendRawBytes(taskJSON). Post("https://app.asana.com/api/1.0/tasks"). End() h.logger.WithField("body", body).Debug("created a task") for _, err := range errs { h.logger.WithField("error", err).Error("error creating task") } default: h.logger.WithField("tag", event.Tag).Debug("not handling tag") } } } }