Пример #1
0
func readMessage(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	connUuid := ps.ByName("conn_uuid")

	msgId, err := strconv.ParseUint(ps.ByName("msg_uuid"), 10, 64)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	// load our msg and status
	msg, err := store.MsgFromId(connUuid, msgId)
	defer msg.Release()

	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	// output it
	js, err := json.Marshal(msg)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(js)
}
Пример #2
0
// Starts our sender, this starts a goroutine that blocks on receiving a message to send
func (t TwitterConnection) Start() {
	// todo: this doesn't need to happen for each connection
	anaconda.SetConsumerKey(cfg.Config.Twitter.Consumer_Key)
	anaconda.SetConsumerSecret(cfg.Config.Twitter.Consumer_Secret)

	// this is our sending thread
	go func() {
		t.wg.Add(1)
		defer t.wg.Done()
		var id uint64

		// configure our API
		api := anaconda.NewTwitterApi(t.token, t.secret)
		defer api.Close()

		for {
			// mark ourselves as ready for work, this never blocks
			t.readySenders <- t

			// wait for a job to come in, or for us to be shut down
			select {
			case id = <-t.pendingMsg:
			case <-t.done:
				return
			}

			var msgLog = ""

			// load our msg
			msg, err := store.MsgFromId(t.connection.Uuid, id)
			if err != nil {
				msgLog = fmt.Sprintf("[%s][%d] Error sending msg (%d): %s", t.connection.Uuid, t.id, id, err.Error())
			} else {
				// send the message
				dm, err := api.PostDMToScreenName(msg.Text, msg.Address)
				if err != nil {
					msgLog = fmt.Sprintf("[%s][%d] Error sending msg (%d): %s", t.connection.Uuid, t.id, id, err.Error())
				} else {
					msgLog = fmt.Sprintf("[%s][%d] Sent DM, id: %d", t.connection.Uuid, t.id, dm.Id)
				}
			}

			// mark the message as sent
			err = msg.MarkSent(msgLog)
			if err != nil {
				log.Printf("[%s][%d] Error marking msg sent (%d)", t.connection.Uuid, t.id, id)
			} else {
				log.Printf("[%s][%d] Sent msg (%d)", t.connection.Uuid, t.id, id)
			}

			// release our message back to the pool
			msg.Release()
		}
	}()

	// this is our receiving thread
	go func() {
		t.wg.Add(1)
		defer t.wg.Done()

		api := anaconda.NewTwitterApi(t.token, t.secret)
		defer api.Close()

		userStream := api.UserStream(url.Values{})
		var event interface{}

		for {
			// wait for a twitter event to arrive
			select {
			case event = <-userStream.C:
			case <-t.done:
				userStream.Interrupt()
				return
			}

			// see if this is a direct message
			dm, ok := event.(anaconda.DirectMessage)
			if !ok {
				continue
			}

			// check that this isn't one of our own DM's echoing back at us
			if t.username == strings.ToLower(dm.SenderScreenName) {
				continue
			}

			log.Printf("[%s][%d] Received DM from %s: %s", t.connection.Uuid, t.id, dm.SenderScreenName, dm.Text)

			// create a new msg from our DM
			msg := store.MsgFromText(t.connection.Uuid, dm.SenderScreenName, dm.Text)
			err := msg.WriteToInbox()
			if err != nil {
				log.Printf("[%s][%d] Error saving msg (%d): %s", t.connection.Uuid, t.id, dm.Id, err.Error())
			}

			// pass our message to be received
			t.incoming <- msg.Id

			// release our message back to the pool
			msg.Release()
		}
	}()
}
Пример #3
0
// Starts our receiver, this starts a goroutine that blocks on msgs to forward
func (r HttpReceiver) Start() {
	go func() {
		// tell our wait group we started
		r.wg.Add(1)

		// when we exit, tell our wait group we stopped
		defer r.wg.Done()
		var id uint64

		for {
			// mark ourselves as ready for work, this never blocks
			r.readyReceivers <- r

			// wait for a job to come in, or be marked as complete
			select {
			case id = <-r.pendingMsg:
			case <-r.done:
				return
			}

			// load our msg
			var msgLog = ""
			msg, err := store.MsgFromId(r.connection.Uuid, id)
			if err != nil {
				msgLog = fmt.Sprintf(
					"[%s][%d] Error loading msg (%d) from store: %s", r.connection.Uuid, r.id, id, err.Error())
			} else {
				js, err := json.Marshal(msg)
				if err != nil {
					msgLog = fmt.Sprintf(
						"[%s][%d] Error json encoding msg (%d): %s", r.connection.Uuid, r.id, id, err.Error())
				} else {
					// we post our Msg body to our receiver URL
					req, err := http.NewRequest("POST", r.url, bytes.NewBuffer(js))
					req.Header.Set("Content-Type", "application/json")

					client := &http.Client{}
					resp, err := client.Do(req)
					if err != nil {
						msgLog = fmt.Sprintf("[%s][%d] Error posting msg (%d): %s", r.connection.Uuid, r.id, id, err.Error())
					} else {
						buf := new(bytes.Buffer)
						buf.ReadFrom(resp.Body)
						body := buf.String()

						if resp.Status != "200" && resp.Status != "201" {
							msgLog = fmt.Sprintf("[%s][%d] Error posting msg (%d) received status %s: %s",
								r.connection.Uuid, r.id, id, resp.Status, body)
						} else {
							msgLog = fmt.Sprintf("Status: %s\n\n%s", resp.Status, body)
						}
						resp.Body.Close()
					}
				}
			}

			// mark the message as sent
			err = msg.MarkHandled(msgLog)
			log.Printf("[%s][%d] Handled msg (%d)", r.connection.Uuid, r.id, id)
			if err != nil {
				log.Println("Error marking msg handled")
			}

			// release our msg back to our object pool
			msg.Release()
		}
	}()
}