1 module telega.telegram.inline; 2 3 import std.typecons : Nullable; 4 import std.meta : AliasSeq; 5 import telega.botapi : BotApi, TelegramMethod, HTTPMethod; 6 import telega.telegram.basic : ParseMode, InlineKeyboardMarkup, InputMessageContent, User, Location; 7 import telega.serialization : JsonableAlgebraicProxy; 8 9 struct InlineQuery 10 { 11 string id; 12 User from; 13 Nullable!Location location; 14 string query; 15 string offset; 16 } 17 18 alias InlineQueryResultStructs = AliasSeq!( 19 InlineQueryResultArticle, InlineQueryResultPhoto, InlineQueryResultGif, InlineQueryResultMpeg4Gif, 20 InlineQueryResultVideo, InlineQueryResultAudio, InlineQueryResultVoice, InlineQueryResultDocument, 21 InlineQueryResultLocation, InlineQueryResultVenue, InlineQueryResultContact, InlineQueryResultGame, 22 InlineQueryResultCachedPhoto, InlineQueryResultCachedGif, InlineQueryResultCachedMpeg4Gif, 23 InlineQueryResultCachedSticker, InlineQueryResultCachedDocument, InlineQueryResultCachedVideo, 24 InlineQueryResultCachedVoice, InlineQueryResultCachedAudio 25 ); 26 27 alias InlineQueryResult = JsonableAlgebraicProxy!InlineQueryResultStructs; 28 29 mixin template InlineQueryFields() 30 { 31 Nullable!InlineKeyboardMarkup reply_markup; 32 Nullable!InputMessageContent input_message_content; 33 } 34 35 struct InlineQueryResultArticle 36 { 37 string type = "article"; 38 string id; 39 string title; 40 Nullable!string url; 41 Nullable!bool hide_url; 42 Nullable!string description; 43 Nullable!string thumb_url; 44 Nullable!uint thumb_width; 45 Nullable!uint thumb_height; 46 47 Nullable!InlineKeyboardMarkup reply_markup; 48 InputMessageContent input_message_content; // can't be nullable 49 } 50 51 struct InlineQueryResultPhoto 52 { 53 string type = "photo"; 54 string id; 55 string photo_url; 56 string thumb_url; 57 Nullable!uint photo_width; 58 Nullable!uint photo_height; 59 Nullable!string title; 60 Nullable!string description; 61 Nullable!string caption; 62 Nullable!ParseMode parse_mode; 63 64 mixin InlineQueryFields; 65 } 66 67 struct InlineQueryResultGif 68 { 69 string type = "gif"; 70 string id; 71 string gif_url; 72 Nullable!uint gif_width; 73 Nullable!uint gif_height; 74 Nullable!uint gif_duration; 75 Nullable!string thumb_url; 76 Nullable!string title; 77 Nullable!string caption; 78 Nullable!ParseMode parse_mode; 79 80 mixin InlineQueryFields; 81 } 82 83 struct InlineQueryResultMpeg4Gif 84 { 85 string type ="mpeg4_gif"; 86 string id; 87 string mpeg4_url; 88 Nullable!uint mpeg4_width; 89 Nullable!uint mpeg4_height; 90 Nullable!uint mpeg4_duration; 91 Nullable!string thumb_url; 92 Nullable!string title; 93 Nullable!string caption; 94 Nullable!ParseMode parse_mode; 95 96 mixin InlineQueryFields; 97 } 98 99 struct InlineQueryResultVideo 100 { 101 string type ="video"; 102 string id; 103 string video_url; 104 string mime_type; 105 string thumb_url; 106 string title; 107 Nullable!string caption; 108 Nullable!ParseMode parse_mode; 109 Nullable!uint video_width; 110 Nullable!uint video_height; 111 Nullable!uint video_duration; 112 Nullable!string description; 113 114 mixin InlineQueryFields; 115 } 116 117 struct InlineQueryResultAudio 118 { 119 string type = "audio"; 120 string id; 121 string audio_url; 122 string title; 123 Nullable!string caption; 124 Nullable!ParseMode parse_mode; 125 Nullable!string performer; 126 Nullable!uint audio_duration; 127 128 mixin InlineQueryFields; 129 } 130 131 struct InlineQueryResultVoice 132 { 133 string type = "voice"; 134 string id; 135 string voice_url; 136 string title; 137 Nullable!string caption; 138 Nullable!ParseMode parse_mode; 139 Nullable!uint voice_duration; 140 141 mixin InlineQueryFields; 142 } 143 144 struct InlineQueryResultDocument 145 { 146 string type = "document"; 147 string id; 148 string title; 149 Nullable!string caption; 150 Nullable!ParseMode parse_mode; 151 Nullable!string document_url; 152 Nullable!string mime_type; 153 Nullable!string description; 154 Nullable!string thumb_url; 155 Nullable!uint thumb_width; 156 Nullable!uint thumb_height; 157 158 mixin InlineQueryFields; 159 } 160 161 struct InlineQueryResultLocation 162 { 163 string type = "location"; 164 string id; 165 float latitude; 166 float longitude; 167 string title; 168 Nullable!uint live_period; 169 Nullable!string thumb_url; 170 Nullable!uint thumb_width; 171 Nullable!uint thumb_height; 172 173 mixin InlineQueryFields; 174 } 175 176 struct InlineQueryResultVenue 177 { 178 string type = "venue"; 179 string id; 180 float latitude; 181 float longitude; 182 string title; 183 string address; 184 Nullable!string foursquare_id; 185 Nullable!string thumb_url; 186 Nullable!uint thumb_width; 187 Nullable!uint thumb_height; 188 189 mixin InlineQueryFields; 190 } 191 192 struct InlineQueryResultContact 193 { 194 string type = "contact"; 195 string id; 196 string phone_number; 197 string first_name; 198 Nullable!string last_name; 199 Nullable!string thumb_url; 200 Nullable!uint thumb_width; 201 Nullable!uint thumb_height; 202 203 mixin InlineQueryFields; 204 } 205 206 struct InlineQueryResultGame 207 { 208 string type = "game"; 209 string id; 210 string game_short_name; 211 Nullable!InlineKeyboardMarkup reply_markup; 212 } 213 214 215 struct InlineQueryResultCachedPhoto 216 { 217 string type = "photo"; 218 string id; 219 string photo_file_id; 220 Nullable!string title; 221 Nullable!string description; 222 Nullable!string caption; 223 Nullable!ParseMode parse_mode; 224 225 mixin InlineQueryFields; 226 } 227 228 struct InlineQueryResultCachedGif 229 { 230 string type = "gif"; 231 string id; 232 string gif_file_id; 233 Nullable!string title; 234 Nullable!string caption; 235 Nullable!ParseMode parse_mode; 236 237 mixin InlineQueryFields; 238 } 239 240 struct InlineQueryResultCachedMpeg4Gif 241 { 242 string type = "mpeg4_gif"; 243 string id; 244 string mpeg4_file_id; 245 Nullable!string title; 246 Nullable!string caption; 247 Nullable!ParseMode parse_mode; 248 249 mixin InlineQueryFields; 250 } 251 252 struct InlineQueryResultCachedSticker 253 { 254 string type = "sticker"; 255 string id; 256 string sticker_file_id; 257 258 mixin InlineQueryFields; 259 } 260 261 struct InlineQueryResultCachedDocument 262 { 263 string type = "document"; 264 string id; 265 string title; 266 string document_file_id; 267 Nullable!string description; 268 Nullable!string caption; 269 Nullable!ParseMode parse_mode; 270 271 mixin InlineQueryFields; 272 } 273 274 struct InlineQueryResultCachedVideo 275 { 276 string type = "video"; 277 string id; 278 string video_file_id; 279 string title; 280 Nullable!string description; 281 Nullable!string caption; 282 Nullable!ParseMode parse_mode; 283 284 mixin InlineQueryFields; 285 } 286 287 struct InlineQueryResultCachedVoice 288 { 289 string type = "voice"; 290 string id; 291 string voice_file_id; 292 string title; 293 Nullable!string caption; 294 Nullable!ParseMode parse_mode; 295 296 mixin InlineQueryFields; 297 } 298 299 300 struct InlineQueryResultCachedAudio 301 { 302 string type = "audio"; 303 string id; 304 string audio_file_id; 305 Nullable!string caption; 306 Nullable!ParseMode parse_mode; 307 308 mixin InlineQueryFields; 309 } 310 311 // methods 312 313 struct AnswerInlineQueryMethod 314 { 315 mixin TelegramMethod!"/answerInlineQuery"; 316 317 string inline_query_id; 318 InlineQueryResult[] results; 319 uint cache_time; 320 bool is_personal; 321 string next_offset; 322 string switch_pm_text; 323 string switch_pm_parameter; 324 } 325 326 bool answerInlineQuery(BotApi api, ref AnswerInlineQueryMethod m) 327 { 328 return api.callMethod!bool(m); 329 } 330 331 bool answerInlineQuery(BotApi api, string inlineQueryId, InlineQueryResult[] results) 332 { 333 AnswerInlineQueryMethod m = { 334 inline_query_id : inlineQueryId, 335 results : results 336 }; 337 338 return api.answerInlineQuery(m); 339 } 340 341 unittest 342 { 343 class BotApiMock : BotApi 344 { 345 this(string token) 346 { 347 super(token); 348 } 349 350 T callMethod(T, M)(M method) 351 { 352 T result; 353 354 logDiagnostic("[%d] Requesting %s", requestCounter, method.name); 355 356 return result; 357 } 358 } 359 360 auto api = new BotApiMock(null); 361 362 InlineQueryResult[] iqr = new InlineQueryResult[20]; 363 364 iqr[0] = InlineQueryResultArticle(); 365 iqr[1] = InlineQueryResultPhoto(); 366 iqr[2] = InlineQueryResultGif(); 367 iqr[3] = InlineQueryResultMpeg4Gif(); 368 iqr[4] = InlineQueryResultVideo(); 369 iqr[5] = InlineQueryResultAudio(); 370 iqr[6] = InlineQueryResultVoice(); 371 iqr[7] = InlineQueryResultDocument(); 372 iqr[8] = InlineQueryResultLocation(); 373 iqr[9] = InlineQueryResultVenue(); 374 iqr[10] = InlineQueryResultContact(); 375 iqr[11] = InlineQueryResultGame(); 376 iqr[12] = InlineQueryResultCachedPhoto(); 377 iqr[13] = InlineQueryResultCachedGif(); 378 iqr[14] = InlineQueryResultCachedMpeg4Gif(); 379 iqr[15] = InlineQueryResultCachedSticker(); 380 iqr[16] = InlineQueryResultCachedDocument(); 381 iqr[17] = InlineQueryResultCachedVideo(); 382 iqr[18] = InlineQueryResultCachedVoice(); 383 iqr[19] = InlineQueryResultCachedAudio(); 384 385 api.answerInlineQuery("answer-inline-query", iqr); 386 }