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  }