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 foursquare_type; 186 Nullable!string thumb_url; 187 Nullable!uint thumb_width; 188 Nullable!uint thumb_height; 189 190 mixin InlineQueryFields; 191 } 192 193 struct InlineQueryResultContact 194 { 195 string type = "contact"; 196 string id; 197 string phone_number; 198 string first_name; 199 Nullable!string last_name; 200 Nullable!string vcard; 201 Nullable!string thumb_url; 202 Nullable!uint thumb_width; 203 Nullable!uint thumb_height; 204 205 mixin InlineQueryFields; 206 } 207 208 struct InlineQueryResultGame 209 { 210 string type = "game"; 211 string id; 212 string game_short_name; 213 Nullable!InlineKeyboardMarkup reply_markup; 214 } 215 216 217 struct InlineQueryResultCachedPhoto 218 { 219 string type = "photo"; 220 string id; 221 string photo_file_id; 222 Nullable!string title; 223 Nullable!string description; 224 Nullable!string caption; 225 Nullable!ParseMode parse_mode; 226 227 mixin InlineQueryFields; 228 } 229 230 struct InlineQueryResultCachedGif 231 { 232 string type = "gif"; 233 string id; 234 string gif_file_id; 235 Nullable!string title; 236 Nullable!string caption; 237 Nullable!ParseMode parse_mode; 238 239 mixin InlineQueryFields; 240 } 241 242 struct InlineQueryResultCachedMpeg4Gif 243 { 244 string type = "mpeg4_gif"; 245 string id; 246 string mpeg4_file_id; 247 Nullable!string title; 248 Nullable!string caption; 249 Nullable!ParseMode parse_mode; 250 251 mixin InlineQueryFields; 252 } 253 254 struct InlineQueryResultCachedSticker 255 { 256 string type = "sticker"; 257 string id; 258 string sticker_file_id; 259 260 mixin InlineQueryFields; 261 } 262 263 struct InlineQueryResultCachedDocument 264 { 265 string type = "document"; 266 string id; 267 string title; 268 string document_file_id; 269 Nullable!string description; 270 Nullable!string caption; 271 Nullable!ParseMode parse_mode; 272 273 mixin InlineQueryFields; 274 } 275 276 struct InlineQueryResultCachedVideo 277 { 278 string type = "video"; 279 string id; 280 string video_file_id; 281 string title; 282 Nullable!string description; 283 Nullable!string caption; 284 Nullable!ParseMode parse_mode; 285 286 mixin InlineQueryFields; 287 } 288 289 struct InlineQueryResultCachedVoice 290 { 291 string type = "voice"; 292 string id; 293 string voice_file_id; 294 string title; 295 Nullable!string caption; 296 Nullable!ParseMode parse_mode; 297 298 mixin InlineQueryFields; 299 } 300 301 302 struct InlineQueryResultCachedAudio 303 { 304 string type = "audio"; 305 string id; 306 string audio_file_id; 307 Nullable!string caption; 308 Nullable!ParseMode parse_mode; 309 310 mixin InlineQueryFields; 311 } 312 313 // methods 314 315 struct AnswerInlineQueryMethod 316 { 317 mixin TelegramMethod!"/answerInlineQuery"; 318 319 string inline_query_id; 320 InlineQueryResult[] results; 321 uint cache_time; 322 bool is_personal; 323 string next_offset; 324 string switch_pm_text; 325 string switch_pm_parameter; 326 } 327 328 bool answerInlineQuery(BotApi api, ref AnswerInlineQueryMethod m) 329 { 330 return api.callMethod!bool(m); 331 } 332 333 bool answerInlineQuery(BotApi api, string inlineQueryId, InlineQueryResult[] results) 334 { 335 AnswerInlineQueryMethod m = { 336 inline_query_id : inlineQueryId, 337 results : results 338 }; 339 340 return api.answerInlineQuery(m); 341 } 342 343 unittest 344 { 345 class BotApiMock : BotApi 346 { 347 this(string token) 348 { 349 super(token); 350 } 351 352 T callMethod(T, M)(M method) 353 { 354 T result; 355 356 logDiagnostic("[%d] Requesting %s", requestCounter, method.name); 357 358 return result; 359 } 360 } 361 362 auto api = new BotApiMock(null); 363 364 InlineQueryResult[] iqr = new InlineQueryResult[20]; 365 366 iqr[0] = InlineQueryResultArticle(); 367 iqr[1] = InlineQueryResultPhoto(); 368 iqr[2] = InlineQueryResultGif(); 369 iqr[3] = InlineQueryResultMpeg4Gif(); 370 iqr[4] = InlineQueryResultVideo(); 371 iqr[5] = InlineQueryResultAudio(); 372 iqr[6] = InlineQueryResultVoice(); 373 iqr[7] = InlineQueryResultDocument(); 374 iqr[8] = InlineQueryResultLocation(); 375 iqr[9] = InlineQueryResultVenue(); 376 iqr[10] = InlineQueryResultContact(); 377 iqr[11] = InlineQueryResultGame(); 378 iqr[12] = InlineQueryResultCachedPhoto(); 379 iqr[13] = InlineQueryResultCachedGif(); 380 iqr[14] = InlineQueryResultCachedMpeg4Gif(); 381 iqr[15] = InlineQueryResultCachedSticker(); 382 iqr[16] = InlineQueryResultCachedDocument(); 383 iqr[17] = InlineQueryResultCachedVideo(); 384 iqr[18] = InlineQueryResultCachedVoice(); 385 iqr[19] = InlineQueryResultCachedAudio(); 386 387 api.answerInlineQuery("answer-inline-query", iqr); 388 }