smooch

package module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 6, 2020 License: MIT Imports: 17 Imported by: 0

README

Smooch

This is a Go library for making bots with Smooch service.

Note : This a modified version version of EddyTravels/smooch library with additional features. Please refer to the original repo for the original features.

Additional Feature

  • Token expiration & its checking.
  • Pre-create app user and link app user to specified channel functionality.
  • Send message in whatsapp HSM format.
  • Renew token functionality whenever token is expired.
  • Support smooch basic auth and JWT auth.
  • Redis support as a centralized storage to store JWT token for supporting autoscaling environment. Use redigo as redis library.

Tips

Smooch documentation: https://docs.smooch.io/rest/

Installing

$ go get -u github.com/kitabisa/smooch

Example

Using basic authentication :

import (
	"os"

	"github.com/kitabisa/smooch"
)

func main() {
    smoochClient, err := smooch.New(smooch.Options{
        Auth:         smooch.AuthBasic,
        AppID:        os.Getenv("SMOOCH_APP_ID"),
        KeyID:        os.Getenv("SMOOCH_KEY_ID"),
        Secret:       os.Getenv("SMOOCH_SECRET"),
    })

    if err != nil {
        panic(err)
    }
}

Using JWT authentication :

import (
	"os"

	"github.com/kitabisa/smooch"
)

func main() {
    smoochClient, err := smooch.New(smooch.Options{
        Auth:         smooch.AuthJWT,
        AppID:        os.Getenv("SMOOCH_APP_ID"),
        KeyID:        os.Getenv("SMOOCH_KEY_ID"),
        Secret:       os.Getenv("SMOOCH_SECRET"),
        RedisPool:    redisPool,
    })

    if err != nil {
        panic(err)
    }
}

Contributing

You are more than welcome to contribute to this project. Fork and make a Pull Request, or create an Issue if you see any problem.

Documentation

Index

Constants

View Source
const (
	RegionUS = "US"
	RegionEU = "EU"
)
View Source
const (
	MessageTypeText     = MessageType("text")
	MessageTypeImage    = MessageType("image")
	MessageTypeFile     = MessageType("file")
	MessageTypeLocation = MessageType("location")
	MessageTypeCarousel = MessageType("carousel")
	MessageTypeList     = MessageType("list")
	MessageTypeHSM      = MessageType("hsm")

	ActionTypePostback        = ActionType("postback")
	ActionTypeReply           = ActionType("reply")
	ActionTypeLocationRequest = ActionType("locationRequest")
	ActionTypeShare           = ActionType("share")
	ActionTypeBuy             = ActionType("buy")
	ActionTypeLink            = ActionType("link")
	ActionTypeWebview         = ActionType("webview")

	AuthBasic = "basic_auth"
	AuthJWT   = "jwt"

	SourceTypeWeb       = "web"
	SourceTypeIOS       = "ios"
	SourceTypeAndroid   = "android"
	SourceTypeMessenger = "messenger"
	SourceTypeViber     = "viber"
	SourceTypeTelegram  = "telegram"
	SourceTypeWeChat    = "wechat"
	SourceTypeLine      = "line"
	SourceTypeTwilio    = "twilio"
	SourceTypeApi       = "api"
	SourceTypeWhatsApp  = "whatsapp"

	RoleAppUser  = Role("appUser")
	RoleAppMaker = Role("appMaker")

	TriggerMessageAppUser         = "message:appUser"
	TriggerMessageAppMaker        = "message:appMaker"
	TriggerMessageDeliveryFailure = "message:delivery:failure"
	TriggerMessageDeliveryChannel = "message:delivery:channel"
	TriggerMessageDeliveryUser    = "message:delivery:user"

	ConfirmationTypeImmediate    = "immediate"
	ConfirmationTypeUserActivity = "userActivity"
	ConfirmationTypePrompt       = "prompt"

	ImageRatioHorizontal = ImageRatio("horizontal")
	ImageRatioSquare     = ImageRatio("square")

	SizeCompact = Size("compact")
	SizeLarge   = Size("large")
)
View Source
const JWTExpiration = 3600

