{"id":20677773,"url":"https://github.com/clivern/hamster","last_synced_at":"2025-04-19T21:06:55.341Z","repository":{"id":34665396,"uuid":"150013651","full_name":"Clivern/Hamster","owner":"Clivern","description":"🐀 A Bot toolkit for github that supports OAuth, Events, API, Custom Commands and Check Runs.","archived":false,"fork":false,"pushed_at":"2024-11-07T04:58:17.000Z","size":1599,"stargazers_count":44,"open_issues_count":10,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-07T05:33:11.364Z","etag":null,"topics":["bot","clivern","github","github-bot","github-client","go-lang","golang","hamster"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Clivern.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-09-23T18:33:43.000Z","updated_at":"2024-08-29T15:44:00.000Z","dependencies_parsed_at":"2023-02-10T12:31:49.128Z","dependency_job_id":"39cc023a-90e4-4671-8c24-fbe2bc9bfcc7","html_url":"https://github.com/Clivern/Hamster","commit_stats":null,"previous_names":[],"tags_count":7,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Clivern%2FHamster","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Clivern%2FHamster/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Clivern%2FHamster/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Clivern%2FHamster/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Clivern","download_url":"https://codeload.github.com/Clivern/Hamster/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224969892,"owners_count":17400294,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bot","clivern","github","github-bot","github-client","go-lang","golang","hamster"],"created_at":"2024-11-16T21:17:04.716Z","updated_at":"2024-11-16T21:17:05.306Z","avatar_url":"https://github.com/Clivern.png","language":"Go","readme":"\u003cp align=\"center\"\u003e\n    \u003cimg alt=\"Hamster Logo\" src=\"https://raw.githubusercontent.com/Clivern/Hamster/master/assets/img/logo.png\" height=\"80\" /\u003e\n    \u003ch3 align=\"center\"\u003eHamster\u003c/h3\u003e\n    \u003cp align=\"center\"\u003eA Bot Toolkit for Github!\u003c/p\u003e\n\u003c/p\u003e\n\n## Documentation\n\n### Config \u0026 Run The Application\n\nHamster uses [Go Modules](https://github.com/golang/go/wiki/Modules) to manage dependencies. First Create a dist config file.\n\n```bash\n$ cp config.json config.dist.json\n```\n\nThen add your `app_mode`, `app_port`, `app_log_level`, `github_token`, `github_webhook_secret`, `repository_author` and `repository_name`\n\n```json\n{\n    \"app_mode\": \"prod\",\n    \"app_port\": \"8080\",\n    \"app_log_level\": \"info\",\n    \"github_token\": \"...\",\n    \"github_webhook_secret\": \"...\",\n    \"repository_author\": \"Clivern\",\n    \"repository_name\": \"Hamster\",\n\n    \"app_domain\": \"example.com\",\n    \"github_app_client_id\": \"..\",\n    \"github_app_redirect_uri\": \"..\",\n    \"github_app_allow_signup\": \"true\",\n    \"github_app_scope\": \"..\",\n    \"github_app_client_secret\": \"..\"\n}\n```\n\nYou can config `app_domain` and the rest of github app configs `github_app_*` in case you need a github app not a personal bot.\n\nAdd a new webhook from `Settings \u003e Webhooks`, Set the `Payload URL` to be `https://hamster.com/listen`, `Content type` as `JSON` and Add Your Webhook Secret.\n\nAnd then run the application\n\n```bash\n$ go build hamster.go\n$ ./hamster\n\n// OR\n\n$ go run hamster.go\n```\n\nAlso running hamster with docker still an option. Just don't forget to update `GithubToken`, `GithubWebhookSecret`, `RepositoryAuthor` and `RepositoryName` inside `docker-compose.yml` file. Then run the following stuff\n\n```bash\n$ docker-compose build\n$ docker-compose up -d\n```\n\n### Customize the Default Event Listeners\n\nAnytime github call hamster listen endpoint, there will be a callback that get called with incoming data. For example when you get a status change call from github, the `StatusListener(status event.Status)` will get called. So do whatever you need inside this callback.\n\n**any event:** any time listen endpoint get a call, the following callback get called.\n\n```go\n// plugin/base.go\n\n// Any Action\nfunc RawListener(raw event.Raw) (bool, error) {\n    logger.Info(\"Raw event listener fired!\")\n    return true, nil\n}\n```\n\n**[status event:](https://developer.github.com/v3/activity/events/types/#statusevent)** any time a Repository has a status update from the API, The following callback get called.\n```go\n// plugin/base.go\n\n// Status Action\nfunc StatusListener(status event.Status) (bool, error) {\n    logger.Info(\"Status event listener fired!\")\n    return true, nil\n}\n```\n\n**[watch event:](https://developer.github.com/v3/activity/events/types/#watchevent)** any time a User stars a Repository.\n```go\n// plugin/base.go\n\n// Watch Action\nfunc WatchListener(watch event.Watch) (bool, error) {\n    logger.Info(\"Watch event listener fired!\")\n    return true, nil\n}\n```\n\n**[issues event:](https://developer.github.com/v3/activity/events/types/#issuesevent)** any time an Issue is assigned, unassigned, labeled, unlabeled, opened, edited, milestoned, demilestoned, closed, or reopened.\n```go\n// plugin/base.go\n\n// Issue Action\nfunc IssuesListener(issues event.Issues) (bool, error) {\n    logger.Info(\"Issues event listener fired!\")\n    return true, nil\n}\n```\n\n**[issue_comment event:](https://developer.github.com/v3/activity/events/types/#issuecommentevent)** any time a comment on an issue is created, edited, or deleted.\n```go\n// plugin/base.go\n\n// Issue Comment Action\nfunc IssueCommentListener(issueComment event.IssueComment) (bool, error) {\n    logger.Info(\"IssueComment event listener fired!\")\n    return true, nil\n}\n```\n\n**[push event:](https://developer.github.com/v3/activity/events/types/#pushevent)** Any Git push to a Repository, including editing tags or branches. Commits via API actions that update references are also counted. This is the default event.\n```go\n// plugin/base.go\n\n// Push Action\nfunc PushListener(push event.Push) (bool, error) {\n    logger.Info(\"Push event listener fired!\")\n    return true, nil\n}\n```\n\n**[create event:](https://developer.github.com/v3/activity/events/types/#createevent)** Any time a Branch or Tag is created.\n\n```go\n// plugin/base.go\n\n// Create Action\nfunc CreateListener(create event.Create) (bool, error) {\n    logger.Info(\"Create event listener fired!\")\n    return true, nil\n}\n```\n\n**[label event:](https://developer.github.com/v3/activity/events/types/#labelevent)** Any time a Label is created, edited, or deleted.\n\n```go\n// plugin/base.go\n\n// Label Action\nfunc LabelListener(label event.Label) (bool, error) {\n    logger.Info(\"Label event listener fired!\")\n    return true, nil\n}\n```\n\n**[delete event:](https://developer.github.com/v3/activity/events/types/#deleteevent)** Any time a branch or tag is deleted.\n\n```go\n// plugin/base.go\n\n// Delete Action\nfunc DeleteListener(delete event.Delete) (bool, error) {\n    logger.Info(\"Delete event listener fired!\")\n    return true, nil\n}\n```\n\n**[milestone event:](https://developer.github.com/v3/activity/events/types/#milestoneevent)** Any time a Milestone is created, closed, opened, edited, or deleted.\n\n```go\n// plugin/base.go\n\n// Milestone Action\nfunc MilestoneListener(milestone event.Milestone) (bool, error) {\n    logger.Info(\"Milestone event listener fired!\")\n    return true, nil\n}\n```\n\n**[pull_request event:](https://developer.github.com/v3/activity/events/types/#pullrequestevent)** Any time a pull request is assigned, unassigned, labeled, unlabeled, opened, edited, closed, reopened, or synchronized (updated due to a new push in the branch that the pull request is tracking). Also any time a pull request review is requested, or a review request is removed.\n\n```go\n// plugin/base.go\n\n// Pull Request Action\nfunc PullRequestListener(pullRequest event.PullRequest) (bool, error) {\n    logger.Info(\"PullRequest event listener fired!\")\n    return true, nil\n}\n```\n\n**[pull_request_review event:](https://developer.github.com/v3/activity/events/types/#pullrequestreviewevent)** Any time a pull request review is submitted, edited, or dismissed.\n\n```go\n// plugin/base.go\n\n// Pull Request Review Action\nfunc PullRequestReviewListener(pullRequestReview event.PullRequestReview) (bool, error) {\n    logger.Info(\"PullRequestReview event listener fired!\")\n    return true, nil\n}\n```\n\n**[pull_request_review_comment event:](https://developer.github.com/v3/activity/events/types/#pullrequestreviewcommentevent)** Any time a comment on a pull request's unified diff is created, edited, or deleted (in the Files Changed tab).\n\n```go\n// plugin/base.go\n\n// Pull Request Review Comment Action\nfunc PullRequestReviewCommentListener(pullRequestReviewComment event.PullRequestReviewComment) (bool, error) {\n    logger.Info(\"PullRequestReviewComment event listener fired!\")\n    return true, nil\n}\n```\n\nAll current supported events and the future events will be available on `plugin/base.go`. Also it is handy to add aditional callbacks so each event can have any number of callbacks.\n\nAlso please check [the latest github webhooks guide](https://developer.github.com/webhooks/).\n\n\n### Build Custom Commands\n\nIn order to build an interactive bot, you will need to listen to a pre-defined commands that once your repo users type on an issue or a comment, your application get notified. Github don't support this by default but it is still possible to achieve this manually.\n\nFirst you need to define you command and the callback on `internal/app/controller/listener.go`, exactly like the `test` command:\n\n```go\n// The default test command for issue comments\ncommands.RegisterIssueCommentAction(\"test\", plugin.IssueCommentTestCommandListener)\n\n//The new run command for issue comments\ncommands.RegisterIssueCommentAction(\"run\", plugin.IssueCommentRunCommandListener)\n```\n\n```go\n// The default test command for issues\ncommands.RegisterIssuesAction(\"test\", plugin.IssuesTestCommandListener)\n\n//The new run command for issues\ncommands.RegisterIssuesAction(\"run\", plugin.IssuesRunCommandListener)\n```\n\nThen define the callbacks on `plugin/base.go` same as `test` commands callbacks:\n\n```go\n// Test Command Callbacks\n// Test Command Listener for Issues\nfunc IssuesTestCommandListener(command event.Command, issues event.Issues) (bool, error) {\n    logger.Info(\"IssuesTestCommandListener event listener fired!\")\n    return true, nil\n}\n\n// Test Command Listener for Issues Comments\nfunc IssueCommentTestCommandListener(command event.Command, issue_comment event.IssueComment) (bool, error) {\n    logger.Info(\"IssueCommentTestCommandListener event listener fired!\")\n    return true, nil\n}\n\n// Run Command Callbacks\n// Run Command Listener for Issues\nfunc IssuesRunCommandListener(command event.Command, issues event.Issues) (bool, error) {\n    logger.Info(\"IssuesTestCommandListener event listener fired!\")\n    return true, nil\n}\n\n// Run Command Listener for Issues Comments\nfunc IssueCommentRunCommandListener(command event.Command, issue_comment event.IssueComment) (bool, error) {\n    logger.Info(\"IssueCommentTestCommandListener event listener fired!\")\n    return true, nil\n}\n```\n\nNow if you create a new issue or issue comment, the related callbacks will get notified with command object:\n\n```go\n/test\n/test{option1}\n/test{option1,option2}\n/test{option1,option2,option3}\n\n/run\n/run{option1}\n/run{option1,option2}\n/run{option1,option2,option3}\n\nThe command object will be\n\nevent.Command{Name=test, Parameters=[]}\nevent.Command{Name=test, Parameters=[option1]}\nevent.Command{Name=test, Parameters=[option1 option2]}\nevent.Command{Name=test, Parameters=[option1 option2 option3]}\n\nevent.Command{Name=run, Parameters=[]}\nevent.Command{Name=run, Parameters=[option1]}\nevent.Command{Name=run, Parameters=[option1 option2]}\nevent.Command{Name=run, Parameters=[option1 option2 option3]}\n```\n\n### Create a Github Comment\n\n```go\n// for more info https://developer.github.com/v3/issues/comments/#create-a-comment\n\nimport (\n    \"github.com/clivern/hamster/internal/app/pkg/github\"\n    \"os\"\n)\n\n\ngithub_api := \u0026github.API{\n    Token: os.Getenv(\"GithubToken\"),\n    Author: os.Getenv(\"RepositoryAuthor\"),\n    Repository: os.Getenv(\"RepositoryName\"),\n}\n\n// Replace Message with the message and 1 with the issue id\ncreated_comment, err := github_api.NewComment(\"Message\", 1)\n\nif err == nil {\n    // created_comment.ID\n    // check github.com/clivern/hamster/internal/app/response/created_comment.CreatedComment for available data\n}else{\n    // err.Error()\n}\n```\n\n### Create a Label\n\n```go\n// for more info https://developer.github.com/v3/issues/labels/#create-a-label\n\nimport (\n    \"github.com/clivern/hamster/internal/app/pkg/github\"\n    \"os\"\n)\n\n\ngithub_api := \u0026github.API{\n    Token: os.Getenv(\"GithubToken\"),\n    Author: os.Getenv(\"RepositoryAuthor\"),\n    Repository: os.Getenv(\"RepositoryName\"),\n}\n\n// Get Repository label with name\n// github_api.CreateLabel (name string, color string) (response.Label, error)\nlabel, err := github_api.CreateLabel(\"Bug\", \"f29513\")\n\nif err == nil {\n    // label of type response.Label\n}else{\n    // err.Error()\n}\n```\n\n### Get a Label\n\n```go\n// for more info https://developer.github.com/v3/issues/labels/#get-a-single-label\n\nimport (\n    \"github.com/clivern/hamster/internal/app/pkg/github\"\n    \"os\"\n)\n\n\ngithub_api := \u0026github.API{\n    Token: os.Getenv(\"GithubToken\"),\n    Author: os.Getenv(\"RepositoryAuthor\"),\n    Repository: os.Getenv(\"RepositoryName\"),\n}\n\n// Get Repository label with name\n// github_api.GetLabel (name string) (response.Label, error)\nlabel, err := github_api.GetLabel(\"Bug\")\n\nif err == nil {\n    // label of type response.Label\n}else{\n    // err.Error()\n}\n```\n\n### Update a Label with Name\n\n```go\n// for more info https://developer.github.com/v3/issues/labels/#update-a-label\n\nimport (\n    \"github.com/clivern/hamster/internal/app/pkg/github\"\n    \"os\"\n)\n\n\ngithub_api := \u0026github.API{\n    Token: os.Getenv(\"GithubToken\"),\n    Author: os.Getenv(\"RepositoryAuthor\"),\n    Repository: os.Getenv(\"RepositoryName\"),\n}\n\n// Update label name and color\n// github_api.UpdateLabel (currentName string, name string, color string) (response.Label, error)\nlabel, err := github_api.UpdateLabel(\"CurrentName\", \"NewName\", \"b01f26\")\n\nif err == nil {\n    // label of type response.Label\n}else{\n    // err.Error()\n}\n```\n\n### Delete a Label with Name\n\n```go\n// for more info https://developer.github.com/v3/issues/labels/#delete-a-label\n\nimport (\n    \"github.com/clivern/hamster/internal/app/pkg/github\"\n    \"os\"\n)\n\n\ngithub_api := \u0026github.API{\n    Token: os.Getenv(\"GithubToken\"),\n    Author: os.Getenv(\"RepositoryAuthor\"),\n    Repository: os.Getenv(\"RepositoryName\"),\n}\n\n// Delete label with name\n// github_api.DeleteLabel (name string) (bool, error)\nok, err := github_api.DeleteLabel(\"CurrentName\")\n\nif ok \u0026\u0026 err == nil {\n    // label deleted\n}else{\n    // err.Error()\n}\n```\n\n### Get Repository Labels List\n\n```go\n// for more info https://developer.github.com/v3/issues/labels/#list-all-labels-for-this-repository\n\nimport (\n    \"github.com/clivern/hamster/internal/app/pkg/github\"\n    \"os\"\n)\n\n\ngithub_api := \u0026github.API{\n    Token: os.Getenv(\"GithubToken\"),\n    Author: os.Getenv(\"RepositoryAuthor\"),\n    Repository: os.Getenv(\"RepositoryName\"),\n}\n\n// Get Repository labels\n// github_api.GetRepositoryLabels () ([]response.Label, error)\nlabels, err := github_api.GetRepositoryLabels()\n\nif err == nil {\n    // labels of type []response.Label\n}else{\n    // err.Error()\n}\n```\n\n### Get Issue Labels List\n\n```go\n// for more info https://developer.github.com/v3/issues/labels/#list-labels-on-an-issue\n\nimport (\n    \"github.com/clivern/hamster/internal/app/pkg/github\"\n    \"os\"\n)\n\n\ngithub_api := \u0026github.API{\n    Token: os.Getenv(\"GithubToken\"),\n    Author: os.Getenv(\"RepositoryAuthor\"),\n    Repository: os.Getenv(\"RepositoryName\"),\n}\n\n// Get Repository issue labels with issue_id\n// github_api.GetRepositoryIssueLabels (issueId int) ([]response.Label, error)\nlabels, err := github_api.GetRepositoryIssueLabels(9)\n\nif err == nil {\n    // labels of type []response.Label\n}else{\n    // err.Error()\n}\n```\n\n### Remove Label from an Issue\n\n```go\n// for more info https://developer.github.com/v3/issues/labels/#remove-a-label-from-an-issue\n\nimport (\n    \"github.com/clivern/hamster/internal/app/pkg/github\"\n    \"os\"\n)\n\n\ngithub_api := \u0026github.API{\n    Token: os.Getenv(\"GithubToken\"),\n    Author: os.Getenv(\"RepositoryAuthor\"),\n    Repository: os.Getenv(\"RepositoryName\"),\n}\n\n// Remove a Label from an Issue\n// github_api.RemoveLabelFromIssue (issueId int, labelName string) (bool, error)\nok, err := github_api.RemoveLabelFromIssue(9, \"bug\")\n\nif ok \u0026\u0026 err == nil {\n    // Label Removed\n}else{\n    // err.Error()\n}\n```\n\n### Remove All Labels from an Issue\n\n```go\n// for more info https://developer.github.com/v3/issues/labels/#remove-all-labels-from-an-issue\n\nimport (\n    \"github.com/clivern/hamster/internal/app/pkg/github\"\n    \"os\"\n)\n\n\ngithub_api := \u0026github.API{\n    Token: os.Getenv(\"GithubToken\"),\n    Author: os.Getenv(\"RepositoryAuthor\"),\n    Repository: os.Getenv(\"RepositoryName\"),\n}\n\n// Remove a Label from an Issue\n// github_api.RemoveAllLabelForIssue (issueId int) (bool, error)\nok, err := github_api.RemoveAllLabelForIssue(9)\n\nif ok \u0026\u0026 err == nil {\n    // All Labels Removed\n}else{\n    // err.Error()\n}\n```\n\n### Get Milestone Labels List\n\n```go\n// for more info https://developer.github.com/v3/issues/labels/#get-labels-for-every-issue-in-a-milestone\n\nimport (\n    \"github.com/clivern/hamster/internal/app/pkg/github\"\n    \"os\"\n)\n\n\ngithub_api := \u0026github.API{\n    Token: os.Getenv(\"GithubToken\"),\n    Author: os.Getenv(\"RepositoryAuthor\"),\n    Repository: os.Getenv(\"RepositoryName\"),\n}\n\n// Get Milestone Labels List\n// github_api.GetRepositoryMilestoneLabels (milestoneId int) ([]response.Label, error)\nlabels, err := github_api.GetRepositoryMilestoneLabels(9)\n\nif err == nil {\n    // labels of type []response.Label\n}else{\n    // err.Error()\n}\n```\n\n### Add Labels to an Issue\n\n```go\n// for more info https://developer.github.com/v3/issues/labels/#add-labels-to-an-issue\n\nimport (\n    \"github.com/clivern/hamster/internal/app/pkg/github\"\n    \"os\"\n)\n\n\ngithub_api := \u0026github.API{\n    Token: os.Getenv(\"GithubToken\"),\n    Author: os.Getenv(\"RepositoryAuthor\"),\n    Repository: os.Getenv(\"RepositoryName\"),\n}\n\n// Add Labels to an Issue\n// github_api.AddLabelsToIssue (issueId int, labels []string) ([]response.Label, error)\nlabels, err := github_api.AddLabelsToIssue(9, []string{\"new-label\", \"another-label\"})\n\nif err == nil {\n    // labels of type []response.Label\n}else{\n    // err.Error()\n}\n```\n\n### Replace all Labels for an Issue\n\n```go\n// for more info https://developer.github.com/v3/issues/labels/#replace-all-labels-for-an-issue\n\nimport (\n    \"github.com/clivern/hamster/internal/app/pkg/github\"\n    \"os\"\n)\n\n\ngithub_api := \u0026github.API{\n    Token: os.Getenv(\"GithubToken\"),\n    Author: os.Getenv(\"RepositoryAuthor\"),\n    Repository: os.Getenv(\"RepositoryName\"),\n}\n\n// Replace all Labels for an Issue\n// github_api.ReplaceAllLabelsForIssue (issueId int, labels []string) ([]response.Label, error)\nlabels, err := github_api.ReplaceAllLabelsForIssue(9, []string{\"new-label\", \"another-label\"})\n\nif err == nil {\n    // labels of type []response.Label\n}else{\n    // err.Error()\n}\n```\n\n\n### Get PR Labels List\n\n```go\n// for more info https://developer.github.com/v3/issues/labels/#list-labels-on-an-issue\n\nimport (\n    \"github.com/clivern/hamster/internal/app/pkg/github\"\n    \"os\"\n)\n\n\ngithub_api := \u0026github.API{\n    Token: os.Getenv(\"GithubToken\"),\n    Author: os.Getenv(\"RepositoryAuthor\"),\n    Repository: os.Getenv(\"RepositoryName\"),\n}\n\n// Get Repository PR labels with PRId\n// github_api.GetRepositoryPRLabels (PRId int) ([]response.Label, error)\nlabels, err := github_api.GetRepositoryPRLabels(9)\n\nif err == nil {\n    // labels of type []response.Label\n}else{\n    // err.Error()\n}\n```\n\n### Remove Label from PR\n\n```go\n// for more info https://developer.github.com/v3/issues/labels/#remove-a-label-from-an-issue\n\nimport (\n    \"github.com/clivern/hamster/internal/app/pkg/github\"\n    \"os\"\n)\n\n\ngithub_api := \u0026github.API{\n    Token: os.Getenv(\"GithubToken\"),\n    Author: os.Getenv(\"RepositoryAuthor\"),\n    Repository: os.Getenv(\"RepositoryName\"),\n}\n\n// Remove a Label from PR\n// github_api.RemoveLabelFromPR (PRId int, labelName string) (bool, error)\nok, err := github_api.RemoveLabelFromPR(9, \"bug\")\n\nif ok \u0026\u0026 err == nil {\n    // Label Removed\n}else{\n    // err.Error()\n}\n```\n\n### Remove All Labels from PR\n\n```go\n// for more info https://developer.github.com/v3/issues/labels/#remove-all-labels-from-an-issue\n\nimport (\n    \"github.com/clivern/hamster/internal/app/pkg/github\"\n    \"os\"\n)\n\n\ngithub_api := \u0026github.API{\n    Token: os.Getenv(\"GithubToken\"),\n    Author: os.Getenv(\"RepositoryAuthor\"),\n    Repository: os.Getenv(\"RepositoryName\"),\n}\n\n// Remove a Label from PR\n// github_api.RemoveAllLabelForPR (PRId int) (bool, error)\nok, err := github_api.RemoveAllLabelForPR(9)\n\nif ok \u0026\u0026 err == nil {\n    // All Labels Removed\n}else{\n    // err.Error()\n}\n```\n\n### Add Labels to PR\n\n```go\n// for more info https://developer.github.com/v3/issues/labels/#add-labels-to-an-issue\n\nimport (\n    \"github.com/clivern/hamster/internal/app/pkg/github\"\n    \"os\"\n)\n\n\ngithub_api := \u0026github.API{\n    Token: os.Getenv(\"GithubToken\"),\n    Author: os.Getenv(\"RepositoryAuthor\"),\n    Repository: os.Getenv(\"RepositoryName\"),\n}\n\n// Add Labels to PR\n// github_api.AddLabelsToPR (PRId int, labels []string) ([]response.Label, error)\nlabels, err := github_api.AddLabelsToPR(9, []string{\"new-label\", \"another-label\"})\n\nif err == nil {\n    // labels of type []response.Label\n}else{\n    // err.Error()\n}\n```\n\n### Replace all Labels for PR\n\n```go\n// for more info https://developer.github.com/v3/issues/labels/#replace-all-labels-for-an-issue\n\nimport (\n    \"github.com/clivern/hamster/internal/app/pkg/github\"\n    \"os\"\n)\n\n\ngithub_api := \u0026github.API{\n    Token: os.Getenv(\"GithubToken\"),\n    Author: os.Getenv(\"RepositoryAuthor\"),\n    Repository: os.Getenv(\"RepositoryName\"),\n}\n\n// Replace all Labels for PR\n// github_api.ReplaceAllLabelsForPR (PRId int, labels []string) ([]response.Label, error)\nlabels, err := github_api.ReplaceAllLabelsForPR(9, []string{\"new-label\", \"another-label\"})\n\nif err == nil {\n    // labels of type []response.Label\n}else{\n    // err.Error()\n}\n```\n\n### Authorizing OAuth Apps\n\nYou can enable other users to authorize your OAuth App. First configure the app credentials on `config.dist.json` or `docker-compose.yml`\n\n```\n// config.dist.json\n    \"app_domain\": \"example.com\",\n    \"github_app_client_id\": \"..\",\n    \"github_app_redirect_uri\": \"..\",\n    \"github_app_allow_signup\": \"false\",\n    \"github_app_scope\": \"\", // It can be empty\n    \"github_app_client_secret\": \"..\"\n```\n```\n// docker-compose.yml\n     - GithubAppClientID=ValueHere\n     - GithubAppRedirectURI=ValueHere\n     - GithubAppAllowSignup=true\n     - GithubAppScope= // It can be empty\n     - GithubAppClientSecret=ValueHere\n     - AppDomain=example.com\n```\n\nThe github app should configured to use `http://example.com/auth` as redirect URL.\n\nIf you run the application, the authorize URL on `/login` page should be something like that:\n```\nhttps://github.com/login/oauth/authorize?allow_signup=true\u0026client_id=Iv1.eda..\u0026redirect_uri=https%3A%2F%2F3fa8b997.ngrok.io%2Fauth\u0026scope=\u0026state=5a0a8c973e93ed82820f7896dddb1df70a3dce62\n```\n\nIf you click authorize and authorized the app, github will send you back to hamster `/auth` route with a code and the state. Hamster will use that code to fetch the `accessToken` for you or any user. You can use the `accessToken` to do all subsequent github API Calls.\n\n### Github Check Runs\n\nTo create a status check:\n\n```go\n\nimport (\n    \"github.com/clivern/hamster/internal/app/response\"\n    \"github.com/clivern/hamster/internal/app/sender\"\n    \"github.com/clivern/hamster/internal/app/pkg/github\"\n\n    \"os\"\n    \"time\"\n    \"fmt\"\n)\n\noutput := sender.Output{\n    Title: \"CI Report\",\n    Summary: \"Output Summary\",\n    Text: \"Some Text Goes Here\",\n}\n\ncheckRun := sender.CheckRun{\n    Name: \"CI Status\",\n    HeadSha: \"6c46684560f9fed86be6fd87f9dbaa91e4b242c9\",\n    Status: \"in_progress\",\n    DetailsURL: \"http://clivern.com/ci/5\",\n    ExternalID: \"43\",\n    StartedAt: time.Now().UTC().Format(time.RFC3339),\n    Output: output,\n}\n\nvar checkRunResponse response.CheckRun\n\ngithub_api := \u0026github.API{\n    Token: \"5688665c9184800e...\", # Token via a GitHub App.\n    Author: os.Getenv(\"RepositoryAuthor\"),\n    Repository: os.Getenv(\"RepositoryName\"),\n}\n\n// method CreateCheckRun(CheckRun sender.CheckRun) (response.CheckRun, error)\ncheckRunResponse, err := github_api.CreateCheckRun(checkRun)\n\nif err == nil{\n    fmt.Println(checkRunResponse.ID)\n}else{\n    fmt.Println(err.Error())\n}\n```\n\nTo update a status check:\n\n```go\nimport (\n    \"github.com/clivern/hamster/internal/app/response\"\n    \"github.com/clivern/hamster/internal/app/sender\"\n    \"github.com/clivern/hamster/internal/app/pkg/github\"\n\n    \"os\"\n    \"time\"\n    \"fmt\"\n)\n\noutput := sender.Output{\n    Title: \"CI Report\",\n    Summary: \"Final Output Summary\",\n    Text: \"Some Final Text Goes Here\",\n}\n\ncheckRun := sender.CheckRun{\n    Name: \"CI Status\",\n    HeadSha: \"6c46684560f9fed86be6fd87f9dbaa91e4b242c9\",\n    Status: \"completed\",\n    DetailsURL: \"http://clivern.com/ci/5\",\n    ExternalID: \"43\",\n    CompletedAt: time.Now().UTC().Format(time.RFC3339),\n    Conclusion: \"success\",\n    Output: output,\n}\n\nvar checkRunResponse response.CheckRun\n\ngithub_api := \u0026github.API{\n    Token: \"5688665c9184800e...\", // Token via a GitHub App.\n    Author: os.Getenv(\"RepositoryAuthor\"),\n    Repository: os.Getenv(\"RepositoryName\"),\n}\n\n// method UpdateCheckRun(ID int, CheckRun sender.CheckRun) (response.CheckRun, error)\ncheckRunResponse, err := github_api.UpdateCheckRun(25165135, checkRun)\n\nif err == nil{\n    fmt.Println(checkRunResponse.ID)\n}else{\n    fmt.Println(err.Error())\n}\n```\n\nTo get a status check with ID:\n\n```go\nimport (\n    \"github.com/clivern/hamster/internal/app/response\"\n    \"github.com/clivern/hamster/internal/app/pkg/github\"\n\n    \"os\"\n    \"fmt\"\n)\n\nvar checkRunResponse response.CheckRun\n\ngithub_api := \u0026github.API{\n    Token: \"5688665c9184800e...\", // Token via a GitHub App.\n    Author: os.Getenv(\"RepositoryAuthor\"),\n    Repository: os.Getenv(\"RepositoryName\"),\n}\n\ncheckRunResponse, err := github_api.GetCheckRun(25165135)\n\nif err == nil{\n    fmt.Println(checkRunResponse.ID)\n}else{\n    fmt.Println(err.Error())\n}\n```\n\n### Logging\n\nWe use [google/logger](https://github.com/google/logger) under the hood, make use of it or use these simple functions:\n\n```go\nimport (\n    \"github.com/clivern/hamster/internal/app/pkg/logger\"\n)\n\nlogger.Info(\"Info Goes Here!\")\nlogger.Infoln(\"Infoln Goes Here!\")\nlogger.Infof(\"Infof %s Here!\", \"Goes\")\n\nlogger.Warning(\"Warning Goes Here!\")\nlogger.Warningln(\"Warningln Goes Here!\")\nlogger.Warningf(\"Warningf %s Here!\", \"Goes\")\n\nlogger.Error(\"Error Goes Here!\")\nlogger.Errorln(\"Errorln Goes Here!\")\nlogger.Errorf(\"Errorf %s Here!\", \"Goes\")\n\nlogger.Fatal(\"Fatal Goes Here!\")\nlogger.Fatalln(\"Fatalln Goes Here!\")\nlogger.Fatalf(\"Fatalf %s Here!\", \"Goes\")\n```\n\n\n## Badges\n\n[![Build Status](https://travis-ci.org/Clivern/Hamster.svg?branch=master)](https://travis-ci.org/Clivern/Hamster)\n[![GitHub license](https://img.shields.io/github/license/Clivern/Hamster.svg)](https://github.com/Clivern/Hamster/blob/master/LICENSE)\n[![Version](https://img.shields.io/badge/Version-3.1.0-red.svg)](https://github.com/Clivern/Hamster/releases)\n[![Go Report Card](https://goreportcard.com/badge/github.com/Clivern/Hamster)](https://goreportcard.com/report/github.com/Clivern/Hamster)\n\n\n## Changelog\n\n* Version 3.1.0:\n```\nSwitch to go 1.11 modules.\n```\n\n* Version 3.0.1:\n```\nFix ineffassign for some vars.\n```\n\n* Version 3.0.0:\n```\nMore Enhancements.\n```\n\n* Version 2.0.0:\n```\nAdd More Events.\nAdd Labels \u0026 Comments API to Github pkg.\nCustom Commands.\nOAuth Apps Support.\nCheck Runs Support.\n```\n\n* Version 1.1.1:\n```\nAdd Logger Package.\n```\n\n* Version 1.1.0:\n```\nAdd new events watch, issues and issue_comment.\nFix dockerfile \u0026 docker-compose.\n```\n\n* Version 1.0.0:\n```\nInitial Release.\n```\n\n\n## Acknowledgements\n\n© 2018, Clivern. Released under [MIT License](https://opensource.org/licenses/mit-license.php).\n\n**Hamster** is authored and maintained by [@clivern](http://github.com/clivern).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclivern%2Fhamster","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclivern%2Fhamster","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclivern%2Fhamster/lists"}