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