JWTExpiration defines how many seconds jwt token is valid

Variables

View Source
var (
	ErrUserIDEmpty           = errors.New("user id is empty")
	ErrSurnameEmpty          = errors.New("surname is empty")
	ErrGivenNameEmpty        = errors.New("givenName is empty")
	ErrPhonenumberEmpty      = errors.New("phonenumber is empty")
	ErrChannelTypeEmpty      = errors.New("channel type is empty")
	ErrConfirmationTypeEmpty = errors.New("confirmation type is empty")
	ErrKeyIDEmpty            = errors.New("key id is empty")
	ErrSecretEmpty           = errors.New("secret is empty")
	ErrRedisNil              = errors.New("redis pool is nil")
	ErrMessageNil            = errors.New("message is nil")
	ErrMessageRoleEmpty      = errors.New("message.Role is empty")
	ErrMessageTypeEmpty      = errors.New("message.Type is empty")
	ErrDecodeToken           = errors.New("error decode token")
	ErrWrongAuth             = errors.New("error wrong authentication")
)

Functions

func GenerateJWT

func GenerateJWT(scope string, keyID string, secret string) (string, error)

Types

type Action

type Action struct {
	ID       string                 `json:"_id,omitempty"`
	Type     ActionType             `json:"type,omitempty"`
	Text     string                 `json:"text,omitempty"`
	Default  bool                   `json:"default,omitempty"`
	Payload  string                 `json:"payload,omitempty"`
	URI      string                 `json:"uri,omitempty"`
	Amount   int                    `json:"amount,omitempty"`
	Currency string                 `json:"currency,omitempty"`
	State    string                 `json:"state,omitempty"`
	Metadata map[string]interface{} `json:"metadata,omitempty"`
}

type ActionType

type ActionType string

type AppUser

type AppUser struct {
	ID                  string                 `json:"_id,omitempty"`
	UserID              string                 `json:"userId,omitempty"`
	Properties          map[string]interface{} `json:"properties,omitempty"`
	SignedUpAt          time.Time              `json:"signedUpAt,omitempty"`
	Clients             []*AppUserClient       `json:"clients,omitempty"`
	PendingClients      []*AppUserClient       `json:"pendingClients,omitempty"`
	ConversationStarted bool                   `json:"conversationStarted"`
	Email               string                 `json:"email,omitempty"`
	GivenName           string                 `json:"givenName,omitempty"`
	Surname             string                 `json:"surname,omitempty"`
	HasPaymentInfo      bool                   `json:"hasPaymentInfo,omitmepty"`
}

type AppUserClient added in v0.2.0

type AppUserClient struct {
	ID            string                 `json:"_id,omitempty"`
	Platform      string                 `json:"platform,omitempty"`
	IntegrationId string                 `json:"integrationId,omitempty"`
	Primary       bool                   `json:"primary"`
	Active        bool                   `json:"active"`
	DeviceID      string                 `json:"deviceId,omitempty"`
	DisplayName   string                 `json:"displayName,omitempty"`
	AvatarURL     string                 `json:"avatarUrl,omitempty"`
	Info          map[string]interface{} `json:"info,omitempty"`
	Raw           map[string]interface{} `json:"raw,omitempty"`
	AppVersion    string                 `json:"appVersion,omitempty"`
	LastSeen      time.Time              `json:"lastSeen,omitempty"`
	LinkedAt      time.Time              `json:"linkedAt,omitempty"`
	Blocked       bool                   `json:"blocked"`
}

type Application

type Application struct {
	ID string `json:"_id,omitempty"`
}

type Attachment added in v0.2.0

type Attachment struct {
	MediaURL  string `json:"mediaUrl"`
	MediaType string `json:"mediaType,omitempty"`
}

type AttachmentUpload added in v0.2.0

type AttachmentUpload struct {
	MIMEType string
	Access   string

	// optionals
	For       string
	AppUserID string
	UserID    string
}

