Exemplo n.º 1
0
func commitsReplied(c *integram.Context, baseURL string, projectID int, commits []commit) error {
	authorized, err := mustBeAuthed(c)

	if err != nil {
		return err
	}

	if !authorized {
		//todo:bug message lost
		return c.User.SetAfterAuthAction(commitsReplied, baseURL, projectID, commits)
	}
	buttons := integram.Buttons{}

	for _, commit := range commits {
		buttons.Append(commit.ID, trim(commit.Message, 40))
	}

	return c.NewMessage().
		SetText(c.User.Mention()+" please specify commit to comment").
		SetKeyboard(buttons.Markup(1), true).
		EnableForceReply().
		SetReplyAction(commitToReplySelected, baseURL, projectID, c.Message).
		Send()

}
Exemplo n.º 2
0
func prText(c *integram.Context, pr *api.PullRequest) string {

	r := reRepoFullNameFromURL.FindStringSubmatch(pr.Links.Self.Href)

	repo := ""
	if len(r) == 2 {
		repo = r[1]
	}

	if pr.Description == pr.Title {
		pr.Description = ""
	}
	text := fmt.Sprintf("%s %s\n%s",
		m.Bold(pr.Title),
		m.URL("➔", c.WebPreview("Pull Request", repo, "by "+pr.Author.DisplayName, pr.Links.HTML.String(), "")),
		pr.Description)

	if len(pr.Reviewers) > 0 {
		text += "\n  👤 "

		for i, reviewer := range pr.Reviewers {
			text += mention(c, &reviewer)
			if i < len(pr.Reviewers)-1 {
				text += ", "
			}
		}
	}
	return text
}
Exemplo n.º 3
0
func mention(c *integram.Context, member *api.Actor) string {
	userName := ""
	c.ServiceCache("nick_map_"+member.UUID, &userName)
	if userName == "" {
		return m.Bold(member.DisplayName)
	}
	return "@" + userName
}
Exemplo n.º 4
0
func sendSnippetComment(c *integram.Context, projectID int, SnippetID int, text string) error {
	note, _, err := client(c).Notes.CreateSnippetNote(projectID, SnippetID, &api.CreateSnippetNoteOptions{Body: text})
	if note != nil {
		c.Message.UpdateEventsID(c.Db(), noteUniqueID(projectID, strconv.Itoa(note.ID)))
	}

	return err
}
Exemplo n.º 5
0
func snippetMessageID(c *integram.Context, snippetID int) int {
	msg, err := c.FindMessageByEventID("snippet_" + strconv.Itoa(snippetID))

	if err == nil && msg != nil {
		return msg.MsgID
	}
	return 0
}
Exemplo n.º 6
0
func issueMessageID(c *integram.Context, issueID int) int {
	msg, err := c.FindMessageByEventID("issue_" + strconv.Itoa(issueID))

	if err == nil && msg != nil {
		return msg.MsgID
	}
	return 0
}
Exemplo n.º 7
0
func commitMessageID(c *integram.Context, commitID string) int {
	msg, err := c.FindMessageByEventID("commit_" + commitID)

	if err == nil && msg != nil {
		return msg.MsgID
	}
	return 0
}
Exemplo n.º 8
0
func mrMessageID(c *integram.Context, mergeRequestID int) int {
	msg, err := c.FindMessageByEventID("mr_" + strconv.Itoa(mergeRequestID))

	if err == nil && msg != nil {
		return msg.MsgID
	}
	return 0
}
Exemplo n.º 9
0
func settings(c *integram.Context) error {
	btns := integram.InlineButtons{}

	btns.Append("ci", "CI")
	btns.Append("mr", "Merge requests")

	return c.NewMessage().SetText("Tune the notifications").SetInlineKeyboard(btns.Markup(1, "categories")).SetCallbackAction(settingsKeyboardPressed).Send()
}
Exemplo n.º 10
0
func sendIssueComment(c *integram.Context, projectID int, issueID int, text string) error {
	note, _, err := client(c).Notes.CreateIssueNote(projectID, issueID, &api.CreateIssueNoteOptions{Body: text})

	if note != nil {
		c.Message.UpdateEventsID(c.Db(), "issue_note_"+strconv.Itoa(note.ID))
	}

	return err
}
Exemplo n.º 11
0
func cacheNickMap(c *integram.Context) error {
	me, err := me(c)
	if err != nil {
		return err
	}
	c.SetServiceCache("nick_map_"+me.Username, c.User.UserName, time.Hour*24*365)
	err = c.SetServiceCache("nick_map_"+me.Email, c.User.UserName, time.Hour*24*365)
	return err
}
Exemplo n.º 12
0
func sendCommitComment(c *integram.Context, projectID int, commitID string, msg *integram.IncomingMessage) error {
	note, _, err := client(c).Notes.CreateCommitNote(projectID, commitID, &api.CreateCommitNoteOptions{Note: msg.Text})
	if err != nil {
		return err
	}
	// note id not available for commit comment. So use the date. Collisions are unlikely here...
	c.Message.UpdateEventsID(c.Db(), noteUniqueID(projectID, note.CreatedAt))

	return err
}
Exemplo n.º 13
0
func commitReplied(c *integram.Context, baseURL string, projectID int, commitID string) error {
	c.Message.SetReplyAction(commitReplied, baseURL, projectID, commitID)
	c.SetServiceBaseURL(baseURL)

	authorized, err := mustBeAuthed(c)
	if !authorized {
		return c.User.SetAfterAuthAction(sendCommitComment, c, projectID, commitID, c.Message)
	}
	c.Service().DoJob(sendCommitComment, c, projectID, commitID, c.Message)
	return err
}
Exemplo n.º 14
0
func mention(c *integram.Context, name string, email string) string {
	userName := ""
	c.ServiceCache("nick_map_"+name, &userName)
	if userName == "" && email != "" {
		c.ServiceCache("nick_map_"+email, &userName)
	}
	if userName == "" {
		return m.Bold(name)
	}
	return "@" + userName
}
Exemplo n.º 15
0
func settingsKeyboardPressed(c *integram.Context) error {
	cs := chatSettings(c)

	state := c.Callback.Message.InlineKeyboardMarkup.State

	if state == "categories" {
		state = c.Callback.Data
	}

	btns := integram.InlineButtons{}

	if c.Callback.Data == "back" {
		btns.Append("ci", "CI")
		btns.Append("mr", "Merge requests")
		state = "categories"
	} else if state == "mr" {
		btns.Append("back", "← Back")
		switch c.Callback.Data {
		case "open":
			cs.MR.Open = !stateToBool(c.Callback.State)
		case "close":
			cs.MR.Close = !stateToBool(c.Callback.State)
		case "update":
			cs.MR.Update = !stateToBool(c.Callback.State)
		case "merge":
			cs.MR.Merge = !stateToBool(c.Callback.State)
		}

		c.Chat.SaveSettings(cs)

		btns.AppendWithState(boolToState(cs.MR.Open), "open", boolToMark(cs.MR.Open)+"Open")
		btns.AppendWithState(boolToState(cs.MR.Update), "update", boolToMark(cs.MR.Update)+"Update")
		btns.AppendWithState(boolToState(cs.MR.Merge), "merge", boolToMark(cs.MR.Merge)+"Merge")
		btns.AppendWithState(boolToState(cs.MR.Close), "close", boolToMark(cs.MR.Close)+"Close")

	} else if state == "ci" {
		btns.Append("back", "← Back")
		switch c.Callback.Data {
		case "success":
			cs.CI.Success = !stateToBool(c.Callback.State)
		case "fail":
			cs.CI.Fail = !stateToBool(c.Callback.State)
		case "cancel":
			cs.CI.Cancel = !stateToBool(c.Callback.State)
		}

		c.Chat.SaveSettings(cs)

		btns.AppendWithState(boolToState(cs.CI.Success), "success", boolToMark(cs.CI.Success)+"Success")
		btns.AppendWithState(boolToState(cs.CI.Fail), "fail", boolToMark(cs.CI.Fail)+"Fail")
		btns.AppendWithState(boolToState(cs.CI.Cancel), "cancel", boolToMark(cs.CI.Cancel)+"Cancel")
	}
	return c.EditPressedInlineKeyboard(btns.Markup(1, state))
}
Exemplo n.º 16
0
func snippetReplied(c *integram.Context, baseURL string, projectID int, snippetID int) error {
	c.SetServiceBaseURL(baseURL)

	authorized, err := mustBeAuthed(c)
	if !authorized {
		c.User.SetAfterAuthAction(sendSnippetComment, baseURL, projectID, snippetID, c.Message.Text)
	} else {
		_, err = c.Service().DoJob(sendSnippetComment, c, baseURL, projectID, snippetID, c.Message.Text)
	}

	c.Message.SetReplyAction(mrReplied, baseURL, projectID, snippetID)
	return err
}
Exemplo n.º 17
0
/*func me(c *integram.Context) (*gitlab.User, error) {
	api:=Api(c).Repositories.Commits.GetCommit()
	user := &gitlab.User{}

	c.User.Cache("me", user)
	if user.ID > 0 {
		return user, nil
	}

	user, _, err := Api(c).Users.CurrentUser()

	if err != nil {
		return nil, err
	}

	c.User.SetCache("me", user, time.Hour*24*30)

	return user, nil
}

func cacheNickMap(c *integram.Context) error {
	me, err := me(c)
	if err != nil {
		return err
	}
	c.SetServiceCache("nick_map_"+me.Username, c.User.UserName, time.Hour*24*365)
	err = c.SetServiceCache("nick_map_"+me.Email, c.User.UserName, time.Hour*24*365)
	return err
}

*/
func hostedAppSecretEntered(c *integram.Context, baseURL string, appID string) error {
	c.SetServiceBaseURL(baseURL)

	appSecret := strings.TrimSpace(c.Message.Text)
	if len(appSecret) != 64 {
		c.NewMessage().SetText("Looks like this *Application Secret* is incorrect. Must be a 64 HEX symbols. Please try again").EnableHTML().DisableWebPreview().SetReplyAction(hostedAppSecretEntered, baseURL).Send()
		return errors.New("Application Secret '" + appSecret + "' is incorrect")
	}
	conf := integram.OAuthProvider{BaseURL: c.ServiceBaseURL, ID: appID, Secret: appSecret}
	token, err := conf.OAuth2Client(c).Exchange(oauth2.NoContext, "-")

	if strings.Contains(err.Error(), `"error":"invalid_grant"`) {
		// means the app is exists
		c.SaveOAuthProvider(c.ServiceBaseURL, appID, appSecret)
		_, err := mustBeAuthed(c)

		return err
	}
	c.NewMessage().SetText("Application ID or Secret is incorrect. Please try again. Enter *Application Id*").
		EnableHTML().
		SetReplyAction(hostedAppIDEntered, baseURL).Send()

	fmt.Printf("Exchange: token: %+v, err:%v\n", token, err)

	return nil

}
Exemplo n.º 18
0
func issueText(c *integram.Context, issue *api.Issue) string {

	r := reRepoFullNameFromURL.FindStringSubmatch(issue.Links.Self.Href)

	repo := ""
	if len(r) == 2 {
		repo = r[1]
	}

	return fmt.Sprintf("%s %s\n%s\n%s",
		m.Bold(issue.Title),
		m.URL("➔", c.WebPreview("by "+issue.Reporter.DisplayName, repo, "", issue.Links.HTML.String(), "")),
		issue.Content.Raw,
		"#"+issue.Priority+" #"+issue.Type)
}
Exemplo n.º 19
0
func prInlineButtonPressed(c *integram.Context, fullRepoName string, prID int) error {
	if ok, err := mustBeAuthed(c); !ok {
		return err
	}
	pr := api.PullRequest{}

	c.ServiceCache(issueUniqueID(fullRepoName, prID), &pr)

	switch c.Callback.Data {
	case "back":
		return c.EditPressedInlineKeyboard(prInlineKeyboard(&pr))
	case "assign":
		//rest.Repositories.ListPublic()
	}
	return nil

}
Exemplo n.º 20
0
func update(c *integram.Context) error {

	command, param := c.Message.GetCommand()

	if c.Message.IsEventBotAddedToGroup() {
		command = "start"
	}
	if param == "silent" {
		command = ""
	}

	switch command {

	case "start":
		return c.NewMessage().EnableAntiFlood().EnableHTML().
			SetText("Hi here! You can send " + m.URL("Slack-compatible", "https://api.slack.com/docs/message-formatting#message_formatting") + " simple webhooks to " + m.Bold("this chat") + " using this URL: \n" + m.Fixed(c.Chat.ServiceHookURL()) + "\n\nExample (JSON payload):\n" + m.Pre("{\"text\":\"So _advanced_\\nMuch *innovations* 🙀\"}")).Send()

	}
	return nil
}
Exemplo n.º 21
0
func webhookHandler(c *integram.Context, wc *integram.WebhookContext) (err error) {

	wh := webhook{Mrkdwn: true}
	err = wc.JSON(&wh)

	if err != nil {
		return
	}

	if len(wh.Attachments) > 0 {
		if wh.Text != "" {
			wh.Text += "\n"
		}
		wp := c.WebPreview(wh.Attachments[0].Title, wh.Attachments[0].AuthorName, wh.Attachments[0].Pretext, wh.Attachments[0].TitleLink, wh.Attachments[0].ThumbURL)
		text := m.URL(" ", wp) + " " + wh.Text
		for i, attachment := range wh.Attachments {
			if i > 0 {
				text += "\n"
			}
			text += m.URL(attachment.Title, attachment.TitleLink) + " " + attachment.Pretext
		}
		return c.NewMessage().SetText(text).EnableAntiFlood().EnableHTML().Send()
	}

	if wh.Text != "" {
		m := c.NewMessage().SetText(wh.Text + " " + wh.Channel).EnableAntiFlood()
		if wh.Mrkdwn {
			m.EnableMarkdown()
		}
		return m.Send()
	}

	return errors.New("Text and Attachments not found")
}
Exemplo n.º 22
0
func update(c *integram.Context) error {

	command, param := c.Message.GetCommand()

	if c.Message.IsEventBotAddedToGroup() {
		command = "start"
	}

	if param == "silent" {
		command = ""
	}

	switch command {

	case "start":
		return c.NewMessage().EnableAntiFlood().EnableHTML().
			SetTextFmt("Hi here! To setup notifications for %s for your BitBucket repo, open Settings -> Webhooks and add this URL:\n%s\n%s", m.Bold("this chat"), m.Fixed(c.Chat.ServiceHookURL()), m.Bold("⚠️ Don't forget to add all triggers inside the \"Choose from a full list of triggers\" radio button!")).Send()

	case "cancel", "clean", "reset":
		return c.NewMessage().SetText("Clean").HideKeyboard().Send()

	}
	return nil
}
Exemplo n.º 23
0
func update(c *integram.Context) error {

	command, param := c.Message.GetCommand()

	if c.Message.IsEventBotAddedToGroup() {
		command = "start"
	}
	if param == "silent" {
		command = ""
	}

	switch command {

	case "start":
		return c.NewMessage().EnableAntiFlood().EnableHTML().
			SetText("Hi here! To setup notifications " + m.Bold("for this chat") + " your GitLab project(repo), open Settings -> Web Hooks and add this URL:\n" + m.Fixed(c.Chat.ServiceHookURL())).EnableHTML().Send()

	case "cancel", "clean", "reset":
		return c.NewMessage().SetText("Clean").HideKeyboard().Send()
	case "settings":
		return settings(c)
	}
	return nil
}
Exemplo n.º 24
0
func hostedAppIDEntered(c *integram.Context, baseURL string) error {
	c.SetServiceBaseURL(baseURL)

	appID := strings.TrimSpace(c.Message.Text)
	if len(appID) != 64 {
		c.NewMessage().SetText("Looks like this *Application Id* is incorrect. Must be a 64 HEX symbols. Please try again").
			EnableHTML().
			SetReplyAction(hostedAppIDEntered, baseURL).Send()
		return errors.New("Application Id '" + appID + "' is incorrect")
	}
	return c.NewMessage().SetText("Great! Now write me the *Secret* for this application").
		EnableHTML().
		SetReplyAction(hostedAppSecretEntered, baseURL, appID).Send()
}
Exemplo n.º 25
0
// we nee msg param because action c.Message can contains selected commit id from prev state at commitsReplied and not the comment message
func commitToReplySelected(c *integram.Context, baseURL string, projectID int, msg *integram.IncomingMessage) error {

	commitID, _ := c.KeyboardAnswer()

	c.Message.SetReplyAction(commitReplied, baseURL, projectID, commitID)
	c.SetServiceBaseURL(baseURL)

	authorized, err := mustBeAuthed(c)
	if !authorized {
		return c.User.SetAfterAuthAction(sendCommitComment, c, projectID, commitID, msg.Text)
	}

	c.Service().DoJob(sendCommitComment, projectID, commitID)

	return err
}
Exemplo n.º 26
0
func mustBeAuthed(c *integram.Context) (bool, error) {

	provider := c.OAuthProvider()

	if !provider.IsSetup() {
		return false, c.NewMessage().SetText(fmt.Sprintf("To be able to use interactive replies in Telegram, first you need to add oauth application on your hosted GitLab instance (admin priveleges required): %s\nAdd application with any name(f.e. Telegram) and specify this *Redirect URI*: \n%s\n\nAfter you press *Submit* you will receive app info. First, send me the *Application ID*", c.ServiceBaseURL.String()+"/admin/applications/new", provider.RedirectURL())).
			SetChat(c.User.ID).
			SetBackupChat(c.Chat.ID).
			EnableHTML().
			EnableForceReply().
			DisableWebPreview().
			SetReplyAction(hostedAppIDEntered, c.ServiceBaseURL.String()).Send()

	}
	if !c.User.OAuthValid() {
		return false, c.NewMessage().SetTextFmt("You need to authorize me to use interactive replies: %s", c.User.OauthInitURL()).
			DisableWebPreview().
			SetChat(c.User.ID).SetBackupChat(c.Chat.ID).Send()
	}

	return true, nil

}
Exemplo n.º 27
0
func webhookHandler(c *integram.Context, wc *integram.WebhookContext) (err error) {
	eventKey := wc.Header("X-Event-Key")

	if eventKey == "" {
		// try the old one Bitbucket POST service

		return oldWebhookHandler(c, wc)
	}

	if _, ok := eventTypeMap[eventKey]; !ok {

		return errors.New("Bad X-Event-Key: " + eventKey)
	}

	c.Log().Debugf("eventKey=%v", eventKey)

	if err != nil {
		return errors.New("JSON deserialization error: " + err.Error())
	}

	switch eventKey {
	case "repo:push":
		event := api.RepoPushEvent{}
		wc.JSON(&event)

		for _, change := range event.Push.Changes {

			msg := c.NewMessage()
			commits := 0
			text := ""

			if len(change.Commits) > 1 {
				anyOherPersonCommits := false
				for _, commit := range change.Commits {
					if commit.Author.User.UUID != event.Actor.UUID {
						anyOherPersonCommits = true
						break
					}
				}
				for _, commit := range change.Commits {
					commits++
					if anyOherPersonCommits {
						text += mention(c, &commit.Author.User) + ": "
					}
					text += m.URL(commit.Message, commit.Links.HTML.Href) + "\n"
				}
				if change.Truncated {
					text += m.URL("... See all", change.Links.Commits.Href) + "\n"
				}
			} else if len(change.Commits) == 1 {
				commits++
				commit := &change.Commits[0]
				if commit.Author.User.UUID != event.Actor.UUID {
					text += mention(c, &commit.Author.User) + ": "
				}

				text += commit.Message + "\n"
			}

			change.New.Target.Author.User.Links.Avatar.Href = strings.Replace(change.New.Target.Author.User.Links.Avatar.Href, "/32/", "/128/", 1)
			wp := ""
			if change.Truncated {
				wp = c.WebPreview("> 5 commits", "@"+commitShort(change.Old.Target.Hash)+" ... @"+commitShort(change.New.Target.Hash), "", change.Links.HTML.Href, change.New.Target.Author.User.Links.Avatar.Href)
			} else if commits > 1 {
				wp = c.WebPreview(fmt.Sprintf("%d commits", commits), "@"+commitShort(change.Old.Target.Hash)+" ... @"+commitShort(change.New.Target.Hash), "", change.Links.HTML.Href, change.New.Target.Author.User.Links.Avatar.Href)
			} else if commits == 1 {
				wp = c.WebPreview("Commit", "@"+commitShort(change.New.Target.Hash), "", change.Commits[0].Links.HTML.Href, change.New.Target.Author.User.Links.Avatar.Href)
			}

			if commits > 0 {
				pushedText := ""
				if change.Forced {
					pushedText = m.URL("❗️ forcibly pushed", wp)
				} else {
					pushedText = m.URL("pushed", wp)
				}
				err = msg.SetTextFmt("%s %s to %s/%s\n%s",
					mention(c, &change.New.Target.Author.User),
					pushedText,
					m.URL(event.Repository.Name, event.Repository.Links.HTML.Href),
					m.URL(change.New.Name, change.New.Links.HTML.Href),
					text).
					AddEventID(commitUniqueID(change.Commits[0].Hash)).
					EnableHTML().
					Send()
			}
		}
	case "issue:created":
		event := api.IssueCreatedEvent{}
		err := wc.JSON(&event)
		if err != nil {
			return err
		}
		event.Issue.Repository = &event.Repository

		c.SetServiceCache(issueUniqueID(event.Repository.FullName, event.Issue.ID), event.Issue, time.Hour*24*365)

		return c.NewMessage().AddEventID(issueUniqueID(event.Repository.FullName, event.Issue.ID)).
			SetInlineKeyboard(issueInlineKeyboard(&event.Issue)).
			SetText(issueText(c, &event.Issue)).
			SetCallbackAction(issueInlineButtonPressed, event.Repository.FullName, event.Issue.ID).
			EnableHTML().Send()
	case "issue:comment_created":
		event := api.IssueCommentCreatedEvent{}
		err := wc.JSON(&event)
		if err != nil {
			return err
		}

		var rm *integram.Message
		if event.Comment.Parent.ID > 0 {
			// actually bitbucket doesn't provide parent id for issue comments for now
			rm, _ = c.FindMessageByEventID(issueCommentUniqueID(event.Repository.FullName, event.Issue.ID, event.Comment.Parent.ID))
		}
		if rm == nil {
			rm, _ = c.FindMessageByEventID(issueUniqueID(event.Repository.FullName, event.Issue.ID))
		}

		msg := c.NewMessage().AddEventID(issueCommentUniqueID(event.Repository.FullName, event.Issue.ID, event.Comment.ID)).EnableHTML()

		if rm != nil {
			return msg.SetReplyToMsgID(rm.MsgID).SetText(fmt.Sprintf("%s: %s", mention(c, &event.Actor), event.Comment.Content.Raw)).Send()
		}
		wp := c.WebPreview("Issue", event.Issue.Title, event.Repository.FullName, event.Comment.Links.HTML.Href, "")
		return msg.SetText(fmt.Sprintf("%s %s: %s", m.URL("💬", wp), mention(c, &event.Actor), event.Comment.Content.Raw)).Send()

	case "repo:commit_comment_created":
		event := api.RepoCommitCommentCreatedEvent{}
		err := wc.JSON(&event)
		if err != nil {
			return err
		}

		var rm *integram.Message
		if event.Comment.Parent.ID > 0 {
			// actually bitbucket doesn't provide parent id for issue comments for now
			rm, _ = c.FindMessageByEventID(commitCommentUniqueID(event.Commit.Hash, event.Comment.Parent.ID))
		}
		if rm == nil {
			rm, _ = c.FindMessageByEventID(commitUniqueID(event.Commit.Hash))
		}

		msg := c.NewMessage().AddEventID(commitCommentUniqueID(event.Commit.Hash, event.Comment.Parent.ID)).EnableHTML()

		if rm != nil {
			return msg.SetReplyToMsgID(rm.MsgID).SetText(fmt.Sprintf("%s: %s", mention(c, &event.Actor), event.Comment.Content.Raw)).Send()
		}
		wp := c.WebPreview("Commit", "@"+event.Commit.Hash[0:10], event.Repository.FullName, event.Comment.Links.HTML.Href, "")
		return msg.SetText(fmt.Sprintf("%s %s: %s", m.URL("💬", wp), mention(c, &event.Actor), event.Comment.Content.Raw)).Send()

	case "issue:updated":
		event := api.IssueUpdatedEvent{}
		err := wc.JSON(&event)
		if err != nil {
			return err
		}
		eventID := issueUniqueID(event.Repository.FullName, event.Issue.ID)
		rm, _ := c.FindMessageByEventID(eventID)

		msg := c.NewMessage().AddEventID(issueCommentUniqueID(event.Repository.FullName, event.Issue.ID, event.Comment.ID)).EnableHTML()

		if event.Comment.Content.Raw != "" {
			event.Comment.Content.Raw = ": " + event.Comment.Content.Raw
		}

		if rm != nil {
			c.EditMessagesTextWithEventID(eventID, issueText(c, &event.Issue))
			// if last Issue message just posted
			if err == nil && time.Now().Sub(rm.Date).Seconds() < 60 {
				return nil
			}

			return msg.SetReplyToMsgID(rm.MsgID).SetText(fmt.Sprintf("%s update the issue%s", mention(c, &event.Actor), event.Comment.Content.Raw)).Send()
		}
		return msg.SetText(fmt.Sprintf("%s updated an issue%s\n%s", mention(c, &event.Actor), event.Comment.Content.Raw, issueText(c, &event.Issue))).Send()

	case "pullrequest:updated":
		event := api.PullRequestCreatedEvent{}
		err := wc.JSON(&event)
		if err != nil {
			return err
		}

		prText := prText(c, &event.PullRequest)

		eventID := prUniqueID(event.Repository.FullName, event.PullRequest.ID)
		rm, _ := c.FindMessageByEventID(eventID)

		msg := c.NewMessage()

		if rm != nil {
			c.EditMessagesTextWithEventID(eventID, prText)
			// if last PR message just posted
			if err == nil && time.Now().Sub(rm.Date).Seconds() < 60 {
				return nil
			}

			msg.SetReplyToMsgID(rm.MsgID)
		} else {
			msg.AddEventID(prUniqueID(event.Repository.FullName, event.PullRequest.ID))
		}

		return msg.
			SetText("✏️ " + prText).
			EnableHTML().Send()
	case "pullrequest:created":
		event := api.PullRequestCreatedEvent{}
		err := wc.JSON(&event)
		if err != nil {
			return err
		}

		c.SetServiceCache(prUniqueID(event.Repository.FullName, event.PullRequest.ID), event.PullRequest, time.Hour*24*365)

		return c.NewMessage().AddEventID(prUniqueID(event.Repository.FullName, event.PullRequest.ID)).
			SetText(prText(c, &event.PullRequest)).
			EnableHTML().Send()

	case "pullrequest:approved":
		event := api.PullRequestApprovedEvent{}
		err := wc.JSON(&event)
		if err != nil {
			return err
		}

		rm, _ := c.FindMessageByEventID(prUniqueID(event.Repository.FullName, event.PullRequest.ID))
		msg := c.NewMessage().EnableHTML()

		if rm != nil {
			return msg.SetReplyToMsgID(rm.MsgID).SetText(fmt.Sprintf("✅ Approved by %s", mention(c, &event.Actor))).Send()
		}
		wp := c.WebPreview("Pull Request", event.PullRequest.Title, "by "+event.PullRequest.Author.DisplayName+" in "+event.Repository.FullName, event.PullRequest.Links.HTML.Href, "")
		return msg.SetText(fmt.Sprintf("✅ %s by %s", m.URL("Approved", wp), mention(c, &event.Actor))).Send()

	case "pullrequest:unapproved":
		event := api.PullRequestApprovalRemovedEvent{}
		err := wc.JSON(&event)
		if err != nil {
			return err
		}

		rm, _ := c.FindMessageByEventID(prUniqueID(event.Repository.FullName, event.PullRequest.ID))
		msg := c.NewMessage().EnableHTML()

		if rm != nil {
			return msg.SetReplyToMsgID(rm.MsgID).SetText(fmt.Sprintf("❌ %s removed approval", mention(c, &event.Actor))).Send()
		}
		wp := c.WebPreview("Pull Request", event.PullRequest.Title, "by "+event.PullRequest.Author.DisplayName+" in "+event.Repository.FullName, event.PullRequest.Links.HTML.Href, "")
		return msg.SetText(fmt.Sprintf("❌ %s %s", mention(c, &event.Actor), m.URL("removed approval", wp))).Send()

	case "pullrequest:fulfilled":
		event := api.PullRequestMergedEvent{}
		err := wc.JSON(&event)
		if err != nil {
			return err
		}

		rm, _ := c.FindMessageByEventID(prUniqueID(event.Repository.FullName, event.PullRequest.ID))
		msg := c.NewMessage().EnableHTML()

		if rm != nil {
			return msg.SetReplyToMsgID(rm.MsgID).SetText(fmt.Sprintf("✅ Merged by %s", mention(c, &event.Actor))).Send()
		}
		wp := c.WebPreview("Pull Request", event.PullRequest.Title, "by "+event.PullRequest.Author.DisplayName+" in "+event.Repository.FullName, event.PullRequest.Links.HTML.Href, "")
		return msg.SetText(fmt.Sprintf("✅ %s by %s", m.URL("Merged", wp), mention(c, &event.Actor))).Send()

	case "pullrequest:rejected":
		event := api.PullRequestDeclinedEvent{}
		err := wc.JSON(&event)
		if err != nil {
			return err
		}

		rm, _ := c.FindMessageByEventID(prUniqueID(event.Repository.FullName, event.PullRequest.ID))
		msg := c.NewMessage().EnableHTML()

		if rm != nil {
			return msg.SetReplyToMsgID(rm.MsgID).SetText(fmt.Sprintf("❌ Declined by %s: %s", mention(c, &event.Actor), event.PullRequest.Reason)).Send()
		}
		wp := c.WebPreview("Pull Request", event.PullRequest.Title, "by "+event.PullRequest.Author.DisplayName+" in "+event.Repository.FullName, event.PullRequest.Links.HTML.Href, "")
		return msg.SetText(fmt.Sprintf("❌ %s by %s", m.URL("Declined", wp), mention(c, &event.Actor))).Send()

	case "pullrequest:comment_created":
		event := api.PullRequestCommentCreatedEvent{}
		err := wc.JSON(&event)
		if err != nil {
			return err
		}

		rm, _ := c.FindMessageByEventID(prUniqueID(event.Repository.FullName, event.PullRequest.ID))

		msg := c.NewMessage().AddEventID(prCommentUniqueID(event.Repository.FullName, event.PullRequest.ID, event.Comment.ID)).EnableHTML()

		if rm != nil {
			return msg.SetReplyToMsgID(rm.MsgID).SetText(fmt.Sprintf("%s: %s", mention(c, &event.Actor), event.Comment.Content.Raw)).Send()
		}
		wp := c.WebPreview("Pull Request", event.PullRequest.Title, event.Repository.FullName, event.PullRequest.Links.HTML.Href, "")
		return msg.SetText(fmt.Sprintf("%s %s: %s", m.URL("💬", wp), mention(c, &event.Actor), event.Comment.Content.Raw)).Send()

	}
	return err

}
Exemplo n.º 28
0
func oldWebhookHandler(c *integram.Context, wc *integram.WebhookContext) (err error) {

	wh := oldWebhook{}

	payload := wc.FormValue("payload")

	if payload == "" {
		return errors.New("X-Event-Key header missed and old-style webhook data not found")
	}

	json.Unmarshal([]byte(payload), &wh)

	if wh.CanonURL == "" {
		return errors.New("Error decoding payload for old webhook")
	}

	msg := c.NewMessage()
	commits := 0
	text := ""
	wp := ""

	if len(wh.Commits) == 0 {
		return nil
	}

	headCommit := wh.Commits[len(wh.Commits)-1]

	if len(wh.Commits) > 1 {

		wp = c.WebPreview(fmt.Sprintf("%d commits", len(wh.Commits)), "@"+wh.Commits[0].Node[0:10]+" ... @"+headCommit.Node[0:10], "", wh.CanonURL+wh.Repository.AbsoluteURL+"/compare/"+headCommit.Node+".."+wh.Commits[0].Parents[0], "")

		anyOherPersonCommits := false
		for _, commit := range wh.Commits {
			if commit.Author != wh.User {
				anyOherPersonCommits = true
				break
			}
		}
		for _, commit := range wh.Commits {
			commits++
			if anyOherPersonCommits {
				text += m.Bold(commit.Author) + ": "
			}
			text += m.URL(commit.Message, wh.CanonURL+wh.Repository.AbsoluteURL+"commits/"+headCommit.Node[0:10]) + "\n"
		}

	} else if len(wh.Commits) == 1 {
		wp = c.WebPreview("Commit", "@"+headCommit.Node[0:10], "", wh.CanonURL+wh.Repository.AbsoluteURL+"commits/"+headCommit.Node[0:10], "")

		commit := &wh.Commits[0]
		if commit.Author != wh.User {
			text += m.Bold(commit.Author) + ": "
		}

		text += commit.Message + "\n"
	}

	if len(wh.Commits) > 0 {

		return msg.SetTextFmt("%s %s to %s/%s\n%s",
			m.Bold(wh.User),
			m.URL("pushed", wp),
			m.URL(wh.Repository.Name, wh.CanonURL+wh.Repository.AbsoluteURL),
			m.URL(headCommit.Branch, wh.CanonURL+wh.Repository.AbsoluteURL+"branch/"+headCommit.Branch),
			text).
			EnableHTML().
			Send()
	}
	return nil

}
Exemplo n.º 29
0
func mustBeAuthed(c *integram.Context) (bool, error) {

	provider := c.OAuthProvider()

	if !provider.IsSetup() {
		return false, c.NewMessage().SetText(fmt.Sprintf("To be able to use interactive replies in Telegram, first you need to add oauth application on your hosted Bitbucket instance (admin priveleges required): %s\nAdd application with any name(f.e. Telegram) and specify this *Redirect URI*: \n%s\n\nAfter you press *Submit* you will receive app info. First, send me the *Application Id*", c.ServiceBaseURL.String()+"/account/", provider.RedirectURL())).
			SetChat(c.User.ID).
			SetBackupChat(c.Chat.ID).
			EnableHTML().
			EnableForceReply().
			DisableWebPreview().
			SetReplyAction(hostedAppIDEntered, c.ServiceBaseURL.String()).Send()

	}
	if !c.User.OAuthValid() {
		if c.Callback != nil {
			c.AnswerCallbackQuery("You need to authorize me\nUse the \"Tap me to auth\" button", true)
		}
		if !c.User.IsPrivateStarted() && c.Callback != nil {
			kb := c.Callback.Message.InlineKeyboardMarkup
			kb.AddPMSwitchButton(c.Bot(), "👉  Tap me to auth", "auth")
			c.EditPressedInlineKeyboard(kb)
		} else {
			return false, c.NewMessage().SetTextFmt("You need to authorize me to use interactive replies: %s", c.User.OauthInitURL()).
				DisableWebPreview().
				SetChat(c.User.ID).SetBackupChat(c.Chat.ID).Send()
		}
	}

	return true, nil

}
Exemplo n.º 30
0
func oAuthSuccessful(c *integram.Context) error {
	return c.NewMessage().SetText("Great! Now you can reply issues, commits, merge requests and snippets").Send()
}