Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 30 additions & 15 deletions .github/workflows/release-branch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ jobs:
env:
CLIENT_VERSION: ${{ github.event.client_payload.version }}
INPUT_VERSION: ${{ inputs.version }}

run: |
set -euo pipefail
version="${CLIENT_VERSION:-$INPUT_VERSION}"
Expand All @@ -53,46 +54,60 @@ jobs:
client-id: ${{ vars.DELIVERY_BOT_CLIENT_ID }}
private-key: ${{ secrets.DELIVERY_BOT_APP_PEM }}

- name: Create release branch
uses: peterjgrainger/action-create-branch@v3.0.0
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
with:
branch: ${{ steps.version.outputs.value }}

- name: Checkout release branch
- name: Checkout
uses: actions/checkout@v7
with:
ref: ${{ steps.version.outputs.value }}
token: ${{ steps.app-token.outputs.token }}

- name: Create release branch
env:
VERSION: ${{ steps.version.outputs.value }}

run: |
set -euo pipefail

# re-runs are expected: continue from an existing release branch instead of rewinding it
if git ls-remote --exit-code --heads origin "$VERSION" >/dev/null 2>&1; then
echo "branch $VERSION already exists; continuing from it"
git fetch --depth=1 origin "+refs/heads/$VERSION:refs/remotes/origin/$VERSION"
git switch -c "$VERSION" "origin/$VERSION"
else
git switch -c "$VERSION"
fi

- name: Pin buf inputs to the release branch
env:
VERSION: ${{ steps.version.outputs.value }}
GIT_USERNAME: ${{ steps.app-token.outputs.user-name }}
GIT_EMAIL: ${{ steps.app-token.outputs.user-email }}

run: |
set -euo pipefail

# pin every buf.gen*.yaml input that tracks webitel/protos to the release branch
changed=0
while IFS= read -r f; do
if grep -q 'git_repo: "https://github.com/webitel/protos"' "$f"; then
sed -i -E "s#^([[:space:]]*branch:[[:space:]]*\")main(\")#\1${VERSION}\2#" "$f"
echo "pinned $f -> $VERSION"
changed=1
fi
done < <(find . -type f -name 'buf.gen*.yaml')

if [ "$changed" = "0" ]; then
if git diff --quiet; then
echo "no buf.gen*.yaml references webitel/protos; nothing to pin"
exit 0
fi

git config user.name "$GIT_USERNAME"
git config user.email "$GIT_EMAIL"
git add -A

# [skip ci]: pin does not affect the build (generated code is committed)
git commit -m "chore: pin buf inputs to $VERSION [skip ci]"
git commit -m "chore: pin buf inputs to $VERSION"

- name: Push release branch
env:
VERSION: ${{ steps.version.outputs.value }}

run: |
set -euo pipefail

git push origin "HEAD:refs/heads/$VERSION"
echo "branch $VERSION is at $(git rev-parse HEAD)"
26 changes: 26 additions & 0 deletions app/cc/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"

"github.com/webitel/engine/gen/cc"
"github.com/webitel/engine/gen/engine"
"github.com/webitel/engine/model"
"github.com/webitel/engine/pkg/wbt"
)

Expand All @@ -26,6 +28,30 @@ func (api *agentApi) Online(domainId, agentId int64, onDemand bool) error {
return err
}

func (api *agentApi) OnlineWithStatus(ctx context.Context, r *model.AgentLoginRequest) error {
var onlineStatus *engine.Lookup
if r.OnlineStatus != nil {
onlineStatus = &engine.Lookup{
Id: int64(r.OnlineStatus.Id),
Name: r.OnlineStatus.Name,
}
}

if _, err := api.Api.Online(
ctx,
&cc.OnlineRequest{
AgentId: r.AgentID,
OnDemand: r.OnDemand,
DomainId: r.DomainID,
OnlineSkill: onlineStatus,
},
); err != nil {
return err
}

return nil
}

