Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
haimgel committed Oct 3, 2022
0 parents commit 7d6732b
Show file tree
Hide file tree
Showing 8 changed files with 282 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/dist
29 changes: 29 additions & 0 deletions cmd/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package cmd

import (
"fmt"
slack2 "github.com/haimgel/slack-status/internal/slack"
"net/http"
"time"
)

func Execute(version string, exit func(int), args []string) {
//cookie := slack.GetDCookie()
cookie := &http.Cookie{
Name: "d",
Value: "xoxd-9%2FFyocxzZ2E17ACCYqcRfCu0x2Er48eXT%2FBtF7IeSNRERAxJLkZ5fFkHl5EZZCsGYvkUd09wdYRwJiwGjYvlPa8QD0mEeBRg3JtRLEcujPfN2ifMB0TGJoJSpTNUxeM1wcO3V5duoC0RltMmVTEhci9WzPH8aChg8dis4EZ5A97QXysEPWNsdhrQ",
Path: "/",
Domain: ".slack.com",
Expires: time.Now().AddDate(1, 0, 0),
Secure: true,
HttpOnly: true,
SameSite: 0,
}
fmt.Printf("d-cookie=%s", cookie.Value)
result, err := slack2.ScrapeToken("hageltech", cookie)
fmt.Printf("%s, %s", result, err)
err = slack2.SetStatus(result, cookie.Value, "Lunch", ":hamburger:", 30*time.Minute)
// Not authorized is `slack.SlackErrorResponse` with Err = "not_authed"
fmt.Printf("%s", err)
// slack.New("xoxc", slack.OptionCookie("d", ""))
}
31 changes: 31 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module github.com/haimgel/slack-status

go 1.18

require (
github.com/slack-go/slack v0.11.3
github.com/zellyn/kooky v0.0.0-20220429214451-68fd0a98b521
)

require (
github.com/Velocidex/json v0.0.0-20220224052537-92f3c0326e5a // indirect
github.com/Velocidex/ordereddict v0.0.0-20220411103415-79032cf99b1d // indirect
github.com/Velocidex/yaml/v2 v2.2.8 // indirect
github.com/bobesa/go-domain-util v0.0.0-20190911083921-4033b5f7dd89 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-ini/ini v1.66.4 // indirect
github.com/go-sqlite/sqlite3 v0.0.0-20180313105335-53dd8e640ee7 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/gonuts/binary v0.2.0 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/keybase/go-keychain v0.0.0-20220408132150-ad3b4a8fd4a7 // indirect
github.com/zalando/go-keyring v0.2.1 // indirect
golang.org/x/crypto v0.0.0-20220408190544-5352b0902921 // indirect
golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3 // indirect
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f // indirect
golang.org/x/text v0.3.7 // indirect
www.velocidex.com/golang/go-ese v0.1.0 // indirect
)