func NewAttachmentUpload added in v0.2.0

func NewAttachmentUpload(mime string) AttachmentUpload

type BytesFileReader added in v0.2.0

type BytesFileReader struct {
	*bytes.Reader
	Filename string
}

func NewBytesFileReader added in v0.2.0

func NewBytesFileReader(filename string, b []byte) *BytesFileReader

type Client

type Client interface {
	Handler() http.Handler
	IsJWTExpired() (bool, error)
	RenewToken() (string, error)
	AddWebhookEventHandler(handler WebhookEventHandler)
	Send(userID string, message *Message) (*ResponsePayload, error)
	SendHSM(userID string, hsmMessage *HsmMessage) (*ResponsePayload, error)
	GetAppUser(userID string) (*AppUser, error)
	PreCreateAppUser(userID, surname, givenName string) (*AppUser, error)
	LinkAppUserToChannel(channelType, confirmationType, phoneNumber string) (*AppUser, error)
	UploadFileAttachment(filepath string, upload AttachmentUpload) (*Attachment, error)
	UploadAttachment(r io.Reader, upload AttachmentUpload) (*Attachment, error)
}

type Conversation

type Conversation struct {
	ID          string `json:"_id"`
	UnreadCount int    `json:"unreadCount,omitempty"`
}

type DisplaySettings

type DisplaySettings struct {
	ImageAspectRatio ImageRatio `json:"imageAspectRatio,omitempty"`
}

type Error added in v0.2.0

type Error struct {
	Code            string                 `json:"code"`
	UnderlyingError map[string]interface{} `json:"underlyingError"`
	Message         string                 `json:"message"`
}

type ErrorDetails

type ErrorDetails struct {
	Code        string `json:"code"`
	Description string `json:"description"`
}

type ErrorPayload

type ErrorPayload struct {
	Details ErrorDetails `json:"error"`
}

type GetAppUserResponse added in v0.2.0

type GetAppUserResponse struct {
	AppUser *AppUser `json:"appUser,omitempty"`
}

type HsmLanguage added in v0.4.0

type HsmLanguage struct {
	Policy string `json:"policy" mapstructure:"policy"`
	Code   string `json:"code" mapstructure:"code"`
}

HsmLanguage defines hsm language payload

type HsmLocalizableParams added in v0.4.0

type HsmLocalizableParams struct {
	Default interface{} `json:"default" mapstructure:"default"`
}

HsmLocalizableParams defines hsm localizable params data

type HsmMessage added in v0.4.0

type HsmMessage struct {
	Role          Role           `json:"role"`
	MessageSchema string         `json:"messageSchema"`
	Message       HsmMessageBody `json:"message"`
	Received      time.Time      `json:"received,omitempty"`
}

HsmMessage defines struct payload for Whatsapp HSM message

func (*HsmMessage) MarshalJSON added in v0.4.0

func (hm *HsmMessage) MarshalJSON() ([]byte, error)

MarshalJSON will marshall whatsapp HSM message

func (*HsmMessage) UnmarshalJSON added in v0.4.0

func (hm *HsmMessage) UnmarshalJSON(data []byte) error

UnmarshalJSON will unmarshall whatsapp HSM message

type HsmMessageBody added in v0.4.0

type HsmMessageBody struct {
	Type MessageType `json:"type" mapstructure:"type"`
	Hsm  HsmPayload  `json:"hsm" mapstructure:"hsm"`
}

HsmMessageBody defines property for HSM message

type HsmPayload added in v0.4.0

type HsmPayload struct {
	Namespace         string                 `json:"namespace" mapstructure:"namespace"`
	ElementName       string                 `json:"element_name" mapstructure:"element_name"`
	Language          HsmLanguage            `json:"language" mapstructure:"language"`
	LocalizableParams []HsmLocalizableParams `json:"localizable_params" mapstructure:"localizable_params"`
}

HsmPayload defines payload for hsm

type ImageRatio

type ImageRatio string

type Item

