import 'dart:async'; import 'package:color/color.dart'; import 'package:http/http.dart' as http; import 'slack_data.dart'; import 'package:dart_framework/utils/string_util.dart'; enum SlackBuildType { android, ios, windows, mac, web } class SlackSender { //Bot TOKEN final token = "xoxb-291006091297-QT2K1PCpwyX4b5wKk3AQew2G"; //API - https://api.slack.com/methods/chat.postMessage final urlMessagePost = "https://slack.com/api/chat.postMessage"; //API - https://api.slack.com/methods/files.upload final urlFileUplaod = "https://slack.com/api/files.upload"; String getValidatedUser(String? targetUser) { targetUser ??= "@channel"; if (targetUser.indexOf("@") != 0) targetUser = "@$targetUser"; return targetUser; } String getURL(String channel, DataSlack message, String? targetUser, {bool includeURL = true}) { targetUser = getValidatedUser(targetUser); var buffer = StringBuffer(); if (includeURL) { buffer.write(urlMessagePost); buffer.write('?'); } buffer.write('token=$token'); buffer.write('&channel=$channel'); var sendMessage = message.message == null ? '' : Uri.encodeComponent(' ${message.message!}'); buffer.write('&text=$targetUser$sendMessage'); if (message.blocks.isNotEmpty) { var json = message.getBlocks(); print(json); buffer.write('&blocks=${Uri.encodeComponent(message.getBlocks())}'); } if (message.attachments.isNotEmpty) { buffer.write( '&attachments=${Uri.encodeComponent(message.getAttachments())}'); } buffer.write('&link_names=true'); print(buffer.toString()); return buffer.toString(); } //단일 Attachment로 보낼시 Future send(String channel, SlackAttachment attachment, {String? targetUser, Function(String)? completeListener, Function(Exception)? errorListener}) async { var data = DataSlack(); data.attachments = [attachment]; return await sends(channel, data, targetUser: targetUser); } //복수의 Attachment로 보낼시 Future sends(String channel, DataSlack message, {String? targetUser, Function(String)? completeListener, Function(Object)? errorListener}) async { var c = Completer(); String url = getURL(channel, message, targetUser); var response = await http.get(Uri.parse(url)); if (response.statusCode < 300 && response.statusCode >= 200) { print(response.body); if (completeListener != null) completeListener(response.body); } else { if (errorListener != null) errorListener(response); } c.complete(); return c.future; } String getParameters(String channel, DataSlack message, {String? targetUser}) { return getURL(channel, message, targetUser, includeURL: false); } /// ****************** File Send ******************* http.MultipartRequest getPostForm( String url, String channel, String? targetUser) { var form = http.MultipartRequest('POST', Uri.parse(url)); targetUser = getValidatedUser(targetUser); form.fields['token'] = token; form.fields['channels'] = channel; return form; } Future sendFile(String channel, SlackFile file, {String? targetUser, Function(String)? completeListener, Function(Object)? errorListener}) async { var c = Completer(); var form = getPostForm(urlFileUplaod, channel, targetUser); form = await file.setFileData(form); var response = await form.send(); var result = await response.stream.bytesToString(); if (response.statusCode < 300 && response.statusCode >= 200) { if (completeListener != null) completeListener(result); } else { if (errorListener != null) errorListener(result); } c.complete(); return c.future; } /// ****************** Send template ******************* void sendTest() async { DataSlack message = DataSlack(); message.attachments = []; var attachment = SlackAttachment(); attachment.author_name = 'toki'; attachment.text = 'This is Test!!'; attachment.color = '#ff2f00'; attachment.fields = [ SlackField.withParam('Test1', 'Value1'), SlackField.withParam('Test2', 'Value2'), ]; message.attachments.add(attachment); attachment = SlackAttachment(); attachment.author_name = 'toki'; attachment.text = 'This is Test!!2'; attachment.color = '#0084ff'; attachment.fields = [ SlackField.withParam('Test3', 'Value3'), SlackField.withParam('Test4', 'Value4'), ]; message.attachments.add(attachment); await sends('app_notifier', message, targetUser: 'toki'); } Future sendBuild(String appName, SlackBuildType buildType, Color color, String version, String downloadURL, {String channel = 'build'}) async { final buildURL = 'http://toki-labs.com/build/'; String thumUrl = buildType == SlackBuildType.android ? '${buildURL}android.png' : '${buildURL}appstore.png'; String projectIcon = "$buildURL$appName/icon.png"; // ignore: unused_local_variable String emoji = buildType == SlackBuildType.android ? ":android1: " : ":ios0: "; String osColor = buildType == SlackBuildType.ios ? "#ED145B" : "#81CA3F"; var message = DataSlack(); var attachments = message.attachments; var attachment = SlackAttachment(); attachment.color = color.toHexColor().toCssString(); attachment.fields = [SlackField.withParam(toPascal(appName), null)]; attachments.add(attachment); var buildTypeStr = buildTypeToString(buildType); attachment = SlackAttachment(); attachment.color = osColor; attachment.author_name = /*emoji +*/ buildTypeStr; attachment.author_icon = thumUrl; attachment.thumb_url = projectIcon; attachment.fields = [ SlackField.withParam(null, "Successfully build $buildTypeStr binary file.\nBuild version: *$version*") ]; attachment.actions = [ SlackAction.withParam( 'build', 'Download', downloadURL, null, SlackActionType.button, null) ]; attachments.add(attachment); return await sends(channel, message); } String buildTypeToString(SlackBuildType type) { var typeStr = type.name; return typeStr == 'ios' ? 'iOS' : toPascal(typeStr); } }