func (s *Story) ShouldIgnore() bool {
	return s.Type != "story" ||
		s.Score < ScoreThreshold ||
		s.Descendants < NumCommentsThreshold ||
		s.URL == ""
}
ShouldIgnore is a filter for story.
package bots
import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"time"
	"github.com/pkg/errors"
	"google.golang.org/appengine/datastore"
	"google.golang.org/appengine/log"
)
const Hot = "🔥"
type Story struct {
	ID                  int64     `json:"id"`
	URL                 string    `json:"url"`
	Title               string    `json:"title"`
	Descendants         int64     `json:"descendants"`
	Score               int64     `json:"score"`
	MessageID           int64     `json:"-"`
	LastSave            time.Time `json:"-"`
	Type                string    `json:"type"`
	missingFieldsLoaded bool
}
func NewFromDatastore(ctx context.Context, id int64) (Story, error) {
	var story Story
	if err := datastore.Get(ctx, GetKey(ctx, id), &story); err != nil {
		return story, errors.WithStack(err)
	}
	return story, nil
}
func (s *Story) Load(ps []datastore.Property) error {
	return datastore.LoadStruct(s, ps)
}
func (s *Story) Save() ([]datastore.Property, error) {
	return []datastore.Property{
		{
			Name:  "MessageID",
			Value: s.MessageID,
		},
		{
			Name:  "ID",
			Value: s.ID,
		},
		{
			Name:  "LastSave",
			Value: time.Now(),
		},
	}, nil
}
func (s *Story) FillMissingFields(ctx context.Context) error {
	resp, err := myHTTPClient(ctx).Get(ItemURL(s.ID))
	if err != nil {
		return errors.WithStack(err)
	}
	defer resp.Body.Close()
	err = json.NewDecoder(resp.Body).Decode(s)
	if err != nil {
		return errors.WithStack(err)
	}
	s.missingFieldsLoaded = true
	return nil
}