type Item struct {
	ID          string    `json:"_id,omitempty"`
	Title       string    `json:"title,omitempty"`
	Description string    `json:"description,omitempty"`
	Size        Size      `json:"size,omitempty"`
	MediaURL    string    `json:"mediaUrl,omitempty"`
	MediaType   string    `json:"mediaType,omitempty"`
	Actions     []*Action `json:"actions"`
}

type LinkAppConfirmationData added in v0.4.0

type LinkAppConfirmationData struct {
	Type string `json:"type"`
}

LinkAppConfirmationData defines

type LinkAppUserToChannelPayload added in v0.4.0

type LinkAppUserToChannelPayload struct {
	Type         string                  `json:"type"`
	Confirmation LinkAppConfirmationData `json:"confirmation"`
	PhoneNumber  string                  `json:"phoneNumber"`
}

LinkAppUserToChannelPayload will link app user to specified channel

type LinkAppUserToChannelResponse added in v0.4.0

type LinkAppUserToChannelResponse struct {
	AppUser *AppUser `json:"appUser,omitempty"`
}

LinkAppUserToChannelResponse defines reponse for link app user to channel request

type Logger

type Logger interface {
	Debugw(msg string, keysAndValues ...interface{})
	Infow(msg string, keysAndValues ...interface{})
	Errorw(msg string, keysAndValues ...interface{})
}
type Menu struct {
	Items []*MenuItem `json:"items"`
}
type MenuItem struct {
	ID   string `json:"_id,omitempty"`
	Type string `json:"type,omitempty"`
	Text string `json:"text,omitempty"`
	URI  string `json:"uri,omitempty"`
}
type MenuPayload struct {
	Menu Menu `json:"menu"`
}

type Message

type Message struct {
	ID              string                 `json:"_id,omitempty"`
	Type            MessageType            `json:"type"`
	Text            string                 `json:"text,omitempty"`
	Role            Role                   `json:"role"`
	AuthorID        string                 `json:"authorId,omitempty"`
	Name            string                 `json:"name,omitempty"`
	Received        time.Time              `json:"received,omitempty"`
	Source          *SourceDestination     `json:"source,omitempty"`
	MediaURL        string                 `json:"mediaUrl,omitempty"`
	Actions         []*Action              `json:"actions,omitempty"`
	Items           []*Item                `json:"items,omitempty"`
	Metadata        map[string]interface{} `json:"metadata,omitempty"`
	DisplaySettings *DisplaySettings       `json:"displaySettings,omitempty"`
}

func (*Message) MarshalJSON

func (m *Message) MarshalJSON() ([]byte, error)

func (*Message) UnmarshalJSON

func (m *Message) UnmarshalJSON(data []byte) error

type MessageType

type MessageType string

type Options

type Options struct {
	Auth       string
	AppID      string
	KeyID      string
	Secret     string
	WebhookURL string
	Mux        *http.ServeMux
	Logger     Logger
	Region     string
	HttpClient *http.Client
	RedisPool  *redis.Pool
}

type Payload

type Payload struct {
	Trigger      string             `json:"trigger,omitempty"`
	App          Application        `json:"app,omitempty"`
	Messages     []*Message         `json:"messages,omitempty"`
	AppUser      AppUser            `json:"appUser,omitempty"`
	Conversation Conversation       `json:"conversation,omitempty"`
	Destination  *SourceDestination `json:"destination,omitempty"`
	IsFinalEvent bool               `json:"isFinalEvent"`
	Message      *TruncatedMessage  `json:"message,omitempty"`
	Error        *Error             `json:"error,omitempty"`
	Version      string             `json:"version,omitempty"`
}

type PreCreateAppUserPayload added in v0.4.0

type PreCreateAppUserPayload struct {
	UserID    string `json:"userId"`
	Surname   string `json:"surname"`
	GivenName string `json:"givenName"`
}

PreCreateAppUserPayload defines payload for pre-create app user request

type PreCreateAppUserResponse added in v0.4.0

type PreCreateAppUserResponse struct {
	AppUser *AppUser `json:"appUser,omitempty"`
}

