Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support message attributes when sending and receiving messages #6

Merged
merged 1 commit into from
Jun 7, 2023
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,33 @@ object Mapper {
)
}

fun attributesToMap(attributes: Attributes): Map<String, Any> {
return mapOf(
"type" to "name.string",
"data" to "User"
)
fun attributesToMap(attributes: Attributes): Map<String, Any?> {
return when {
attributes.boolean != null -> mapOf(
"type" to "boolean",
"data" to attributes.boolean!!,
)
attributes.number != null -> mapOf(
"type" to "number",
"data" to attributes.number!!,
)
attributes.string != null -> mapOf(
"type" to "string",
"data" to attributes.string!!,
)
attributes.jsonArray != null -> mapOf(
"type" to "array",
"data" to "${attributes.jsonArray}",
)
attributes.jsonObject != null -> mapOf(
"type" to "object",
"data" to "${attributes.jsonObject}",
)
else -> mapOf(
"type" to "null",
"data" to null,
)
}
}

private fun channelsToMap(channels: List<Conversation>): Map<String, Any> {
Expand Down
6 changes: 4 additions & 2 deletions example/lib/redux/effects/twilio_middleware.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ class TwilioMiddleware extends EpicMiddleware<AppState> {
) =>
stream.asyncExpand((action) async* {
try {
final request = await action.channel.messages
?.sendMessage(MessageOptions()..withBody(action.text));
final request =
await action.channel.messages?.sendMessage(MessageOptions()
..withBody(action.text)
..withAttributes({'customKey': 'customValue'}));

if (request != null) {
print(
Expand Down
3 changes: 2 additions & 1 deletion example/lib/widgets/message_item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ class MessageItem extends StatelessWidget {
padding: const EdgeInsets.only(
bottom: 6,
),
child: Text('${message.author} @ ${message.dateCreated}'),
child: Text(
'${message.author} @ ${message.dateCreated} with ${message.attributes?.getJSONObject()}}'),
),
Container(
decoration: BoxDecoration(
Expand Down
6 changes: 6 additions & 0 deletions ios/Classes/Methods/MessagesMethods.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ public class MessagesMethods {
if (options["body"] != nil) {
messagePreparator.setBody(options["body"] as? String)
}

if (options["attributes"] as? [String: Any?] != nil) {
let attributesDict = options["attributes"] as? [String: Any?]
let attributes = TCHJsonAttributes.init(dictionary: attributesDict! as [AnyHashable: Any])
messagePreparator.setAttributes(attributes, error: nil)
}

if (options["input"] != nil && options["mimeType"] as? String != nil) {
let input = options["input"] as? String
Expand Down
6 changes: 4 additions & 2 deletions lib/src/attributes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ class Attributes {
Attributes(this._type, this._json);

factory Attributes.fromMap(Map<String, dynamic> map) {
var type = AttributesType.STRING;
return Attributes(type, 'DATA');
final type =
EnumToString.fromString(AttributesType.values, map['type'] ?? 'null') ??
AttributesType.NULL;
return Attributes(type, map['data'] ?? '');
}

Map<String, dynamic>? getJSONObject() {
Expand Down
133 changes: 133 additions & 0 deletions test/attributes_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_twilio_conversations/flutter_twilio_conversations.dart';

void main() {
setUpAll(() {});

group('.fromMap()', () {
const objectExample = {
'type': 'object',
'data': '{"key": "value"}',
};

const arrayExample = {
'type': 'array',
'data': '[{"key": "value"}, {"key1": "value1"}]',
};

const stringExample = {
'type': 'string',
'data': 'string',
};

const numberExample = {
'type': 'number',
'data': '123',
};

const booleanExample = {
'type': 'boolean',
'data': 'true',
};

const nullExample = {
'type': 'null',
'data': 'null',
};

const invalidExample = {
'invalid': 'invalid',
};

const invalidObjectExample = {
'type': 'object',
'data': 'not a json',
};

test('should construct from OBJECT', () async {
final object = Attributes.fromMap(objectExample);
expect(object.type, AttributesType.OBJECT);
expect(object.getBoolean(), isNull);
expect(object.getNumber(), isNull);
expect(object.getString(), isNull);
expect(object.getJSONArray(), isNull);
expect(object.getJSONObject(), isNotNull);
expect(object.getJSONObject(), {"key": "value"});
});

test('should construct from ARRAY', () async {
final array = Attributes.fromMap(arrayExample);
expect(array.type, AttributesType.ARRAY);
expect(array.getJSONObject(), isNull);
expect(array.getBoolean(), isNull);
expect(array.getNumber(), isNull);
expect(array.getString(), isNull);
expect(array.getJSONArray(), isNotNull);
expect(array.getJSONArray(), [
{"key": "value"},
{"key1": "value1"}
]);
});

test('should construct from STRING', () async {
final string = Attributes.fromMap(stringExample);
expect(string.type, AttributesType.STRING);
expect(string.getBoolean(), isNull);
expect(string.getNumber(), isNull);
expect(string.getJSONArray(), isNull);
expect(string.getJSONObject(), isNull);
expect(string.getString(), isNotNull);
expect(string.getString(), "string");
});

test('should construct from NUMBER', () async {
final number = Attributes.fromMap(numberExample);
expect(number.type, AttributesType.NUMBER);
expect(number.getBoolean(), isNull);
expect(number.getString(), isNull);
expect(number.getJSONArray(), isNull);
expect(number.getJSONObject(), isNull);
expect(number.getNumber(), isNotNull);
expect(number.getNumber(), 123);
});

test('should construct from BOOLEAN', () async {
final boolean = Attributes.fromMap(booleanExample);
expect(boolean.type, AttributesType.BOOLEAN);
expect(boolean.getNumber(), isNull);
expect(boolean.getString(), isNull);
expect(boolean.getJSONArray(), isNull);
expect(boolean.getJSONObject(), isNull);
expect(boolean.getBoolean(), isNotNull);
expect(boolean.getBoolean(), true);
});

test('should construct from NULL', () async {
final nullAttr = Attributes.fromMap(nullExample);
expect(nullAttr.type, AttributesType.NULL);
expect(nullAttr.getBoolean(), isNull);
expect(nullAttr.getNumber(), isNull);
expect(nullAttr.getString(), isNull);
expect(nullAttr.getJSONArray(), isNull);
expect(nullAttr.getJSONObject(), isNull);
});

test('should construct from invalid', () async {
final invalidAttr = Attributes.fromMap(invalidExample);
expect(invalidAttr.type, AttributesType.NULL);
expect(invalidAttr.getBoolean(), isNull);
expect(invalidAttr.getNumber(), isNull);
expect(invalidAttr.getString(), isNull);
expect(invalidAttr.getJSONArray(), isNull);
expect(invalidAttr.getJSONObject(), isNull);

final invalidObject = Attributes.fromMap(invalidObjectExample);
expect(invalidObject.type, AttributesType.OBJECT);
expect(invalidObject.getBoolean(), isNull);
expect(invalidObject.getNumber(), isNull);
expect(invalidObject.getString(), isNull);
expect(invalidObject.getJSONArray(), isNull);
expect(invalidObject.getJSONObject, throwsException);
});
});
}