github.com/grantbow/fit@v0.7.1-0.20220916164603-1f7c88ac81e6/fitapp/Twilio.go (about) 1 package fitapp 2 3 import ( 4 "encoding/json" 5 "fmt" 6 bugs "github.com/grantbow/fit/issues" 7 "github.com/grantbow/fit/scm" 8 "net/http" 9 "net/url" 10 "strings" 11 ) 12 13 //var dops = bugs.Directory(os.PathSeparator) 14 //var sops = string(os.PathSeparator) 15 16 // TwilioUrlHttp default base of url https://api.twilio.com/2010-04-01/Accounts/ 17 var TwilioUrlHttp = "https://api.twilio.com/2010-04-01/Accounts/" 18 // TwilioUrlMessages default like Messages.json /Messages.json 19 var TwilioUrlMessages = "/Messages.json" 20 21 // Twilio is a subcommand to send to changed isssues with tag_twilio_4155551212 22 func Twilio(config bugs.Config) { 23 var hasPart = func(target string, part string) bool { 24 return strings.Contains(target, part) 25 } 26 27 buglist := bugs.GetAllIssues(config) 28 //fmt.Printf("getallbugs: %q\n", buglist) 29 if len(buglist) > 0 { 30 // from buglist and 31 // from scm get added, changed and removed 32 //fmt.Printf("debug 1\n") 33 scmoptions := map[string]bool{} 34 handler, _, ErrH := scm.DetectSCM(scmoptions, config) 35 if ErrH == nil { 36 // scm exists 37 if _, err := handler.SCMIssuesUpdaters(config); err != nil { 38 // []byte and err 39 // uncommitted files including staged AND working directory 40 //fmt.Printf("debug 2\n") 41 if b, ErrCach := handler.SCMIssuesCacher(config); ErrCach != nil { 42 // []byte and ErrCach 43 // uncommitted files staged only NOT working directory 44 //fmt.Printf("debug 3\n") 45 updatedissues := map[string]bool{} // issues staged no duplicates 46 twiliorecipients := map[string]string{} // one or more per issue staged 47 //fmt.Printf("updated issues:\n") 48 for _, bline := range strings.Split(string(b), "\n") { 49 if len(bline) > 0 { 50 i := strings.Split(string(bline), sops) 51 if len(i) > 2 { 52 updatedissues[i[1]] = true 53 } 54 } 55 } 56 // updated issues exist 57 //for key, _ := range updatedissues { 58 // fmt.Printf("bug dirname: %v\n", key) 59 //} 60 bug := bugs.Issue{} 61 62 // build message for each recipient from updated issues and twilio tags 63 for key := range updatedissues { 64 //fmt.Printf("twilio bug dirname: %v\n", key) 65 expectedbugdir := string(bugs.FitDirer(config)) + sops + key 66 bug.LoadIssue(bugs.Directory(expectedbugdir), config) 67 tags := bug.Tags() 68 //fmt.Printf("debug %v tags %v\n", key, tags) 69 for _, k := range tags { 70 //fmt.Printf("k: %v\n", k) 71 if hasPart(string(k), "twilio") { // local function returns bool 72 a := strings.Split(string(k), ":") // : separated from issue.Tags 73 recip := a[1] 74 //fmt.Printf("twilio issue dirname: %v tag %v : %v\n", key, a[0], recip) 75 // if strings.ToLower(string(tag)) == "twilio" { 76 if _, ok := twiliorecipients[recip]; ok { 77 // recipient exists, append 78 twiliorecipients[recip] = twiliorecipients[recip] + ", " + key 79 } else { 80 // new recipient 81 twiliorecipients[recip] = "site " + config.FitSite + "\nupdated " + key 82 } 83 } 84 } 85 } 86 fmt.Printf("result: %v\n", twiliorecipients) 87 for msg := range twiliorecipients { 88 TwilioDoSend(config, msg, twiliorecipients[msg]) 89 } 90 } else { 91 fmt.Printf("No updated and staged issues.\n") 92 } 93 } else { 94 fmt.Printf("No updated or staged issues.\n") 95 } 96 } 97 } else { 98 fmt.Print("<no twilio tags yet>\n") 99 return 100 } 101 } 102 103 // TwilioDoSend used to text all recipients a string 104 func TwilioDoSend(config bugs.Config, PNTo string, BodyStr string) { 105 urlStr := TwilioUrlHttp + config.TwilioAccountSid + TwilioUrlMessages 106 fmt.Println(urlStr) 107 msgData := url.Values{} 108 msgData.Set("To", PNTo) // Phone Number To 109 msgData.Set("From", config.TwilioPhoneNumberFrom) 110 msgData.Set("Body", BodyStr) // text message body 111 msgDataReader := *strings.NewReader(msgData.Encode()) 112 // 113 client := &http.Client{} 114 req, _ := http.NewRequest("POST", urlStr, &msgDataReader) 115 req.SetBasicAuth(config.TwilioAccountSid, config.TwilioAuthToken) 116 req.Header.Add("Accept", "application/json") 117 req.Header.Add("Content-Type", "application/x-www-form-urlencoded") 118 // 119 resp, _ := client.Do(req) 120 if resp.StatusCode >= 200 && resp.StatusCode < 300 { 121 var data map[string]interface{} 122 decoder := json.NewDecoder(resp.Body) 123 err := decoder.Decode(&data) 124 if err != nil { // less than perfect, == nil perfect 125 fmt.Println(data["sid"]) 126 } else { 127 fmt.Printf("%v\n", resp) // print success 128 } 129 } else { 130 fmt.Printf("%v\n", resp) // print failure 131 } 132 }