func (api *agentApi) Offline(domainId, agentId int64) error {
_, err := api.Api.Offline(context.TODO(), &cc.OfflineRequest{
AgentId: agentId,
Expand Down
2 changes: 2 additions & 0 deletions app/cc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"sync"

"github.com/webitel/engine/gen/cc"
"github.com/webitel/engine/model"
"github.com/webitel/engine/pkg/wbt"
"github.com/webitel/wlog"
)
Expand All @@ -13,6 +14,7 @@ const ServiceName = "call_center"

type AgentApi interface {
Online(domainId, agentId int64, onDemand bool) error
OnlineWithStatus(ctx context.Context, r *model.AgentLoginRequest) error
Offline(domainId, agentId int64) error
Pause(domainId, agentId int64, payload, statusComment string, timeout int) error

Expand Down
8 changes: 8 additions & 0 deletions app/cc_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,14 @@ func (a *App) AgentCC(ctx context.Context, domainId int64, userId int64) (*model
return a.Store.Agent().AgentCC(ctx, domainId, userId)
}

func (a *App) LoginAgentFromRequest(ctx context.Context, r *model.AgentLoginRequest) model.AppError {
if err := a.cc.Agent().OnlineWithStatus(ctx, r); err != nil {
return model.NewBadRequestError("app.agent.login.app_err", err.Error())
}

return nil
}

func (a *App) LoginAgent(domainId, agentId int64, onDemand bool) model.AppError {
err := a.cc.Agent().Online(domainId, agentId, onDemand)
if err != nil {
Expand Down
16 changes: 9 additions & 7 deletions app/event_trigger.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ import (
"context"
"encoding/json"
"fmt"
"strconv"
"strings"
"sync/atomic"
"time"

amqp "github.com/rabbitmq/amqp091-go"
"github.com/webitel/engine/app/flow"
"github.com/webitel/engine/model"
"github.com/webitel/engine/store"
"github.com/webitel/engine/utils"
"github.com/webitel/wlog"
"strconv"
"strings"
"sync/atomic"
"time"
)

const (
Expand Down Expand Up @@ -236,10 +237,10 @@ func (ct *TriggerEventMQ) processedMessages(messages <-chan amqp.Delivery) {
rs.variables["action"] = event
job, err := ct.store.Trigger().CreateJob(ctx, rs.domainId, rs.triggerId, rs.variables)
if err != nil {
ct.log.Error(fmt.Sprintf("could not create job: %v: %s", rs, err.Error()))
ct.log.Error("creating trigger job", wlog.Any("request", rs), wlog.Err(err))
return
}
ct.log.Info(fmt.Sprintf("started trigger \"%s\" job_id : %d", rs.name, job.Id))
ct.log.Info("started trigger", wlog.String("name", rs.name), wlog.Int64("job_id", job.Id))
}
}
}
Expand Down Expand Up @@ -317,7 +318,8 @@ func (ct *TriggerEventMQ) initQueue() error {
true,
false,
false,
false, amqp.Table{"x-queue-type": "quorum"},
false,
amqp.Table{"x-queue-type": "quorum"},
)
if err != nil {
return fmt.Errorf("could not create queue %s: %w", ct.config.Queue, err)
Expand Down
37 changes: 37 additions & 0 deletions app/online_skills.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package app

import (
"context"

"github.com/webitel/engine/model"
)

func (app *App) CreateOnlineSkills(ctx context.Context, preset *model.OnlineSkills) (*model.OnlineSkills, model.AppError) {
preset.PreSave()

return app.Store.OnlineSkills().Create(ctx, preset)
}

func (app *App) GetOnlineSkills(ctx context.Context, query *model.GetSkillPresetQuery) (*model.OnlineSkills, model.AppError) {
return app.Store.OnlineSkills().Get(ctx, query)
}

func (app *App) SearchOnlineSkills(ctx context.Context, query *model.SearchOnlineSkillsQuery) ([]*model.OnlineSkills, model.AppError) {
return app.Store.OnlineSkills().Search(ctx, query)
}

func (app *App) UpdateOnlineSkills(ctx context.Context, cmd *model.OnlineSkills) (*model.OnlineSkills, model.AppError) {
cmd.PreSave()

return app.Store.OnlineSkills().Update(ctx, cmd)
}

func (app *App) PatchOnlineSkills(ctx context.Context, cmd *model.PatchOnlineSkillsCmd) (*model.OnlineSkills, model.AppError) {
cmd.PrePatch()

return app.Store.OnlineSkills().Patch(ctx, cmd)
}

func (app *App) DeleteOnlineSkills(ctx context.Context, cmd *model.DeleteSkillPresetCmd) model.AppError {
return app.Store.OnlineSkills().Delete(ctx, cmd)
}
37 changes: 0 additions & 37 deletions app/skill_preset_store.go

This file was deleted.

22 changes: 22 additions & 0 deletions controller/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,28 @@ func (c *Controller) GetAgentSession(ctx context.Context, session *auth_manager.
return c.app.GetAgentSession(ctx, session.Domain(domainId), userId)
}

func (c *Controller) LoginAgentFromRequest(ctx context.Context, session *auth_manager.Session, r *model.AgentLoginRequest) model.AppError {
if err := r.Validate(); err != nil {
return err
}

permission := session.GetPermission(model.PERMISSION_SCOPE_CC_AGENT)
if !permission.CanRead() {
return c.app.MakePermissionError(session, permission, auth_manager.PERMISSION_ACCESS_READ)
}

if session.UseRBAC(auth_manager.PERMISSION_ACCESS_READ, permission) {
if perm, err := c.app.AgentCheckAccess(ctx, session.Domain(r.DomainID), r.AgentID, session.GetAclRoles(), auth_manager.PERMISSION_ACCESS_READ); err != nil {
return err
} else if !perm {
return c.app.MakeResourcePermissionError(session, r.AgentID, permission, auth_manager.PERMISSION_ACCESS_READ)
}
}

return c.app.LoginAgentFromRequest(ctx, r)
}

// DEPRECATED
func (c *Controller) LoginAgent(ctx context.Context, session *auth_manager.Session, domainId, agentId int64, onDemand bool) model.AppError {
permission := session.GetPermission(model.PERMISSION_SCOPE_CC_AGENT)
if !permission.CanRead() {
Expand Down
Loading
Loading