Esempio n. 1
0
func checkNumber(config *periwinkle.Cfg, tx *periwinkle.Tx, number backend.TwilioNumber) {
	url := "https://api.twilio.com/2010-04-01/Accounts/" + config.TwilioAccountID + "/Messages.json?To=" + number.Number
	if lastPoll != timeZero {
		url += "&DateSent>=" + strings.Split(lastPoll.UTC().String(), " ")[0]
	}

	req, _ := http.NewRequest("GET", url, nil)
	req.SetBasicAuth(config.TwilioAccountID, config.TwilioAuthToken)
	resp, uerr := (&http.Client{}).Do(req)
	if uerr != nil {
		periwinkle.LogErr(locale.UntranslatedError(uerr))
	}

	defer resp.Body.Close()
	body, uerr := ioutil.ReadAll(resp.Body)
	if uerr != nil {
		periwinkle.LogErr(locale.UntranslatedError(uerr))
	}

	// converts JSON messages
	var page twilio.Paging
	json.Unmarshal([]byte(body), &page)

	for _, message := range page.Messages {
		timeSend, uerr := time.Parse(time.RFC1123Z, message.DateSent)
		if uerr != nil {
			periwinkle.LogErr(locale.UntranslatedError(uerr))
			continue
		}
		if timeSend.Unix() < lastPoll.Unix() {
			periwinkle.Logf("message %q older than our last poll; ignoring", message.Sid)
			continue
		}
		user := backend.GetUserByAddress(tx, "sms", message.From)
		if user == nil {
			periwinkle.Logf("could not figure out which user has number %q", message.From)
			continue
		}
		group := backend.GetGroupByUserAndTwilioNumber(tx, user.ID, message.To)
		if group == nil {
			periwinkle.Logf("could not figure out which group this is meant for: user: %q, number: %q", user.ID, message.To)
			continue
		}
		periwinkle.Logf("received message for group %q", group.ID)
		MessageBuilder{
			Maildir: config.Mailstore,
			Headers: map[string]string{
				"To":      group.ID + "@" + config.GroupDomain,
				"From":    backend.UserAddress{Medium: "sms", Address: message.From}.AsEmailAddress(),
				"Subject": user.ID + ": " + message.Body,
			},
			Body: "",
		}.Done()
	}
}
Esempio n. 2
0
func HandleSMS(r io.Reader, name string, db *periwinkle.Tx, cfg *periwinkle.Cfg) postfixpipe.ExitStatus {
	message, uerr := mail.ReadMessage(r)
	if uerr != nil {
		periwinkle.LogErr(locale.UntranslatedError(uerr))
		return postfixpipe.EX_NOINPUT
	}

	group := message.Header.Get("From")
	user := backend.GetUserByAddress(db, "sms", name)

	smsFrom := backend.GetTwilioNumberByUserAndGroup(db, user.ID, strings.Split(group, "@")[0])

	if smsFrom == "" {
		twilio_num := twilio.GetUnusedTwilioNumbersByUser(cfg, db, user.ID)
		if twilio_num == nil {
			new_num, err := twilio.NewPhoneNum(cfg)
			if err != nil {
				periwinkle.LogErr(err)
				return postfixpipe.EX_UNAVAILABLE
			}
			backend.AssignTwilioNumber(db, user.ID, strings.Split(group, "@")[0], new_num)
			smsFrom = new_num
		} else {
			backend.AssignTwilioNumber(db, user.ID, strings.Split(group, "@")[0], twilio_num[0])
			smsFrom = twilio_num[0]
		}
	}

	smsBody := message.Header.Get("Subject")
	//smsBody, err := ioutil.ReadAll(message.Body)
	//if err != nil {
	//	return "", err
	//}

	messagesURL := "https://api.twilio.com/2010-04-01/Accounts/" + cfg.TwilioAccountID + "/Messages.json"

	v := url.Values{}
	v.Set("From", smsFrom)
	v.Set("To", name)
	v.Set("Body", string(smsBody))
	v.Set("StatusCallback", cfg.WebRoot+"/callbacks/twilio-sms")
	//host,_ := os.Hostname()
	//v.Set("StatusCallback", "http://" + host + ":8080/callbacks/twilio-sms")
	client := &http.Client{}

	req, uerr := http.NewRequest("POST", messagesURL, bytes.NewBuffer([]byte(v.Encode())))
	if uerr != nil {
		periwinkle.LogErr(locale.UntranslatedError(uerr))
		return postfixpipe.EX_UNAVAILABLE
	}
	req.SetBasicAuth(cfg.TwilioAccountID, cfg.TwilioAuthToken)
	req.Header.Add("Accept", "application/json")
	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

	resp, uerr := client.Do(req)
	defer resp.Body.Close()
	if uerr != nil {
		periwinkle.LogErr(locale.UntranslatedError(uerr))
		return postfixpipe.EX_UNAVAILABLE
	}

	if resp.StatusCode != 200 && resp.StatusCode != 201 {
		return postfixpipe.EX_UNAVAILABLE
	}

	body, uerr := ioutil.ReadAll(resp.Body)
	if uerr != nil {
		periwinkle.LogErr(locale.UntranslatedError(uerr))
		return postfixpipe.EX_UNAVAILABLE
	}
	return postfixpipe.EX_OK
	tmessage := twilio.Message{}
	json.Unmarshal([]byte(body), &tmessage)
	_, err := TwilioSMSWaitForCallback(cfg, tmessage.Sid)
	if err != nil {
		periwinkle.LogErr(err)
		return postfixpipe.EX_UNAVAILABLE
	}
	return postfixpipe.EX_OK
}