0.9.15
Fixed
- Poller no longer crashes (and crash-loops the whole supervision tree) when Telegram or a proxy returns a non-JSON body.
get_updates/1now matchesstatus_code: 200and decodes withoutJason.decode!; a 502 HTML page returns{:error, {:http_status, 502}}instead of raising. - Poller error diagnostics use
inspect/1instead ofAtom.to_string/1, which crashed on tuple reasons like{:tls_alert, β¦}. - Empty and errored polls keep the current offset instead of resetting to
0, so an unconfirmed update batch is no longer replayed after a transport failure (double-firing handlers, includinghandle_successful_payment). Errored polls also back off from 100ms to 5s instead of hot-looping.
Changed
Sexy.Bot.get_updates/1(andSexy.Bot.Api.get_updates/1) error return widened: alongside{:error, atom}it can now return{:error, {:http_status, integer}}or{:error, :invalid_json}. Bare:error(noresultkey) was already possible.
0.9.14
Cleanup pass (ponytail audit). Breaking changes β see below.
Breaking
- Removed
Sexy.Bot.Screen. UseSexy.Bot.build/1(now backed bySexy.Utils.Object.build/1). - Removed
wallet_init/5(Wallet.tg integration + globalWALLETenv). Keep it in your app β it is not Telegram Bot API. send_dice/2now takes a Telegram dice emoji ("π²","π―","π","β½","π³","π°") instead of the"dice"/"bowl"/"foot"/"bask"/"dart"/"777"codes.send_chat_action/2now takes a real Telegram action string ("typing","upload_photo", β¦) instead of the"txt"/"pic"/"vid"codes.get_user_photo/1returnsnilwhen the user has no photo, instead of a hardcoded fallbackfile_id. It also handles any number of photo sizes.Sexy.Utils.Bot.wrap_textis nowwrap_text/2(wrapper, text), replacing the previouswrap_text/1(decorative borders) andwrap_text/3(HTML tag).
Fixed
Sexy.Utilsquery parsing no longer callsString.to_atomon user-supplied callback keys (atom-table exhaustion / DoS). Unknown or malformed keys are dropped.mix sexy.tdl.generate_typesnow writes tolib/tdl/{object,method}.ex(the real paths), so regeneration overwrites the shipped files.
Internal
- Deduplicated HTTP response decoding in
Sexy.Bot.Api(decode_response/1). get_photo_id/1simplified toList.last/1; sharedtitlecase_once/1moved toSexy.Utils.
0.9.13
- Multipart upload for photo, video and animation (parallel to
send_document):- New:
Sexy.Bot.Api.send_photo/5,send_video/5,send_animation/5 - Top-level delegates:
Sexy.Bot.send_photo/5,send_video/5,send_animation/5
- New:
New
Sexy.Utils.Objectfield:upload_type(:photo | :video | :animation | :document | nil) drives multipart uploads. Detection prefersupload_typeovermedia.detect_object_type/1no longer crashes whenmediais not a binary (guards added; non-string media β"unknown").- Legacy
media: "file"sentinel still works (equivalent toupload_type: :document).
0.9.12
- Fix
send_documentmultipart format for hackney 1.25.0. Use standard 4-tuple{"document", binary, disposition, []}instead of{binary, disposition, []}.
0.9.11
- Add
after: secondsoption tonotify/3for auto-deleting notifications.
0.9.10
- Add delayed deletion:
delete_message(chat_id, mid, after: seconds). Runs asynchronously viaTaskβ accepts integers and floats.
0.9.9
- Fix
send_documentbadarg when sending binary content as multipart. HTTPoison was interpreting{:file, binary, ...}as a file path instead of raw content.
0.9.8
- Replace individual
*_pidfields inSexy.TDL.Registrywith ElixirRegistry-backed worker discovery (Sexy.TDL.Workers). Workers auto-unregister on death β no stale PIDs. New API:register_worker/2,get_worker/2,list_workers/1 - Add
Sexy.TDL.Workers(Elixir Registry,:uniquekeys) to supervision tree
0.9.7
- Add client process pid fields to
Sexy.TDL.Registrydefstruct (sorter_pid,updater_pid,sender_pid,answerer_pid,reactor_pid,direct_pid)
0.9.6
- Add Telegram Payments (Stars) support in Poller and Session:
- Route
pre_checkout_queryupdates tohandle_pre_checkout/1callback - Route
successful_paymentmessages tohandle_successful_payment/1callback - Both callbacks are optional: pre_checkout auto-approves, successful_payment logs
successful_paymentclause placed before generalmessageto ensure correct matching
- Route
0.9.5
- Rewrite
bot-quickstart.mdfor beginners: add intro (single-message UI concept), BotFather step, split Session into 3 blocks (Storage, Dispatch, Screens), explain update structure, callback_query, inline_keyboard layout, answer_callback, add "How it works" flow diagram - Replace all Russian comments and log messages with English
- Rename
extraβupdate_datain Session callback definition, docs, and examples for consistency withSexy.Utils.Object.update_datafield - Fix Screen module examples to use
Sexy.Bot.build/send(public API) instead ofSexy.Bot.Screen.build/Sexy.Bot.Sender.deliver(internal modules)
0.9.4
- Add comprehensive test suite: 113 tests, 0 failures (7 test files)
mox+bypasstest dependencies for HTTP stubbing and behaviour mocking- Pure function tests: Utils, Utils.Bot, Utils.Object, Bot.Screen
- Integration tests with Bypass: Bot.Api, Bot.Sender, Bot.Notification
- Add
credodependency, passmix credo --strict(0 issues) - Add 66
@specannotations and@typedefinitions across 10 modules - Refactor
get_message_type: 11-branch cond βEnum.find_valueover@message_types - Refactor
fiat_chunk: extractformat_integer_part/1+join_chunks/1, remove 100 lines of duplication - Refactor
Sender.deliver: extractparse_mode/1,send_by_type/4,update_screen/3(complexity 10β3, nesting 3β1) - Refactor
Handler.recursive_match: extractrecurse_if_typed/2(nesting 3β1) - Fix credo issues: alias ordering,
Enum.map_join,unlessβif, nested module refsβaliases - Run
mix formaton all files
0.9.3
- Add comprehensive ExDoc documentation with
@moduledocand@docfor all modules/functions - Add quickstart guides:
bot-quickstart.md,tdl-quickstart.md - Add hex.pm packaging config (description, package, docs)
- Filter auto-generated TDL.Object/Method submodules from docs
- Expand README with Object struct, send options, and notify options documentation
- Add MIT LICENSE
0.9.2
- Flatten
lib/structure: remove redundantlib/sexy/nesting
0.9.1
- Move all Bot modules under
Sexy.Botnamespace:Sexy.ApiβSexy.Bot.ApiSexy.SenderβSexy.Bot.SenderSexy.NotificationβSexy.Bot.NotificationSexy.PollerβSexy.Bot.PollerSexy.ScreenβSexy.Bot.ScreenSexy.SessionβSexy.Bot.Session
0.9.0
Breaking: Sexy split into Sexy.Bot + Sexy.TDL.
Sexymodule is now a namespace only β useSexy.Botas supervisor entry point- All Bot API functions moved:
Sexy.*βSexy.Bot.* - New
Sexy.TDLβ TDLib integration for userbot sessionsSexy.TDL.open/3,close/1,transmit/2β session managementSexy.TDL.Backendβ port to tdlib_json_cli binarySexy.TDL.Handlerβ JSON deserialization + event routingSexy.TDL.Registryβ ETS-based session storageSexy.TDL.Riserβ per-account supervisor- 2558 auto-generated Method/Object structs from TDLib API
- New mix tasks:
mix sexy.tdl.setup,mix sexy.tdl.generate_types - Migration guide: see MIGRATION.md
0.8.2
- Add Telegram Stars payment methods (send_invoice, answer_pre_checkout, refund_star_payment)
- Add wallet_init for Wallet.tg integration
0.8.1
- Built-in /_transit route for navigation between screens
0.8.0
Breaking: Sexy is now a Supervisor, not an Application.
- Start with
{Sexy, token: "...", session: MySession}in supervision tree Sexy.Sessionbehaviour β single integration point (persistence + dispatch)- Removed
Sexy.Application,Sexy.Visor, config-based dispatch - Config replaced with
persistent_term(no more:sexycon) - Added
build/1,send/1-2,notify/2-3facade functions - Hardcoded dismiss_text default to "OK"
- Removed
wrap_textfrom Sender
0.7.4
- Add
Sexy.Notificationβ overlay/replace notification pattern - Dismiss button with built-in
/_deleteroute in Poller - Configurable
dismiss_textviaApplication.get_env(:sexy, :dismiss_text)
0.7.3
- Remove 26 legacy short-name delegates (pm, dm, um, ui, etc.)
- Remove unused
api_url/1
0.7.2
- Add
Sexy.Sessionbehaviour (get_message_id/1,on_message_sent/4) - Add
Sexy.Senderβ delivers Object, manages mid lifecycle via Session callbacks - Add
Sexy.Screenβ converts app maps to Object structs Sexy.Utils.Object: addchat_id, renameupdate_userβupdate_data
0.7.1
- Create
Sexy.Apiwith readable method names (send_message, delete_message, etc.) - Consolidate HTTP into
do_request/3anddo_multipart/3 - Rewrite
Sexyas facade withdefdelegatetoSexy.Api - Legacy short names kept as backward-compat delegates
0.7.0
- Initial extraction from OrderMachine into standalone library
- Modules: Sexy (API client), Sexy.Poller, Sexy.Visor, Sexy.Utils, Sexy.Utils.Bot, Sexy.Utils.Object
- Dependencies: HTTPoison, Jason, Base62