Skip to content

Commit

Permalink
feat: CreateBotUserRecord
Browse files Browse the repository at this point in the history
  • Loading branch information
trakhimenok committed Dec 19, 2023
1 parent a3d55d9 commit 305c20e
Show file tree
Hide file tree
Showing 8 changed files with 189 additions and 53 deletions.
37 changes: 37 additions & 0 deletions README-DB.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Bots Framework Database

The bot framework uses [dalgo](https://github.com/dal-go) (_Db Abstraction Layer in GO_) to work with different
databases in a unified way.

It was designed to be able to work with nested collections (e.g. with Firestore)
but thanks to `dalgo` it will be able to work with any database supported by `dalgo`.
Including relational SQL databases like MySQL, PostgreSQL, etc.

## Database structure

- `botPlafforms` collection
- `bots` collection
- `botUsers` collection
- `botChats` collection

In case if you use relational SQL databases, collections will be tables and documents will be rows.
The parent keys will be foreign key fields. You would not need `botPlafforms` & `bots` tables in this case.

- `botUsers` table
- Platform string field
- Bot string field
- `botChats` table
- Platform string field
- Bot string field

### botPlatforms collection

Contains the bot platforms like `telegram`, `whatsapp`, etc.

#### bots collection

Contains the bots. Each bot has a unique id.

##### botUsers collection

Contains the bot users. Each bot user has a unique id.
65 changes: 43 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
# 🏋️ Strongo [Bots Go Framework](https://github.com/bots-go-framework)

A [Go language](https://golang.org/) framework to develop bots for messengers.

Developed & shared by [Sneat-co](https://github.com/sneat-co) & [Strongo](https://github.com/strongo) teams
with usage of [dalgo](https://github.com/dal-go) library.
Developed & shared by [Sneat-co](https://github.com/sneat-co) & [Strongo](https://github.com/strongo) teams
with usage of [dalgo](https://github.com/dal-go) library.

**Reasons to use**:

* Same code can work across different messenger (_Telegram, Facebook Messenger, Viber, Skype, Line, Kik, WeChat, etc._)
* You can tune your code to a specific messenger's UX.
* i18n & l10n support (_multilingual_)
* Can be hosted in cloud or just as a standard Go HTTP server. Supports [AppEngine](https://cloud.google.com/appengine/) standard environment.
* It's fast

* Same code can work across different messenger (_Telegram, Facebook Messenger, Viber, Skype, Line, Kik, WeChat, etc._)
* You can tune your code to a specific messenger's UX.
* i18n & l10n support (_multilingual_)
* Can be hosted in cloud or just as a standard Go HTTP server. Supports [AppEngine](https://cloud.google.com/appengine/)
standard environment.
* It's fast

## ♺ Continuous Integration

[![Build and Test](https://github.com/strongo/bots-framework/actions/workflows/go.yml/badge.svg)](https://github.com/bots-go-framework/bots-fw/actions/workflows/go.yml)
[![Go Report Card](https://goreportcard.com/badge/github.com/strongo/bots-framework?cache=1)](https://goreportcard.com/report/github.com/strongo/bots-framework)
[![GoDoc](https://godoc.org/github.com/strongo/bots-framework?status.svg)](https://godoc.org/github.com/strongo/bots-framework)
[![Coverage Status](https://coveralls.io/repos/github/bots-go-framework/bots-fw/badge.svg?branch=main)](https://coveralls.io/github/bots-go-framework/bots-fw?branch=main) - [help with code coverage](https://github.com/bots-go-framework/bots-fw/issues/64) needed.
[![Coverage Status](https://coveralls.io/repos/github/bots-go-framework/bots-fw/badge.svg?branch=main)](https://coveralls.io/github/bots-go-framework/bots-fw?branch=main) - [help with code coverage](https://github.com/bots-go-framework/bots-fw/issues/64)
needed.

## 🍿 Usage

Expand Down Expand Up @@ -47,36 +50,54 @@ with usage of [dalgo](https://github.com/dal-go) library.
}

## 🤖 Sample bots built with Strongo Bots Framework

The best way to learn is to see examples of usage. Here is few:
* ⚫⚪ [**Reversi** game](https://github.com/prizarena/reversi) - open source game. (*Telegram: [@ReversiGameBot](https://t.me/ReversiGameBot)*)
* ✖️⭕ [**Bidding Tic-Tac-Toe**](https://github.com/prizarena/bidding-tictactoe) - open source game. (*Telegram: [@BiddingTicTacToeBot](https://t.me/BiddingTicTacToeBot)*)
* 📃✂️ [**Rock-Paper-Scissors**](https://github.com/prizarena/rock-paper-scissors) - open source game. (*Telegram: [@playRockPaperScissorsBot](https://t.me/playRockPaperScissorsBot)*)
* 💸📝 [**Debtus.app**](http://debtus.app/) — a bot & a reminder service that helps to track your debts & credits.

* ⚫⚪ [**Reversi** game](https://github.com/prizarena/reversi) - open source game. (
*Telegram: [@ReversiGameBot](https://t.me/ReversiGameBot)*)
* ✖️⭕ [**Bidding Tic-Tac-Toe**](https://github.com/prizarena/bidding-tictactoe) - open source game. (
*Telegram: [@BiddingTicTacToeBot](https://t.me/BiddingTicTacToeBot)*)
* 📃✂️ [**Rock-Paper-Scissors**](https://github.com/prizarena/rock-paper-scissors) - open source game. (
*Telegram: [@playRockPaperScissorsBot](https://t.me/playRockPaperScissorsBot)*)
* 💸📝 [**Debtus.app**](http://debtus.app/) — a bot & a reminder service that helps to track your debts & credits.
Sends automated reminders to you & your debtors (_in messenger, email, SMS_).

We would be happy to place a link to your example / bot that is implemented using this framework.

## 📦 Go API libraries used by the framework to talk to messengers

You can use any Bot API library by implementing couple of simple interface but the framework comes with few buildins:
* [bots-go-framework/bots-api-telegram](https://github.com/bots-go-framework/bots-api-telegram) - Go library for [**Telegram** Bot API](https://core.telegram.org/bots/api)
* [bots-go-framework/bots-api-fbm](https://github.com/bots-go-framework/bots-api-fbm) - Go library for [**Facebook Messenger** Bot API](https://developers.facebook.com/docs/messenger-platform)
* [bots-go-framework/bots-api-viber](https://github.com/bots-go-framework/bots-api-viber) - Go library for [**Viber** Bot API](https://developers.viber.com/)


* [bots-go-framework/bots-api-telegram](https://github.com/bots-go-framework/bots-api-telegram) - Go library for [*
*Telegram** Bot API](https://core.telegram.org/bots/api)
* [bots-go-framework/bots-api-fbm](https://github.com/bots-go-framework/bots-api-fbm) - Go library for [**Facebook
Messenger** Bot API](https://developers.facebook.com/docs/messenger-platform)
* [bots-go-framework/bots-api-viber](https://github.com/bots-go-framework/bots-api-viber) - Go library for [**Viber
** Bot API](https://developers.viber.com/)

## 📦 Other Go libraries used by the bot framework
* [dal-go/dalgo](https://github.com/dal-go/dalgo) - Database abstraction layer (DAL) in Go language
* [strongo/gamp](https://github.com/strongo/gamp) - Golang buffered client for Google Analytics (GA) Measurement Protocol

* [dal-go/dalgo](https://github.com/dal-go/dalgo) - Database abstraction layer (DAL) in Go language
* [strongo/gamp](https://github.com/strongo/gamp) - Golang buffered client for Google Analytics (GA) Measurement
Protocol

## [Can I use — features cross-table for bot messenger APIs](can-i-use-bots-api.md)

We are building a [cross-table of features](can-i-use-bots-api.md) supported by different bot APIs.

## Database Abstraction Layer (DAL)

Thanks to [dalgo](https://github.com/dal-go) library the framework can work with different databases.

The Db structure is described in [README-DB.md](README-DB.md).

## 🫂 Contributors
* [Alexander Trakhimenok](https://ie.linkedin.com/in/alexandertrakhimenok)

* [Alexander Trakhimenok](https://ie.linkedin.com/in/alexandertrakhimenok)

## 📰 Press

There are no articles about the Strongo Bots Framework just yet. Send us a link if you find such.

## 📜 [License](https://github.com/strongo/bots-framework/blob/master/LICENSE)

Licensed under Apache 2.0 license
3 changes: 3 additions & 0 deletions botsfw/botsdal/dal_bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,8 @@ const botsCollection = "bots"
// NewBotKey creates a dalgo key to specific bot record
func NewBotKey(platformID, botID string) *dal.Key {
platformKey := NewPlatformKey(platformID)
if botID == "" {
panic("botID is required parameter")
}
return dal.NewKeyWithParentAndID(platformKey, botsCollection, botID)
}
31 changes: 27 additions & 4 deletions botsfw/botsdal/dal_bot_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,46 @@ import (

const botUsersCollection = "botUsers"

// NewBotUserKey creates a dalgo key to specific bot user record
func NewBotUserKey(platformID, botID, botUserID string) *dal.Key {
botKey := NewBotKey(platformID, botID)
if botUserID == "" {
panic("botUserID is required parameter")
}
return dal.NewKeyWithParentAndID(botKey, botUsersCollection, botUserID)
}

// GetBotUser loads bot user data
func GetBotUser(
ctx context.Context,
tx dal.ReadSession,
platformID, botID, userID string,
platformID, botID, botUserID string,
newData func() botsfwmodels.BotUserData,
) (botUser record.DataWithID[string, botsfwmodels.BotUserData], err error) {
key := NewBotUserKey(platformID, botID, userID)
botUserKey := NewBotUserKey(platformID, botID, botUserID)
data := newData()
botUser = record.NewDataWithID(userID, key, data)
botUser = record.NewDataWithID(botUserID, botUserKey, data)
return botUser, tx.Get(ctx, botUser.Record)
}

// CreateBotUserRecord creates bot user record in database
func CreateBotUserRecord(
ctx context.Context,
tx dal.ReadwriteTransaction,
platformID, botID, botUserID string,
botUserData botsfwmodels.BotUserData,
) (err error) {
if validatableData, ok := botUserData.(interface{ Validate() error }); ok {
if err = validatableData.Validate(); err != nil {
return err
}
}
botUserKey := NewBotUserKey(platformID, botID, botUserID)
botUser := record.NewDataWithID(botUserID, botUserKey, botUserData)
err = tx.Insert(ctx, botUser.Record)
return err
}

//import (
// "context"
// "fmt"
Expand Down Expand Up @@ -114,7 +137,7 @@ func GetBotUser(
// })
//}
//
//func (store botUserStore) CreateBotUser(c context.Context, botID string, apiUser botsfw.WebhookActor) (botsfwmodels.BotUserData, error) {
//func (store botUserStore) CreateBotUserRecord(c context.Context, botID string, apiUser botsfw.WebhookActor) (botsfwmodels.BotUserData, error) {
// return store.createBotUser(c, botID, apiUser)
//}
//
Expand Down
58 changes: 51 additions & 7 deletions botsfw/botsdal/dal_bot_user_test.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
package botsdal

import (
"context"
"github.com/bots-go-framework/bots-fw-store/botsfwmodels"
"github.com/dal-go/dalgo/dal"
"github.com/dal-go/dalgo/record"
"testing"
)

func TestNewBotUserStore(t *testing.T) {
func TestGetBotUser(t *testing.T) {
type args struct {
//collection string
//platform string
//db DbProvider
//newBotUserData func(botID string) (botsfwmodels.BotUserData, error)
//createNewUser BotUserCreator
platform string
botID string
botUserID string
}
tests := []struct {
name string
args args
shouldPanic bool
checkResult func(botUser record.DataWithID[string, botsfwmodels.BotUserData], err error)
}{
{name: "empty", shouldPanic: true},
}
Expand All @@ -28,8 +32,48 @@ func TestNewBotUserStore(t *testing.T) {
}
}()
}
panic("temporary disabled")
//_ = newBotUserStore(tt.args.collection, tt.args.platform, tt.args.db, tt.args.newBotUserData, tt.args.createNewUser)
var tx dal.ReadwriteTransaction
botUser, err := GetBotUser(nil, tx, tt.args.platform, tt.args.botID, tt.args.botUserID, func() botsfwmodels.BotUserData {
return nil
})
tt.checkResult(botUser, err)
})
}
}

func TestCreateBotUserRecord(t *testing.T) {
type args struct {
platform string
botID string
botUserID string
botUserData botsfwmodels.BotUserData
}
tests := []struct {
name string
args args
shouldPanic bool
checkResult func(err error)
}{
{
name: "empty",
shouldPanic: true,
checkResult: func(err error) {
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctx := context.Background()
if tt.shouldPanic {
defer func() {
if r := recover(); r == nil {
t.Errorf("CreateBotUserRecord() did not panic")
}
}()
}
var tx dal.ReadwriteTransaction
err := CreateBotUserRecord(ctx, tx, tt.args.platform, tt.args.botID, tt.args.botUserID, tt.args.botUserData)
tt.checkResult(err)
})
}
}
3 changes: 3 additions & 0 deletions botsfw/botsdal/dal_platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@ import "github.com/dal-go/dalgo/dal"
const botPlatformsCollection = "botPlatforms"

func NewPlatformKey(platform string) *dal.Key {
if platform == "" {
panic("platform is required parameter")
}
return dal.NewKeyWithID(botPlatformsCollection, platform)
}
4 changes: 2 additions & 2 deletions botsfw/webhook_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ type WebhookContext interface { // TODO: Make interface much smaller?

AppUserID() string

// AppUserInt64ID TODO: Deprecate: use AppUserID() instead
AppUserInt64ID() int64
// AppUserInt64ID Deprecate: use AppUserID() instead
//AppUserInt64ID() int64

AppUserData() (botsfwmodels.AppUserData, error)
//SaveAppUser(appUserID int64, appUserEntity BotAppUser) error
Expand Down
Loading

0 comments on commit 305c20e

Please sign in to comment.