PreCreateAppUserResponse defines response for pre-create use request

type ResponseData added in v0.4.0

type ResponseData struct {
	HTTPCode int
	Flag     string
}

ResponseData defines data for every response

type ResponsePayload

type ResponsePayload struct {
	Message       *Message      `json:"message,omitempty"`
	ExtraMessages []*Message    `json:"extraMessages,omitempty"`
	Conversation  *Conversation `json:"conversation,omitempty"`
}

type Role

type Role string

type Size

type Size string

type SmoochClient added in v0.4.1

type SmoochClient struct {
	Mux                  *http.ServeMux
	Auth                 string
	AppID                string
	KeyID                string
	Secret               string
	Logger               Logger
	Region               string
	WebhookEventHandlers []WebhookEventHandler
	HttpClient           *http.Client
	Mtx                  sync.Mutex
	RedisStorage         *storage.RedisStorage
}

func New

func New(o Options) (*SmoochClient, error)

func (*SmoochClient) AddWebhookEventHandler added in v0.4.1

func (sc *SmoochClient) AddWebhookEventHandler(handler WebhookEventHandler)

func (*SmoochClient) DeleteAttachment added in v0.4.1

func (sc *SmoochClient) DeleteAttachment(attachment *Attachment) (*ResponseData, error)

func (*SmoochClient) GetAppUser added in v0.4.1

func (sc *SmoochClient) GetAppUser(userID string) (*AppUser, *ResponseData, error)

func (*SmoochClient) Handler added in v0.4.1

func (sc *SmoochClient) Handler() http.Handler

func (*SmoochClient) IsJWTExpired added in v0.4.1

func (sc *SmoochClient) IsJWTExpired() (bool, error)

IsJWTExpired will check whether Smooch JWT is expired or not.

func (*SmoochClient) LinkAppUserToChannel added in v0.4.1

func (sc *SmoochClient) LinkAppUserToChannel(userID, channelType, confirmationType, phoneNumber string) (*AppUser, *ResponseData, error)

LinkAppUserToChannel will link user to specifiied channel

func (*SmoochClient) PreCreateAppUser added in v0.4.1

func (sc *SmoochClient) PreCreateAppUser(userID, surname, givenName string) (*AppUser, *ResponseData, error)

PreCreateAppUser will register user to smooch

func (*SmoochClient) RenewToken added in v0.4.1

func (sc *SmoochClient) RenewToken() (string, error)

RenewToken will generate new Smooch JWT token.

func (*SmoochClient) Send added in v0.4.1

func (sc *SmoochClient) Send(userID string, message *Message) (*ResponsePayload, *ResponseData, error)

func (*SmoochClient) SendHSM added in v0.4.1

func (sc *SmoochClient) SendHSM(userID string, hsmMessage *HsmMessage) (*ResponsePayload, *ResponseData, error)

SendHSM will send message using Whatsapp HSM template

func (*SmoochClient) UploadAttachment added in v0.4.1

func (sc *SmoochClient) UploadAttachment(r io.Reader, upload AttachmentUpload) (*Attachment, *ResponseData, error)

func (*SmoochClient) UploadFileAttachment added in v0.4.1

func (sc *SmoochClient) UploadFileAttachment(filepath string, upload AttachmentUpload) (*Attachment, *ResponseData, error)

type SmoochError

type SmoochError struct {
	// contains filtered or unexported fields
}

func (*SmoochError) Code

func (e *SmoochError) Code() int

func (*SmoochError) Error

func (e *SmoochError) Error() string

type SourceDestination added in v0.2.0

type SourceDestination struct {
	Type              string `json:"type,omitempty"`
	Id                string `json:"id,omitempty"`
	IntegrationId     string `json:"integrationId,omitempty"`
	OriginalMessageId string `json:"originalMessageId,omitempty"`
}

type TruncatedMessage added in v0.2.0

type TruncatedMessage struct {
	ID string `json:"_id"`
}

type WebhookEventHandler

type WebhookEventHandler func(payload *Payload)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL