matterbridge/vendor/github.com/d5/tengo/objects/conversion.go
Wim 1bb39eba87
Add scripting (tengo) support for every incoming message (#731)
TengoModifyMessage allows you to specify the location of a tengo (https://github.com/d5/tengo/) script.
This script will receive every incoming message and can be used to modify the Username and the Text of that message.
The script will have the following global variables:
to modify: msgUsername and msgText
to read: msgChannel and msgAccount

The script is reloaded on every message, so you can modify the script on the fly.

Example script can be found in https://github.com/42wim/matterbridge/tree/master/gateway/bench.tengo
and https://github.com/42wim/matterbridge/tree/master/contrib/example.tengo

The example below will check if the text contains blah and if so, it'll replace the text and the username of that message.
text := import("text")
if text.re_match("blah",msgText) {
    msgText="replaced by this"
    msgUsername="fakeuser"
}

More information about tengo on: https://github.com/d5/tengo/blob/master/docs/tutorial.md and
https://github.com/d5/tengo/blob/master/docs/stdlib.md
2019-02-23 16:39:44 +01:00

250 lines
4.3 KiB
Go

package objects
import (
"fmt"
"strconv"
"time"
)
// ToString will try to convert object o to string value.
func ToString(o Object) (v string, ok bool) {
if o == UndefinedValue {
//ok = false
return
}
ok = true
if str, isStr := o.(*String); isStr {
v = str.Value
} else {
v = o.String()
}
return
}
// ToInt will try to convert object o to int value.
func ToInt(o Object) (v int, ok bool) {
switch o := o.(type) {
case *Int:
v = int(o.Value)
ok = true
case *Float:
v = int(o.Value)
ok = true
case *Char:
v = int(o.Value)
ok = true
case *Bool:
if o == TrueValue {
v = 1
}
ok = true
case *String:
c, err := strconv.ParseInt(o.Value, 10, 64)
if err == nil {
v = int(c)
ok = true
}
}
//ok = false
return
}
// ToInt64 will try to convert object o to int64 value.
func ToInt64(o Object) (v int64, ok bool) {
switch o := o.(type) {
case *Int:
v = o.Value
ok = true
case *Float:
v = int64(o.Value)
ok = true
case *Char:
v = int64(o.Value)
ok = true
case *Bool:
if o == TrueValue {
v = 1
}
ok = true
case *String:
c, err := strconv.ParseInt(o.Value, 10, 64)
if err == nil {
v = c
ok = true
}
}
//ok = false
return
}
// ToFloat64 will try to convert object o to float64 value.
func ToFloat64(o Object) (v float64, ok bool) {
switch o := o.(type) {
case *Int:
v = float64(o.Value)
ok = true
case *Float:
v = o.Value
ok = true
case *String:
c, err := strconv.ParseFloat(o.Value, 64)
if err == nil {
v = c
ok = true
}
}
//ok = false
return
}
// ToBool will try to convert object o to bool value.
func ToBool(o Object) (v bool, ok bool) {
ok = true
v = !o.IsFalsy()
return
}
// ToRune will try to convert object o to rune value.
func ToRune(o Object) (v rune, ok bool) {
switch o := o.(type) {
case *Int:
v = rune(o.Value)
ok = true
case *Char:
v = rune(o.Value)
ok = true
}
//ok = false
return
}
// ToByteSlice will try to convert object o to []byte value.
func ToByteSlice(o Object) (v []byte, ok bool) {
switch o := o.(type) {
case *Bytes:
v = o.Value
ok = true
case *String:
v = []byte(o.Value)
ok = true
}
//ok = false
return
}
// ToTime will try to convert object o to time.Time value.
func ToTime(o Object) (v time.Time, ok bool) {
switch o := o.(type) {
case *Time:
v = o.Value
ok = true
case *Int:
v = time.Unix(o.Value, 0)
ok = true
}
//ok = false
return
}
// objectToInterface attempts to convert an object o to an interface{} value
func objectToInterface(o Object) (res interface{}) {
switch o := o.(type) {
case *Int:
res = o.Value
case *String:
res = o.Value
case *Float:
res = o.Value
case *Bool:
res = o == TrueValue
case *Char:
res = o.Value
case *Bytes:
res = o.Value
case *Array:
res = make([]interface{}, len(o.Value))
for i, val := range o.Value {
res.([]interface{})[i] = objectToInterface(val)
}
case *Map:
res = make(map[string]interface{})
for key, v := range o.Value {
res.(map[string]interface{})[key] = objectToInterface(v)
}
case Object:
return o
}
return
}
// FromInterface will attempt to convert an interface{} v to a Tengo Object
func FromInterface(v interface{}) (Object, error) {
switch v := v.(type) {
case nil:
return UndefinedValue, nil
case string:
return &String{Value: v}, nil
case int64:
return &Int{Value: v}, nil
case int:
return &Int{Value: int64(v)}, nil
case bool:
if v {
return TrueValue, nil
}
return FalseValue, nil
case rune:
return &Char{Value: v}, nil
case byte:
return &Char{Value: rune(v)}, nil
case float64:
return &Float{Value: v}, nil
case []byte:
return &Bytes{Value: v}, nil
case error:
return &Error{Value: &String{Value: v.Error()}}, nil
case map[string]Object:
return &Map{Value: v}, nil
case map[string]interface{}:
kv := make(map[string]Object)
for vk, vv := range v {
vo, err := FromInterface(vv)
if err != nil {
return nil, err
}
kv[vk] = vo
}
return &Map{Value: kv}, nil
case []Object:
return &Array{Value: v}, nil
case []interface{}:
arr := make([]Object, len(v), len(v))
for i, e := range v {
vo, err := FromInterface(e)
if err != nil {
return nil, err
}
arr[i] = vo
}
return &Array{Value: arr}, nil
case time.Time:
return &Time{Value: v}, nil
case Object:
return v, nil
}
return nil, fmt.Errorf("cannot convert to object: %T", v)
}