// Use a patched version because the official one does not support XOXC tokens: https://github.com/slack-go/slack/issues/996
replace github.com/slack-go/slack => github.com/rusq/slack v0.11.300
71 changes: 71 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
github.com/Velocidex/json v0.0.0-20220224052537-92f3c0326e5a h1:AeXPUzhU0yhID/v5JJEIkjaE85ASe+Vh4Kuv1RSLL+4=
github.com/Velocidex/json v0.0.0-20220224052537-92f3c0326e5a/go.mod h1:ukJBuruT9b24pdgZwWDvOaCYHeS03B7oQPCUWh25bwM=
github.com/Velocidex/ordereddict v0.0.0-20191106020901-97c468e5e403/go.mod h1:pxJpvN5ISMtDwrdIdqnJ3ZrjIngCw+WT6gfNil6Zjvo=
github.com/Velocidex/ordereddict v0.0.0-20220411103415-79032cf99b1d h1:XnifmnLRjinjYzZgbog7LQr2XbmEFI81kuiufpn+JUQ=
github.com/Velocidex/ordereddict v0.0.0-20220411103415-79032cf99b1d/go.mod h1:XJDUbaGh2U9e0z78L5O2OXf1hE1wSxnJ7nSlQmA+bIs=
github.com/Velocidex/yaml/v2 v2.2.8 h1:GUrSy4SBJ6RjGt43k6MeBKtw2z/27gh4A3hfFmFY3No=
github.com/Velocidex/yaml/v2 v2.2.8/go.mod h1:PlXIg/Pxmoja48C1vMHo7C5pauAZvLq/UEPOQ3DsjS4=
github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142 h1:8Uy0oSf5co/NZXje7U1z8Mpep++QJOldL2hs/sBQf48=
github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
github.com/bobesa/go-domain-util v0.0.0-20190911083921-4033b5f7dd89 h1:2pkAuIM8OF1fy4ToFpMnI4oE+VeUNRbGrpSLKshK0oQ=
github.com/bobesa/go-domain-util v0.0.0-20190911083921-4033b5f7dd89/go.mod h1:/09nEjna1UMoasyyQDhOrIn8hi2v2kiJglPWed1idck=
github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-ini/ini v1.66.4 h1:dKjMqkcbkzfddhIhyglTPgMoJnkvmG+bSLrU9cTHc5M=
github.com/go-ini/ini v1.66.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-sqlite/sqlite3 v0.0.0-20180313105335-53dd8e640ee7 h1:ow5vK9Q/DSKkxbEIJHBST6g+buBDwdaDIyk1dGGwpQo=
github.com/go-sqlite/sqlite3 v0.0.0-20180313105335-53dd8e640ee7/go.mod h1:JxSQ+SvsjFb+p8Y+bn+GhTkiMfKVGBD0fq43ms2xw04=
github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho=
github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gonuts/binary v0.2.0 h1:caITwMWAoQWlL0RNvv2lTU/AHqAJlVuu6nZmNgfbKW4=
github.com/gonuts/binary v0.2.0/go.mod h1:kM+CtBrCGDSKdv8WXTuCUsw+loiy8f/QEI8YCCC0M/E=
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/keybase/go-keychain v0.0.0-20220408132150-ad3b4a8fd4a7 h1:ttxQhWhqiYEOVLMhmhIRQnZDLmYaBJVP7goucV3FJxM=
github.com/keybase/go-keychain v0.0.0-20220408132150-ad3b4a8fd4a7/go.mod h1:enrU/ug069Om7vWxuFE6nikLI2BZNwevMiGSo43Kt5w=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rusq/slack v0.11.300 h1:s/1gVdKU+gD+3DUhAzMV6NwBGSUOP65J7QP0pB6EZRQ=
github.com/rusq/slack v0.11.300/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/zalando/go-keyring v0.2.1 h1:MBRN/Z8H4U5wEKXiD67YbDAr5cj/DOStmSga70/2qKc=
github.com/zalando/go-keyring v0.2.1/go.mod h1:g63M2PPn0w5vjmEbwAX3ib5I+41zdm4esSETOn9Y6Dw=
github.com/zellyn/kooky v0.0.0-20220429214451-68fd0a98b521 h1:whJ5LV+cjrc5iIB7C/3lpAtQNSqu/iifRliL8ct948o=
github.com/zellyn/kooky v0.0.0-20220429214451-68fd0a98b521/go.mod h1:6JjIozsIKDJ2H0S0ePLIoVbhhBvI15a/oFlMYsfIsSA=
golang.org/x/crypto v0.0.0-20220408190544-5352b0902921 h1:iU7T1X1J6yxDr0rda54sWGkHgOp5XJrqm79gcNlC2VM=
golang.org/x/crypto v0.0.0-20220408190544-5352b0902921/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3 h1:EN5+DfgmRMvRUrMGERW2gQl3Vc+Z7ZMnI/xdEpPSf0c=
golang.org/x/net v0.0.0-20220407224826-aac1ed45d8e3/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f h1:8w7RhxzTVgUzw/AH/9mUV5q0vMgy40SQRursCcfmkCw=
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
www.velocidex.com/golang/go-ese v0.1.0 h1:LObdPh6uoAAbz50MqF4WdJHAn9+Fcr/9kyW0fMsjxlc=
www.velocidex.com/golang/go-ese v0.1.0/go.mod h1:d3PHzQhyhe+AO9RYBnDKZ40As15T+38zr++Dnv4ufuc=
30 changes: 30 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package config

import (
"os"
"path/filepath"
"time"
)

