Skip to content

Commit

Permalink
Refactoring (#13)
Browse files Browse the repository at this point in the history
Made Action trigger type type safer by introducing ActionTrigger
interface. Renamed some enums and their values. Removed some comments.

Signed-off-by: Milos Gajdos <milosthegajdos@gmail.com>
  • Loading branch information
milosgajdos authored Jun 22, 2024
1 parent 6f78484 commit b03a00c
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 52 deletions.
14 changes: 6 additions & 8 deletions account_connections.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import (
type AccountConnType string

const (
OpenAIConnType AccountConnType = "account_connection_openai"
TwilioConnType AccountConnType = "account_connection_twilio"
AccountConnOpenAI AccountConnType = "account_connection_openai"
AccountConnTwilio AccountConnType = "account_connection_twilio"
)

type OpenAICreds struct {
Expand Down Expand Up @@ -47,14 +47,12 @@ type TelAccountConn struct {
}

func (ta *TelAccountConn) UnmarshalJSON(data []byte) error {
// Check if the data is a plain string ID
var id string
if err := json.Unmarshal(data, &id); err == nil {
ta.ID = id
return nil
}

// Otherwise, unmarshal as a full TelAccountConn object
type Alias TelAccountConn
aux := &struct {
*Alias
Expand Down Expand Up @@ -144,13 +142,13 @@ func (a *AccountConn) UnmarshalJSON(data []byte) error {
a.AccountConnsBase = base

switch a.Type {
case OpenAIConnType:
case AccountConnOpenAI:
var openaiAccount OpenAIAccount
if err := json.Unmarshal(data, &openaiAccount); err != nil {
return err
}
a.OpenAIAccount = &openaiAccount
case TwilioConnType:
case AccountConnTwilio:
var twillioAccount TwilioAccount
if err := json.Unmarshal(data, &twillioAccount); err != nil {
return err
Expand All @@ -171,15 +169,15 @@ func (a AccountConnReqBase) MarshalJSON() ([]byte, error) {
type Alias AccountConnReqBase

switch a.Type {
case OpenAIConnType:
case AccountConnOpenAI:
return json.Marshal(&struct {
*Alias
*OpenAIAccount
}{
Alias: (*Alias)(&a),
OpenAIAccount: a.OpenAIAccount,
})
case TwilioConnType:
case AccountConnTwilio:
return json.Marshal(&struct {
*Alias
*TwilioAccount
Expand Down
54 changes: 34 additions & 20 deletions actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ import (
"github.com/milosgajdos/go-vocode/request"
)

// ActionTrigger must be implemented by
// all action triggers.
type ActionTrigger interface {
TriggerType() TriggerType
}

type TriggerType string

const (
Expand All @@ -21,7 +27,7 @@ const (
type PhraseCondition string

const (
PhraseTypeContains PhraseCondition = "phrase_condition_type_contains"
PhraseCondTypeContains PhraseCondition = "phrase_condition_type_contains"
)

type Phrase struct {
Expand All @@ -38,20 +44,28 @@ type PhraseTrigger struct {
Config *PhraseTriggerConfig `json:"config"`
}

func (p *PhraseTrigger) TriggerType() TriggerType {
return PhraseTriggerType
}

type FnCallTrigger struct {
Type TriggerType `json:"type"`
Config map[string]any `json:"config"`
}

func (f *FnCallTrigger) TriggerType() TriggerType {
return FnCallTriggerType
}

type ActionType string

const (
TransferCallActionType ActionType = "action_transfer_call"
EndConversationActionType ActionType = "action_end_conversation"
DtmfActionType ActionType = "action_dtmf"
AddToConferenceActionType ActionType = "action_add_to_conference"
SetHoldActionType ActionType = "action_set_hold"
ExternalActionType ActionType = "action_external"
ActionDTMF ActionType = "action_dtmf"
ActionSetHold ActionType = "action_set_hold"
ActionExternal ActionType = "action_external"
ActionTransferCall ActionType = "action_transfer_call"
ActionEndConversation ActionType = "action_end_conversation"
ActionAddToConference ActionType = "action_add_to_conference"
)

type TransferCallActionConfig struct {
Expand Down Expand Up @@ -110,10 +124,10 @@ type ExternalAction struct {
}

type ActionBase struct {
ID string `json:"id"`
UserID string `json:"user_id"`
Type ActionType `json:"type"`
Trigger interface{} `json:"action_trigger"`
ID string `json:"id"`
UserID string `json:"user_id"`
Type ActionType `json:"type"`
Trigger ActionTrigger `json:"action_trigger"`
}

type Action struct {
Expand All @@ -127,9 +141,9 @@ type Actions struct {
}

type ActionReqBase struct {
Type ActionType `json:"type"`
Config interface{} `json:"config"`
Trigger interface{} `json:"action_trigger"`
Type ActionType `json:"type"`
Trigger ActionTrigger `json:"action_trigger"`
Config interface{} `json:"config"`
}

type CreateActionReq struct {
Expand Down Expand Up @@ -181,37 +195,37 @@ func (a *Action) UnmarshalJSON(data []byte) error {
}

switch a.Type {
case TransferCallActionType:
case ActionTransferCall:
var config TransferCallActionConfig
if err := json.Unmarshal(aux.RawConfig, &config); err != nil {
return err
}
a.Config = &config
case EndConversationActionType:
case ActionEndConversation:
var config map[string]interface{}
if err := json.Unmarshal(aux.RawConfig, &config); err != nil {
return err
}
a.Config = config
case DtmfActionType:
case ActionDTMF:
var config map[string]interface{}
if err := json.Unmarshal(aux.RawConfig, &config); err != nil {
return err
}
a.Config = config
case AddToConferenceActionType:
case ActionAddToConference:
var config AddToConfConfig
if err := json.Unmarshal(aux.RawConfig, &config); err != nil {
return err
}
a.Config = &config
case SetHoldActionType:
case ActionSetHold:
var config map[string]interface{}
if err := json.Unmarshal(aux.RawConfig, &config); err != nil {
return err
}
a.Config = config
case ExternalActionType:
case ActionExternal:
var config ExternalActionConfig
if err := json.Unmarshal(aux.RawConfig, &config); err != nil {
return err
Expand Down
4 changes: 2 additions & 2 deletions examples/account_connections/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func main() {

oaiConnReq := &vocode.CreateAccountConnReq{
AccountConnReqBase: vocode.AccountConnReqBase{
Type: vocode.OpenAIConnType,
Type: vocode.AccountConnOpenAI,
OpenAIAccount: &vocode.OpenAIAccount{
Creds: &vocode.OpenAICreds{
APIKey: oaiAPIKey,
Expand All @@ -50,7 +50,7 @@ func main() {

twillioConnReq := &vocode.CreateAccountConnReq{
AccountConnReqBase: vocode.AccountConnReqBase{
Type: vocode.TwilioConnType,
Type: vocode.AccountConnTwilio,
TwilioAccount: &vocode.TwilioAccount{
Creds: &vocode.TwilioCreds{
AccountID: twillioAccountID,
Expand Down
25 changes: 20 additions & 5 deletions examples/actions/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,41 @@ package main

import (
"context"
"flag"
"log"

"github.com/milosgajdos/go-vocode"
)

var (
phoneNr string
)

func init() {
flag.StringVar(&phoneNr, "phone-nr", "", "phone number")
}

func main() {
flag.Parse()

if phoneNr == "" {
log.Fatal("must specify phone number")
}

client := vocode.NewClient()
ctx := context.Background()

extActionReq := &vocode.CreateActionReq{
ActionReqBase: vocode.ActionReqBase{
Type: vocode.ExternalActionType,
Type: vocode.ActionExternal,
Config: vocode.ExternalActionConfig{
ProcessingMode: vocode.MutedProcessing,
Name: "Baseconfig",
Description: "Some description",
URL: "https://foobar.com",
InputSchema: map[string]any{},
},
Trigger: vocode.FnCallTrigger{
Trigger: &vocode.FnCallTrigger{
Type: vocode.FnCallTriggerType,
Config: map[string]any{},
},
Expand All @@ -36,11 +51,11 @@ func main() {

trCallActionReq := &vocode.CreateActionReq{
ActionReqBase: vocode.ActionReqBase{
Type: vocode.TransferCallActionType,
Type: vocode.ActionTransferCall,
Config: vocode.TransferCallActionConfig{
PhoneNr: "+19517449404",
PhoneNr: phoneNr,
},
Trigger: vocode.FnCallTrigger{
Trigger: &vocode.FnCallTrigger{
Type: vocode.FnCallTriggerType,
Config: map[string]any{},
},
Expand Down
2 changes: 1 addition & 1 deletion examples/prompts/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func main() {
Content: "You are a voice assistant that answers questions about coding",
Fields: []vocode.Field{
{
Type: vocode.FieldTypeEmail,
Type: vocode.EmailFieldType,
Label: "Foo",
Name: "FooPrompt",
Desc: "Example prompt",
Expand Down
6 changes: 3 additions & 3 deletions examples/webhooks/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ func main() {
whCreateReq := &vocode.CreateWebhookReq{
WebhookReqBase: vocode.WebhookReqBase{
Subs: []vocode.Event{
vocode.EventMessage,
vocode.EventAction,
vocode.MessageEvent,
vocode.ActionEvent,
},
URL: "https://foobar.com",
Method: vocode.Post,
Method: vocode.PostWebhook,
},
}

Expand Down
4 changes: 1 addition & 3 deletions prompts.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
type FieldType string

const (
FieldTypeEmail FieldType = "field_type_email"
EmailFieldType FieldType = "field_type_email"
)

type Field struct {
Expand Down Expand Up @@ -45,14 +45,12 @@ type Prompt struct {
}

func (p *Prompt) UnmarshalJSON(data []byte) error {
// Check if the data is a plain string ID
var id string
if err := json.Unmarshal(data, &id); err == nil {
p.ID = id
return nil
}

// Otherwise, unmarshal as a full TelAccountConn object
type Alias Prompt
aux := &struct {
*Alias
Expand Down
20 changes: 10 additions & 10 deletions webhooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@ import (
type Event string

const (
EventMessage Event = "event_message"
EventAction Event = "event_action"
EventCallConnected Event = "event_phone_call_connected"
EventCallEnded Event = "event_phone_call_ended"
EventCallDidntConnect Event = "event_phone_call_did_not_connect"
EventTranscript Event = "event_transcript"
EventRecording Event = "event_recording"
EventHumanDetection Event = "event_human_detection"
MessageEvent Event = "event_message"
ActionEvent Event = "event_action"
CallConnectedEvent Event = "event_phone_call_connected"
CallEndedEvent Event = "event_phone_call_ended"
CallDidntConnectEvent Event = "event_phone_call_did_not_connect"
TranscriptEvent Event = "event_transcript"
RecordingEvent Event = "event_recording"
HumanDetectionEvent Event = "event_human_detection"
)

type WebhookMethod string

const (
Get WebhookMethod = "GET"
Post WebhookMethod = "POST"
GetWebhook WebhookMethod = "GET"
PostWebhook WebhookMethod = "POST"
)

type Webhooks struct {
Expand Down

0 comments on commit b03a00c

Please sign in to comment.