<commit_before>package messenger

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"time"
)

const (
	// ProfileURL is the API endpoint used for retrieving profiles.
	// Used in the form: https://graph.facebook.com/v2.6/<USER_ID>?fields=first_name,last_name,profile_pic&access_token=<PAGE_ACCESS_TOKEN>
	ProfileURL = "https://graph.facebook.com/v2.6/"
	// SendSettingsURL is API endpoint for saving settings.
	SendSettingsURL = "https://graph.facebook.com/v2.6/me/thread_settings"
)

// Options are the settings used when creating a Messenger client.
type Options struct {
	// Verify sets whether or not to be in the "verify" mode. Used for
	// verifying webhooks on the Facebook Developer Portal.
	Verify bool
	// VerifyToken is the token to be used when verifying the webhook. Is set
	// when the webhook is created.
	VerifyToken string
	// Token is the access token of the Facebook page to send messages from.
	Token string
	// WebhookURL is where the Messenger client should listen for webhook events. Leaving the string blank implies a path of "/".
	WebhookURL string
	// Mux is shared mux between several Messenger objects
	Mux *http.ServeMux
}

// MessageHandler is a handler used for responding to a message containing text.
type MessageHandler func(Message, *Response)

// DeliveryHandler is a handler used for responding to a delivery receipt.
type DeliveryHandler func(Delivery, *Response)

// ReadHandler is a handler used for responding to a read receipt.
type ReadHandler func(Read, *Response)

// PostBackHandler is a handler used postback callbacks.
type PostBackHandler func(PostBack, *Response)

// Messenger is the client which manages communication with the Messenger Platform API.
type Messenger struct {
	mux              *http.ServeMux
	messageHandlers  []MessageHandler
	deliveryHandlers []DeliveryHandler
	readHandlers     []ReadHandler
	postBackHandlers []PostBackHandler
	token            string
	verifyHandler    func(http.ResponseWriter, *http.Request)
}

// New creates a new Messenger. You pass in Options in order to affect settings.
func New(mo Options) *Messenger {
	if mo.Mux == nil {
		mo.Mux = http.NewServeMux()
	}

	m := &Messenger{
		mux:   mo.Mux,
		token: mo.Token,
	}

	if mo.WebhookURL == "" {
		mo.WebhookURL = "/"
	}

	m.verifyHandler = newVerifyHandler(mo.VerifyToken)
	m.mux.HandleFunc(mo.WebhookURL, m.handle)

	return m
}

// HandleMessage adds a new MessageHandler to the Messenger which will be triggered
// when a message is received by the client.
func (m *Messenger) HandleMessage(f MessageHandler) {
	m.messageHandlers = append(m.messageHandlers, f)
}

// HandleDelivery adds a new DeliveryHandler to the Messenger which will be triggered
// when a previously sent message is delivered to the recipient.
func (m *Messenger) HandleDelivery(f DeliveryHandler) {
	m.deliveryHandlers = append(m.deliveryHandlers, f)
}

// HandleRead adds a new DeliveryHandler to the Messenger which will be triggered
// when a previously sent message is read by the recipient.
func (m *Messenger) HandleRead(f ReadHandler) {
	m.readHandlers = append(m.readHandlers, f)
}

// HandlePostBack adds a new PostBackHandler to the Messenger
func (m *Messenger) HandlePostBack(f PostBackHandler) {
	m.postBackHandlers = append(m.postBackHandlers, f)
}

// Handler returns the Messenger in HTTP client form.
func (m *Messenger) Handler() http.Handler {
	return m.mux
}

// ProfileByID retrieves the Facebook user associated with that ID
func (m *Messenger) ProfileByID(id int64) (Profile, error) {
	p := Profile{}
	url := fmt.Sprintf("%v%v", ProfileURL, id)

	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return p, err
	}

	req.URL.RawQuery = "fields=first_name,last_name,profile_pic&access_token=" + m.token
<commit_msg>Fix profile fields not being entirely populated<commit_after>package messenger

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"time"
)

const (
	// ProfileURL is the API endpoint used for retrieving profiles.
	// Used in the form: https://graph.facebook.com/v2.6/<USER_ID>?fields=<PROFILE_FIELDS>&access_token=<PAGE_ACCESS_TOKEN>
	ProfileURL = "https://graph.facebook.com/v2.6/"
	// ProfileFields is a list of JSON field names which will be populated by the profile query.
	ProfileFields = "first_name,last_name,profile_pic,locale,timezone,gender"
	// SendSettingsURL is API endpoint for saving settings.
	SendSettingsURL = "https://graph.facebook.com/v2.6/me/thread_settings"
)

// Options are the settings used when creating a Messenger client.
type Options struct {
	// Verify sets whether or not to be in the "verify" mode. Used for
	// verifying webhooks on the Facebook Developer Portal.
	Verify bool
	// VerifyToken is the token to be used when verifying the webhook. Is set
	// when the webhook is created.
	VerifyToken string
	// Token is the access token of the Facebook page to send messages from.
	Token string
	// WebhookURL is where the Messenger client should listen for webhook events. Leaving the string blank implies a path of "/".
	WebhookURL string
	// Mux is shared mux between several Messenger objects
	Mux *http.ServeMux
}

// MessageHandler is a handler used for responding to a message containing text.
type MessageHandler func(Message, *Response)

// DeliveryHandler is a handler used for responding to a delivery receipt.
type DeliveryHandler func(Delivery, *Response)

// ReadHandler is a handler used for responding to a read receipt.
type ReadHandler func(Read, *Response)

// PostBackHandler is a handler used postback callbacks.
type PostBackHandler func(PostBack, *Response)

// Messenger is the client which manages communication with the Messenger Platform API.
type Messenger struct {
	mux              *http.ServeMux
	messageHandlers  []MessageHandler
	deliveryHandlers []DeliveryHandler
	readHandlers     []ReadHandler
	postBackHandlers []PostBackHandler
	token            string
	verifyHandler    func(http.ResponseWriter, *http.Request)
}

// New creates a new Messenger. You pass in Options in order to affect settings.
func New(mo Options) *Messenger {
	if mo.Mux == nil {
		mo.Mux = http.NewServeMux()
	}

	m := &Messenger{
		mux:   mo.Mux,
		token: mo.Token,
	}

	if mo.WebhookURL == "" {
		mo.WebhookURL = "/"
	}

	m.verifyHandler = newVerifyHandler(mo.VerifyToken)
	m.mux.HandleFunc(mo.WebhookURL, m.handle)

	return m
}

// HandleMessage adds a new MessageHandler to the Messenger which will be triggered
// when a message is received by the client.
func (m *Messenger) HandleMessage(f MessageHandler) {
	m.messageHandlers = append(m.messageHandlers, f)
}

// HandleDelivery adds a new DeliveryHandler to the Messenger which will be triggered
// when a previously sent message is delivered to the recipient.
func (m *Messenger) HandleDelivery(f DeliveryHandler) {
	m.deliveryHandlers = append(m.deliveryHandlers, f)
}

// HandleRead adds a new DeliveryHandler to the Messenger which will be triggered
// when a previously sent message is read by the recipient.
func (m *Messenger) HandleRead(f ReadHandler) {
	m.readHandlers = append(m.readHandlers, f)
}

// HandlePostBack adds a new PostBackHandler to the Messenger
func (m *Messenger) HandlePostBack(f PostBackHandler) {
	m.postBackHandlers = append(m.postBackHandlers, f)
}

// Handler returns the Messenger in HTTP client form.
func (m *Messenger) Handler() http.Handler {
	return m.mux
}

// ProfileByID retrieves the Facebook user associated with that ID
func (m *Messenger) ProfileByID(id int64) (Profile, error) {
	p := Profile{}
	url := fmt.Sprintf("%v%v", ProfileURL, id)

	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return p, err
	}

	req.URL.RawQuery = "fields=" + ProfileFields + "&access_token=" + m.token

{'fraction_non_alphanumeric': 0.08948458948458948, 'fraction_numerical': 0.002072002072002072, 'mean_word_length': 4.128154050464808, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 8, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1816522', 'n_tokens_mistral': 2371, 'n_tokens_neox': 2292, 'n_words': 856}