const AppName = "slack-status"

type StatusConfig struct {
Name string `mapstructure:"name"`
Emoji string `mapstructure:"emoji"`
Text string `mapstructure:"text"`
Duration time.Duration `mapstructure:"duration"`
}

type ApplicationConfig struct {
Accounts []string `mapstructure:"accounts"`
Statuses []StatusConfig `mapstructure:"statuses"`
}

func defaultConfigHome() (string, error) {
cfgDir, err := os.UserConfigDir()
if err != nil {
return "", err
}
err = os.MkdirAll(cfgDir, 0750)
return filepath.Join(cfgDir, AppName), err
}
65 changes: 65 additions & 0 deletions internal/slack/credentials.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package slack

import (
"fmt"
"github.com/zellyn/kooky"
_ "github.com/zellyn/kooky/browser/all" // register cookie store finders!
"io"
"io/ioutil"
"net/http"
"regexp"
"sort"
)

// Slack _needs_ user agent pretending to be Chrome, otherwise it does not give back a token
const fakeUserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36"

func GetDCookie() *http.Cookie {
cookies := kooky.ReadCookies(kooky.Valid, kooky.DomainHasSuffix(`slack.com`), kooky.Name("d"))
// Sort found cookies by expiry date, in reverse, to get the most "fresh" cookie
sort.Slice(cookies, func(i, j int) bool {
return cookies[i].Expires.After(cookies[j].Expires)
})
if len(cookies) > 0 {
return &cookies[0].Cookie
} else {
return nil
}
}

func ScrapeToken(team string, dCookie *http.Cookie) (string, error) {
// Just a page where token is exposed as part of JSON in the page body itself
teamUrl := fmt.Sprintf("https://%s.slack.com/customize/emoji", team)

req, err := http.NewRequest("GET", teamUrl, nil)
if err != nil {
return "", err
}
req.Header.Set("User-Agent", fakeUserAgent)
req.AddCookie(dCookie)

resp, err := http.DefaultClient.Do(req)
if err != nil {
return "", err
}
if (resp.StatusCode < 200) || (resp.StatusCode > 299) {
return "", fmt.Errorf("unexpected HTTP response status code: %d", resp.StatusCode)
}

// Make sure the body is closed
defer func(Body io.ReadCloser) {
_ = Body.Close()
}(resp.Body)

html, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
// Find the API token in the page body
re := regexp.MustCompile(`"api_token":"(xo[^"]+)"`)
match := re.FindSubmatch(html)
if match == nil {
return "", fmt.Errorf("token is not found in the HTML body")
}
return string(match[1]), nil
}
20 changes: 20 additions & 0 deletions internal/slack/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package slack

import (
slackApi "github.com/slack-go/slack"
"time"
)

func GetStatus(token string, dCookie string) (string, error) {
api := slackApi.New(token, slackApi.OptionCookie("d", dCookie))
resp, err := api.GetUserProfile(&slackApi.GetUserProfileParameters{UserID: "", IncludeLabels: false})
if err != nil {
return "", err
}
return resp.StatusText, err
}

func SetStatus(token string, dCookie string, statusText string, statusEmoji string, statusExpiration time.Duration) error {
api := slackApi.New(token, slackApi.OptionCookie("d", dCookie))
return api.SetUserCustomStatus(statusText, statusEmoji, time.Now().Add(statusExpiration).Unix())
}
35 changes: 35 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package main

import (
"fmt"
"github.com/haimgel/slack-status/cmd"
"os"
"runtime"
)

// nolint: gochecknoglobals
var (
version = "dev"
commit = ""
date = ""
)

func buildVersion(version, commit, date string) string {
result := version
if commit != "" {
result = fmt.Sprintf("%s\ncommit: %s", result, commit)
}
if date != "" {
result = fmt.Sprintf("%s\nbuilt at: %s", result, date)
}
result = fmt.Sprintf("%s\ngoos: %s\ngoarch: %s", result, runtime.GOOS, runtime.GOARCH)
return result
}

func main() {
cmd.Execute(
buildVersion(version, commit, date),
os.Exit,
os.Args[1:],
)
}

0 comments on commit 7d6732b

Please sign in to comment.