{"action":"created","comment":{"url":"https://api.github.com/repos/nyaruka/courier/pulls/comments/168837345","pull_request_review_id":97275288,"id":168837345,"diff_hunk":"@@ -1,8 +1,192 @@\n package highconnection\n \n+import (\n+\t\"context\"\n+\t\"fmt\"\n+\t\"net/http\"\n+\t\"net/url\"\n+\t\"time\"\n+\n+\t\"github.com/nyaruka/courier\"\n+\t\"github.com/nyaruka/courier/handlers\"\n+\t\"github.com/nyaruka/courier/utils\"\n+\t\"github.com/nyaruka/gocommon/urns\"\n+)\n+\n /*\n GET /handlers/hcnx/status/uuid?push_id=1164711372&status=6&to=%2B33611441111&ret_id=19128317&text=Msg\n \n POST /handlers/hcnx/receive/uuid?FROM=+33644961111\n ID=1164708294&FROM=%2B33644961111&TO=36105&MESSAGE=Msg&VALIDITY_DATE=2017-05-03T21%3A13%3A13&GET_STATUS=0&CLIENT=LEANCONTACTFAST&CLASS_TYPE=0&RECEPTION_DATE=2017-05-02T21%3A13%3A13&TO_OP_ID=20810&INITIAL_OP_ID=20810&STATUS=POSTING_30179_1410&EMAIL=&BINARY=0&PARAM=%7C%7C%7C%7CP223%2F03%2F03&USER_DATA=LEANCONTACTFAST&USER_DATA_2=jours+pas+r%E9gl%E9&BULK_ID=0&MO_ID=0&APPLICATION_ID=0&ACCOUNT_ID=39&GW_MESSAGE_ID=0&READ_STATUS=0&TARIFF=0&REQUEST_ID=33609002123&TAC=%28null%29&REASON=2017-05-02+23%3A13%3A13&FORMAT=&MVNO=&ORIG_ID=1164708215&ORIG_MESSAGE=Msg&RET_ID=123456&ORIG_DATE=2017-05-02T21%3A11%3A44\n */\n+\n+var sendURL = \"https://highpushfastapi-v2.hcnx.eu/api\"\n+var maxMsgLength = 1500\n+\n+func init() {\n+\tcourier.RegisterHandler(newHandler())\n+}\n+\n+type handler struct {\n+\thandlers.BaseHandler\n+}\n+\n+func newHandler() courier.ChannelHandler {\n+\treturn &handler{handlers.NewBaseHandler(courier.ChannelType(\"HX\"), \"High Connection\")}\n+}\n+\n+// Initialize is called by the engine once everything is loaded\n+func (h *handler) Initialize(s courier.Server) error {\n+\th.SetServer(s)\n+\terr := s.AddHandlerRoute(h, http.MethodGet, \"receive\", h.ReceiveMessage)\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\terr = s.AddHandlerRoute(h, http.MethodPost, \"receive\", h.ReceiveMessage)\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\n+\terr = s.AddHandlerRoute(h, http.MethodPost, \"status\", h.StatusMessage)\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\n+\treturn s.AddHandlerRoute(h, http.MethodGet, \"status\", h.StatusMessage)\n+\n+}\n+\n+type moMsg struct {\n+\tTo          string `name:\"TO\" validate:\"required\"`\n+\tFrom        string `name:\"FROM\" validate:\"required\"`\n+\tMessage     string `name:\"MESSAGE\" validate:\"required\"`\n+\tReceiveDate string `name:\"RECEPTION_DATE\"`\n+}\n+\n+// ReceiveMessage is our HTTP handler function for incoming messages\n+func (h *handler) ReceiveMessage(ctx context.Context, channel courier.Channel, w http.ResponseWriter, r *http.Request) ([]courier.Event, error) {\n+\thxRequest := &moMsg{}\n+\terr := handlers.DecodeAndValidateForm(hxRequest, r)\n+\tif err != nil {\n+\t\treturn nil, courier.WriteAndLogRequestError(ctx, w, r, channel, err)\n+\t}\n+\n+\tdate := time.Now()\n+\tif hxRequest.ReceiveDate != \"\" {\n+\t\tdate, err = time.Parse(\"2006-01-02T15:04:05\", hxRequest.ReceiveDate)\n+\t\tif err != nil {\n+\t\t\treturn nil, courier.WriteAndLogRequestError(ctx, w, r, channel, err)\n+\t\t}\n+\t}\n+\n+\t// create our URN\n+\turn := urns.NewTelURNForCountry(hxRequest.From, channel.Country())\n+\n+\t// build our infobipMessage\n+\tmsg := h.Backend().NewIncomingMsg(channel, urn, hxRequest.Message).WithReceivedOn(date.UTC())\n+\n+\t// and write it\n+\terr = h.Backend().WriteMsg(ctx, msg)\n+\tif err != nil {\n+\t\treturn nil, err\n+\t}\n+\treturn []courier.Event{msg}, courier.WriteMsgSuccess(ctx, w, r, []courier.Msg{msg})\n+\n+}\n+\n+type moStatus struct {\n+\tRetID  int64 `name:\"ret_id\" validate:\"required\"`\n+\tStatus int   `name:\"status\" validate:\"required\"`\n+}\n+\n+var statusMapping = map[int]courier.MsgStatusValue{\n+\t2:  courier.MsgFailed,\n+\t4:  courier.MsgSent,\n+\t6:  courier.MsgDelivered,\n+\t11: courier.MsgFailed,\n+\t12: courier.MsgFailed,\n+\t13: courier.MsgFailed,\n+\t14: courier.MsgFailed,\n+\t15: courier.MsgFailed,\n+\t16: courier.MsgFailed,\n+}\n+\n+// StatusMessage is our HTTP handler function for status updates\n+func (h *handler) StatusMessage(ctx context.Context, channel courier.Channel, w http.ResponseWriter, r *http.Request) ([]courier.Event, error) {\n+\thxRequest := &moStatus{}\n+\terr := handlers.DecodeAndValidateForm(hxRequest, r)\n+\tif err != nil {\n+\t\treturn nil, courier.WriteAndLogRequestError(ctx, w, r, channel, err)\n+\t}\n+\n+\tmsgStatus, found := statusMapping[hxRequest.Status]\n+\tif !found {\n+\t\treturn nil, fmt.Errorf(\"unknown status '%d', must be one of 2, 4, 6, 11, 12, 13, 14, 15  or 16\", hxRequest.Status)\n+\t}\n+\n+\t// write our status\n+\tstatus := h.Backend().NewMsgStatusForID(channel, courier.NewMsgID(hxRequest.RetID), msgStatus)\n+\terr = h.Backend().WriteMsgStatus(ctx, status)\n+\tif err == courier.ErrMsgNotFound {\n+\t\treturn nil, courier.WriteAndLogStatusMsgNotFound(ctx, w, r, channel)\n+\t}\n+\n+\tif err != nil {\n+\t\treturn nil, err\n+\t}\n+\n+\treturn []courier.Event{status}, courier.WriteStatusSuccess(ctx, w, r, []courier.MsgStatus{status})\n+\n+}\n+\n+// SendMsg sends the passed in message, returning any error\n+func (h *handler) SendMsg(ctx context.Context, msg courier.Msg) (courier.MsgStatus, error) {\n+\tusername := msg.Channel().StringConfigForKey(courier.ConfigUsername, \"\")\n+\tif username == \"\" {\n+\t\treturn nil, fmt.Errorf(\"no username set for HX channel\")\n+\t}\n+\n+\tpassword := msg.Channel().StringConfigForKey(courier.ConfigPassword, \"\")\n+\tif password == \"\" {\n+\t\treturn nil, fmt.Errorf(\"no password set for HX channel\")\n+\t}\n+\n+\tcallbackDomain := msg.Channel().CallbackDomain(h.Server().Config().Domain)\n+\tstatusURL := fmt.Sprintf(\"https://%s%s%s/status\", callbackDomain, \"/c/hx/\", msg.Channel().UUID())\n+\treceiveURL := fmt.Sprintf(\"https://%s%s%s/receive\", callbackDomain, \"/c/hx/\", msg.Channel().UUID())\n+\n+\tstatus := h.Backend().NewMsgStatusForID(msg.Channel(), msg.ID(), courier.MsgErrored)\n+\tparts := handlers.SplitMsg(handlers.GetTextAndAttachments(msg), maxMsgLength)\n+\tfor _, part := range parts {\n+\n+\t\tform := url.Values{\n+\t\t\t\"accountid\":  []string{username},\n+\t\t\t\"password\":   []string{password},\n+\t\t\t\"text\":       []string{part},\n+\t\t\t\"to\":         []string{msg.URN().Path()},\n+\t\t\t\"ret_id\":     []string{msg.ID().String()},\n+\t\t\t\"datacoding\": []string{\"8\"},\n+\t\t\t\"userdata\":   []string{\"textit\"},\n+\t\t\t\"ret_url\":    []string{statusURL},\n+\t\t\t\"ret_mo_url\": []string{receiveURL},\n+\t\t}\n+\n+\t\tmsgURL, _ := url.Parse(sendURL)\n+\t\tmsgURL.RawQuery = form.Encode()\n+\n+\t\treq, err := http.NewRequest(http.MethodPost, msgURL.String(), nil)","path":"handlers/highconnection/highconnection.go","position":177,"original_position":177,"commit_id":"b7071c5b4a6d73f41025c775b54706861a69533f","original_commit_id":"b7071c5b4a6d73f41025c775b54706861a69533f","user":{"login":"nicpottier","id":168067,"avatar_url":"https://avatars3.githubusercontent.com/u/168067?v=4","gravatar_id":"","url":"https://api.github.com/users/nicpottier","html_url":"https://github.com/nicpottier","followers_url":"https://api.github.com/users/nicpottier/followers","following_url":"https://api.github.com/users/nicpottier/following{/other_user}","gists_url":"https://api.github.com/users/nicpottier/gists{/gist_id}","starred_url":"https://api.github.com/users/nicpottier/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nicpottier/subscriptions","organizations_url":"https://api.github.com/users/nicpottier/orgs","repos_url":"https://api.github.com/users/nicpottier/repos","events_url":"https://api.github.com/users/nicpottier/events{/privacy}","received_events_url":"https://api.github.com/users/nicpottier/received_events","type":"User","site_admin":false},"body":"Should either check error or assign it to _","created_at":"2018-02-16T18:39:50Z","updated_at":"2018-02-16T18:46:00Z","html_url":"https://github.com/nyaruka/courier/pull/116#discussion_r168837345","pull_request_url":"https://api.github.com/repos/nyaruka/courier/pulls/116","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/nyaruka/courier/pulls/comments/168837345"},"html":{"href":"https://github.com/nyaruka/courier/pull/116#discussion_r168837345"},"pull_request":{"href":"https://api.github.com/repos/nyaruka/courier/pulls/116"}}},"pull_request":{"url":"https://api.github.com/repos/nyaruka/courier/pulls/116","id":169642519,"html_url":"https://github.com/nyaruka/courier/pull/116","diff_url":"https://github.com/nyaruka/courier/pull/116.diff","patch_url":"https://github.com/nyaruka/courier/pull/116.patch","issue_url":"https://api.github.com/repos/nyaruka/courier/issues/116","number":116,"state":"open","locked":false,"title":"Highconnection handlers","user":{"login":"norkans7","id":1040571,"avatar_url":"https://avatars0.githubusercontent.com/u/1040571?v=4","gravatar_id":"","url":"https://api.github.com/users/norkans7","html_url":"https://github.com/norkans7","followers_url":"https://api.github.com/users/norkans7/followers","following_url":"https://api.github.com/users/norkans7/following{/other_user}","gists_url":"https://api.github.com/users/norkans7/gists{/gist_id}","starred_url":"https://api.github.com/users/norkans7/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/norkans7/subscriptions","organizations_url":"https://api.github.com/users/norkans7/orgs","repos_url":"https://api.github.com/users/norkans7/repos","events_url":"https://api.github.com/users/norkans7/events{/privacy}","received_events_url":"https://api.github.com/users/norkans7/received_events","type":"User","site_admin":false},"body":"Fix #106 ","created_at":"2018-02-16T14:50:06Z","updated_at":"2018-02-16T18:46:01Z","closed_at":null,"merged_at":null,"merge_commit_sha":"056de2ae33ec6884c1b4ad93fc98e1bb34c4020b","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":800331470,"url":"https://api.github.com/repos/nyaruka/courier/labels/review","name":"review","color":"ededed","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/nyaruka/courier/pulls/116/commits","review_comments_url":"https://api.github.com/repos/nyaruka/courier/pulls/116/comments","review_comment_url":"https://api.github.com/repos/nyaruka/courier/pulls/comments{/number}","comments_url":"https://api.github.com/repos/nyaruka/courier/issues/116/comments","statuses_url":"https://api.github.com/repos/nyaruka/courier/statuses/b7071c5b4a6d73f41025c775b54706861a69533f","head":{"label":"nyaruka:highconnection-handlers","ref":"highconnection-handlers","sha":"b7071c5b4a6d73f41025c775b54706861a69533f","user":{"login":"nyaruka","id":299256,"avatar_url":"https://avatars0.githubusercontent.com/u/299256?v=4","gravatar_id":"","url":"https://api.github.com/users/nyaruka","html_url":"https://github.com/nyaruka","followers_url":"https://api.github.com/users/nyaruka/followers","following_url":"https://api.github.com/users/nyaruka/following{/other_user}","gists_url":"https://api.github.com/users/nyaruka/gists{/gist_id}","starred_url":"https://api.github.com/users/nyaruka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nyaruka/subscriptions","organizations_url":"https://api.github.com/users/nyaruka/orgs","repos_url":"https://api.github.com/users/nyaruka/repos","events_url":"https://api.github.com/users/nyaruka/events{/privacy}","received_events_url":"https://api.github.com/users/nyaruka/received_events","type":"Organization","site_admin":false},"repo":{"id":90886480,"name":"courier","full_name":"nyaruka/courier","owner":{"login":"nyaruka","id":299256,"avatar_url":"https://avatars0.githubusercontent.com/u/299256?v=4","gravatar_id":"","url":"https://api.github.com/users/nyaruka","html_url":"https://github.com/nyaruka","followers_url":"https://api.github.com/users/nyaruka/followers","following_url":"https://api.github.com/users/nyaruka/following{/other_user}","gists_url":"https://api.github.com/users/nyaruka/gists{/gist_id}","starred_url":"https://api.github.com/users/nyaruka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nyaruka/subscriptions","organizations_url":"https://api.github.com/users/nyaruka/orgs","repos_url":"https://api.github.com/users/nyaruka/repos","events_url":"https://api.github.com/users/nyaruka/events{/privacy}","received_events_url":"https://api.github.com/users/nyaruka/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/nyaruka/courier","description":"A fast, GoLang message receiver and sender for SMS and IP channels","fork":false,"url":"https://api.github.com/repos/nyaruka/courier","forks_url":"https://api.github.com/repos/nyaruka/courier/forks","keys_url":"https://api.github.com/repos/nyaruka/courier/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nyaruka/courier/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nyaruka/courier/teams","hooks_url":"https://api.github.com/repos/nyaruka/courier/hooks","issue_events_url":"https://api.github.com/repos/nyaruka/courier/issues/events{/number}","events_url":"https://api.github.com/repos/nyaruka/courier/events","assignees_url":"https://api.github.com/repos/nyaruka/courier/assignees{/user}","branches_url":"https://api.github.com/repos/nyaruka/courier/branches{/branch}","tags_url":"https://api.github.com/repos/nyaruka/courier/tags","blobs_url":"https://api.github.com/repos/nyaruka/courier/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nyaruka/courier/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nyaruka/courier/git/refs{/sha}","trees_url":"https://api.github.com/repos/nyaruka/courier/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nyaruka/courier/statuses/{sha}","languages_url":"https://api.github.com/repos/nyaruka/courier/languages","stargazers_url":"https://api.github.com/repos/nyaruka/courier/stargazers","contributors_url":"https://api.github.com/repos/nyaruka/courier/contributors","subscribers_url":"https://api.github.com/repos/nyaruka/courier/subscribers","subscription_url":"https://api.github.com/repos/nyaruka/courier/subscription","commits_url":"https://api.github.com/repos/nyaruka/courier/commits{/sha}","git_commits_url":"https://api.github.com/repos/nyaruka/courier/git/commits{/sha}","comments_url":"https://api.github.com/repos/nyaruka/courier/comments{/number}","issue_comment_url":"https://api.github.com/repos/nyaruka/courier/issues/comments{/number}","contents_url":"https://api.github.com/repos/nyaruka/courier/contents/{+path}","compare_url":"https://api.github.com/repos/nyaruka/courier/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nyaruka/courier/merges","archive_url":"https://api.github.com/repos/nyaruka/courier/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nyaruka/courier/downloads","issues_url":"https://api.github.com/repos/nyaruka/courier/issues{/number}","pulls_url":"https://api.github.com/repos/nyaruka/courier/pulls{/number}","milestones_url":"https://api.github.com/repos/nyaruka/courier/milestones{/number}","notifications_url":"https://api.github.com/repos/nyaruka/courier/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nyaruka/courier/labels{/name}","releases_url":"https://api.github.com/repos/nyaruka/courier/releases{/id}","deployments_url":"https://api.github.com/repos/nyaruka/courier/deployments","created_at":"2017-05-10T16:38:44Z","updated_at":"2018-02-06T01:10:46Z","pushed_at":"2018-02-16T18:33:06Z","git_url":"git://github.com/nyaruka/courier.git","ssh_url":"git@github.com:nyaruka/courier.git","clone_url":"https://github.com/nyaruka/courier.git","svn_url":"https://github.com/nyaruka/courier","homepage":null,"size":4359,"stargazers_count":30,"watchers_count":30,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":7,"mirror_url":null,"archived":false,"open_issues_count":16,"license":{"key":"agpl-3.0","name":"GNU Affero General Public License v3.0","spdx_id":"AGPL-3.0","url":"https://api.github.com/licenses/agpl-3.0"},"forks":7,"open_issues":16,"watchers":30,"default_branch":"master"}},"base":{"label":"nyaruka:master","ref":"master","sha":"f68e4f20e5ea9f5a5a878b01fad095c12a6824fc","user":{"login":"nyaruka","id":299256,"avatar_url":"https://avatars0.githubusercontent.com/u/299256?v=4","gravatar_id":"","url":"https://api.github.com/users/nyaruka","html_url":"https://github.com/nyaruka","followers_url":"https://api.github.com/users/nyaruka/followers","following_url":"https://api.github.com/users/nyaruka/following{/other_user}","gists_url":"https://api.github.com/users/nyaruka/gists{/gist_id}","starred_url":"https://api.github.com/users/nyaruka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nyaruka/subscriptions","organizations_url":"https://api.github.com/users/nyaruka/orgs","repos_url":"https://api.github.com/users/nyaruka/repos","events_url":"https://api.github.com/users/nyaruka/events{/privacy}","received_events_url":"https://api.github.com/users/nyaruka/received_events","type":"Organization","site_admin":false},"repo":{"id":90886480,"name":"courier","full_name":"nyaruka/courier","owner":{"login":"nyaruka","id":299256,"avatar_url":"https://avatars0.githubusercontent.com/u/299256?v=4","gravatar_id":"","url":"https://api.github.com/users/nyaruka","html_url":"https://github.com/nyaruka","followers_url":"https://api.github.com/users/nyaruka/followers","following_url":"https://api.github.com/users/nyaruka/following{/other_user}","gists_url":"https://api.github.com/users/nyaruka/gists{/gist_id}","starred_url":"https://api.github.com/users/nyaruka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nyaruka/subscriptions","organizations_url":"https://api.github.com/users/nyaruka/orgs","repos_url":"https://api.github.com/users/nyaruka/repos","events_url":"https://api.github.com/users/nyaruka/events{/privacy}","received_events_url":"https://api.github.com/users/nyaruka/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/nyaruka/courier","description":"A fast, GoLang message receiver and sender for SMS and IP channels","fork":false,"url":"https://api.github.com/repos/nyaruka/courier","forks_url":"https://api.github.com/repos/nyaruka/courier/forks","keys_url":"https://api.github.com/repos/nyaruka/courier/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nyaruka/courier/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nyaruka/courier/teams","hooks_url":"https://api.github.com/repos/nyaruka/courier/hooks","issue_events_url":"https://api.github.com/repos/nyaruka/courier/issues/events{/number}","events_url":"https://api.github.com/repos/nyaruka/courier/events","assignees_url":"https://api.github.com/repos/nyaruka/courier/assignees{/user}","branches_url":"https://api.github.com/repos/nyaruka/courier/branches{/branch}","tags_url":"https://api.github.com/repos/nyaruka/courier/tags","blobs_url":"https://api.github.com/repos/nyaruka/courier/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nyaruka/courier/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nyaruka/courier/git/refs{/sha}","trees_url":"https://api.github.com/repos/nyaruka/courier/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nyaruka/courier/statuses/{sha}","languages_url":"https://api.github.com/repos/nyaruka/courier/languages","stargazers_url":"https://api.github.com/repos/nyaruka/courier/stargazers","contributors_url":"https://api.github.com/repos/nyaruka/courier/contributors","subscribers_url":"https://api.github.com/repos/nyaruka/courier/subscribers","subscription_url":"https://api.github.com/repos/nyaruka/courier/subscription","commits_url":"https://api.github.com/repos/nyaruka/courier/commits{/sha}","git_commits_url":"https://api.github.com/repos/nyaruka/courier/git/commits{/sha}","comments_url":"https://api.github.com/repos/nyaruka/courier/comments{/number}","issue_comment_url":"https://api.github.com/repos/nyaruka/courier/issues/comments{/number}","contents_url":"https://api.github.com/repos/nyaruka/courier/contents/{+path}","compare_url":"https://api.github.com/repos/nyaruka/courier/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nyaruka/courier/merges","archive_url":"https://api.github.com/repos/nyaruka/courier/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nyaruka/courier/downloads","issues_url":"https://api.github.com/repos/nyaruka/courier/issues{/number}","pulls_url":"https://api.github.com/repos/nyaruka/courier/pulls{/number}","milestones_url":"https://api.github.com/repos/nyaruka/courier/milestones{/number}","notifications_url":"https://api.github.com/repos/nyaruka/courier/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nyaruka/courier/labels{/name}","releases_url":"https://api.github.com/repos/nyaruka/courier/releases{/id}","deployments_url":"https://api.github.com/repos/nyaruka/courier/deployments","created_at":"2017-05-10T16:38:44Z","updated_at":"2018-02-06T01:10:46Z","pushed_at":"2018-02-16T18:33:06Z","git_url":"git://github.com/nyaruka/courier.git","ssh_url":"git@github.com:nyaruka/courier.git","clone_url":"https://github.com/nyaruka/courier.git","svn_url":"https://github.com/nyaruka/courier","homepage":null,"size":4359,"stargazers_count":30,"watchers_count":30,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":7,"mirror_url":null,"archived":false,"open_issues_count":16,"license":{"key":"agpl-3.0","name":"GNU Affero General Public License v3.0","spdx_id":"AGPL-3.0","url":"https://api.github.com/licenses/agpl-3.0"},"forks":7,"open_issues":16,"watchers":30,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/nyaruka/courier/pulls/116"},"html":{"href":"https://github.com/nyaruka/courier/pull/116"},"issue":{"href":"https://api.github.com/repos/nyaruka/courier/issues/116"},"comments":{"href":"https://api.github.com/repos/nyaruka/courier/issues/116/comments"},"review_comments":{"href":"https://api.github.com/repos/nyaruka/courier/pulls/116/comments"},"review_comment":{"href":"https://api.github.com/repos/nyaruka/courier/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/nyaruka/courier/pulls/116/commits"},"statuses":{"href":"https://api.github.com/repos/nyaruka/courier/statuses/b7071c5b4a6d73f41025c775b54706861a69533f"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"nicpottier"}}