Convert a ChatEmbed to an IEmbed parameters.
1020 {
1021 if (embed == null)
1022 return default;
1023
1024 var embedErrors = new List<string>();
1025 Optional<Color> colour = default;
1026 if (embed.Colour != null)
1027 if (Int32.TryParse(embed.Colour[1..], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var argb))
1028 colour = Color.FromArgb(argb);
1029 else
1030 embedErrors.Add(
1031 String.Format(
1032 CultureInfo.InvariantCulture,
1033 "Invalid embed colour: {0}",
1034 embed.Colour));
1035
1036 if (embed.Author != null && String.IsNullOrWhiteSpace(embed.Author.Name))
1037 {
1038 embedErrors.Add("Null or whitespace embed author name!");
1039 embed.Author = null;
1040 }
1041
1042 List<IEmbedField>? fields = null;
1043 if (embed.Fields != null)
1044 {
1045 fields = new List<IEmbedField>();
1046 var i = -1;
1047 foreach (var field in embed.Fields)
1048 {
1049 ++i;
1050 var invalid = false;
1051 if (String.IsNullOrWhiteSpace(field.Name))
1052 {
1053 embedErrors.Add(
1054 String.Format(
1055 CultureInfo.InvariantCulture,
1056 "Null or whitespace field name at index {0}!",
1057 i));
1058 invalid = true;
1059 }
1060
1061 if (String.IsNullOrWhiteSpace(field.Value))
1062 {
1063 embedErrors.Add(
1064 String.Format(
1065 CultureInfo.InvariantCulture,
1066 "Null or whitespace field value at index {0}!",
1067 i));
1068 invalid = true;
1069 }
1070
1071 if (invalid)
1072 continue;
1073
1074 fields.Add(new EmbedField(field.Name!, field.Value!)
1075 {
1076 IsInline = field.IsInline ?? default(Optional<bool>),
1077 });
1078 }
1079 }
1080
1081 if (embed.Footer != null && String.IsNullOrWhiteSpace(embed.Footer.Text))
1082 {
1083 embedErrors.Add("Null or whitespace embed footer text!");
1084 embed.Footer = null;
1085 }
1086
1087 if (embed.Image != null && String.IsNullOrWhiteSpace(embed.Image.Url))
1088 {
1089 embedErrors.Add("Null or whitespace embed image url!");
1090 embed.Image = null;
1091 }
1092
1093 if (embed.Thumbnail != null && String.IsNullOrWhiteSpace(embed.Thumbnail.Url))
1094 {
1095 embedErrors.Add("Null or whitespace embed thumbnail url!");
1096 embed.Thumbnail = null;
1097 }
1098
1099 Optional<DateTimeOffset> timestampOptional = default;
1100 if (embed.Timestamp != null)
1101 if (DateTimeOffset.TryParse(embed.Timestamp, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out var timestamp))
1102 timestampOptional = timestamp.ToUniversalTime();
1103 else
1104 embedErrors.Add(
1105 String.Format(
1106 CultureInfo.InvariantCulture,
1107 "Invalid embed timestamp: {0}",
1108 embed.Timestamp));
1109
1110 var discordEmbed = new Embed
1111 {
1112 Author = embed.Author != null
1113 ? new EmbedAuthor(embed.Author.Name!)
1114 {
1115 IconUrl = embed.Author.IconUrl ?? default(Optional<string>),
1116 ProxyIconUrl = embed.Author.ProxyIconUrl ?? default(Optional<string>),
1117 Url = embed.Author.Url ?? default(Optional<string>),
1118 }
1119 : default(Optional<IEmbedAuthor>),
1120 Colour = colour,
1121 Description = embed.Description ?? default(Optional<string>),
1122 Fields = fields ??
default(
Optional<IReadOnlyList<IEmbedField>>),
1123 Footer = embed.Footer != null
1124 ? (Optional<IEmbedFooter>)new EmbedFooter(embed.Footer.Text!)
1125 {
1126 IconUrl = embed.Footer.IconUrl ?? default(Optional<string>),
1127 ProxyIconUrl = embed.Footer.ProxyIconUrl ?? default(Optional<string>),
1128 }
1129 : default,
1130 Image = embed.Image != null
1131 ? new EmbedImage(embed.Image.Url!)
1132 {
1133 Width = embed.Image.Width ?? default(Optional<int>),
1134 Height = embed.Image.Height ?? default(Optional<int>),
1135 ProxyUrl = embed.Image.ProxyUrl ?? default(Optional<string>),
1136 }
1137 : default(Optional<IEmbedImage>),
1138 Provider = embed.Provider != null
1139 ? new EmbedProvider
1140 {
1141 Name = embed.Provider.Name ?? default(Optional<string>),
1142 Url = embed.Provider.Url ?? default(Optional<string>),
1143 }
1144 : default(Optional<IEmbedProvider>),
1145 Thumbnail = embed.Thumbnail != null
1146 ? new EmbedThumbnail(embed.Thumbnail.Url!)
1147 {
1148 Width = embed.Thumbnail.Width ?? default(Optional<int>),
1149 Height = embed.Thumbnail.Height ?? default(Optional<int>),
1150 ProxyUrl = embed.Thumbnail.ProxyUrl ?? default(Optional<string>),
1151 }
1152 : default(Optional<IEmbedThumbnail>),
1153 Timestamp = timestampOptional,
1154 Title = embed.Title ?? default(Optional<string>),
1155 Url = embed.Url ?? default(Optional<string>),
1156 Video = embed.Video != null
1157 ? new EmbedVideo
1158 {
1159 Url = embed.Video.Url ?? default(Optional<string>),
1160 Width = embed.Video.Width ?? default(Optional<int>),
1161 Height = embed.Video.Height ?? default(Optional<int>),
1162 ProxyUrl = embed.Video.ProxyUrl ?? default(Optional<string>),
1163 }
1164 : default(Optional<IEmbedVideo>),
1165 };
1166
1167 var result = new List<IEmbed> { discordEmbed };
1168
1169 if (embedErrors.Count > 0)
1170 {
1171 var joinedErrors = String.Join(Environment.NewLine, embedErrors);
1172 Logger.LogError("Embed description contains errors:{newLine}{issues}", Environment.NewLine, joinedErrors);
1173 result.Add(new Embed
1174 {
1175 Title = "TGS Embed Errors",
1176 Description = joinedErrors,
1177 Colour = Color.Red,
1178 Footer = new EmbedFooter("Please report this to your codebase's maintainers."),
1179 Timestamp = DateTimeOffset.UtcNow,
1180 });
1181 }
1182
1183 return result;
1184 }
@ Optional
DMAPI validation is performed but not required for the deployment to succeed.