Update delivery report and message result objects to bring it in line with common Drupal standards, similar to the treatment applied to SmsMessage* classes.
- Add setters
- Add [missing] getters
- Remove mystery meat constructors
- Both objects have duplicated redundant status codes. Move to external class.
- Change status codes to strings. Integers are meaningless. the 2,3,4,5 prefixes mapping to positivity or neg is not used. We have
->getStatus() to track positivity
- Add unit tests, there are currently no tests.
Review result objects
\Drupal\sms\Message\SmsMessageResultInterface
new SmsMessageResult count: 3, zero are tests.
Review deliver report objects
\Drupal\sms\Message\SmsDeliveryReportInterface
new SmsDeliveryReport count: 4, zero are tests.
Comments
Comment #2
dpiComment #3
dpiComment #4
dpiI'm doing some experimentation here https://github.com/dpi/smsframework/pull/51
The first commit adds the methods and simple stuff. Second commit onwards has some radical stuff. Did I go too far? Maybe. But I'm doing some real gateway development with this experimental report/result/status branch and it seems fine so far.
I'm working on the following gateways: Telstra (best example), Clickatell, and MailUp (not ready). And I may try Twilio if I have some time. This should give me an idea of how results and reports need to be implemented.
Comment #5
almaudoh commentedJust did a quick code check. The change from PHP arrays to objects with interfaces is a good one. So is the status constants move to a dedicated class.
However, I don't see the need why the Delivery report recipients property is an array. I don't see a use case for that. Even in your code, each delivery report is keyed by the same single recipient number.
I also still don't see the benefit of composing the SmsMessage object into the SmsResult object (especially if they are both serialized). I would rather compose the SmsResult into the SmsMessage object.
Comment #6
dpiAwesome.
The keying of Result::reports should probably be made unrelated to recipients. So far I see reports as an atomic operation, all recipients should have the same status. Otherwise create new reports if there are differing status.
I added the message to the result purely for the benefit of post process hooks. There is no other reason, and yes I agree it is not ideal.
Can give this a shot.
Comment #7
dpiPushed to the PR:
getResult/setResultto message objects for use in post process events in #2786865.Removed
Result::setMessages/getMessagesresult::reportsto have meaningless array keys.result::getReportto iterate over reports, since keys no longer are for recipient.Comment #8
dpiMerged into #2786865: Replacing hooks with Symfony events. Updated provider to use message::setResult from #7
Changes pushed to PR
Comment #13
dpiAh, the tests exposed the reason why I chose the original design of tacking SMS message onto result:
the provider::send/incoming return an array of results, and there is no reference to the sent SMS messages (chunked, or otherwise).
Comment #14
almaudoh commented#13.1 Is preferable.
Have you considered the case when delivery reports are updated at a later time (that happens to me all the time)? The message might be delayed by the SMSC for a while with a "pending" status. And thereafter updated to "delivered".
Comment #15
dpiConsidering reports themselves arn't persistent it didnt seam to matter...?
If we want to force reports to be for a single recipient that's OK I suppose.
I imagined if a status needed to be updated you can programmatically find the old report by using message Id + recipient.
Comment #16
dpiComment #21
almaudoh commentedThese are unrelated changes (looks like it's already committed even)
Comment #22
dpiYeh don't worry about the patch, just using patches for test runner. Theres a bunch of random other junk in there too.
Just use PR for review.
Comment #23
dpiAnd its not ready for review right now ;)
Probably this weekend sometime.
Comment #24
dpiSince #16: Split status classes into two, updated interface documentation to refer to these classes instead of the old status class.
---
So as I see it now, to programmatically determine if a message was sent successfully:
Does this make sense?
Comment #25
dpiIgnore the
SmsDevelMessageFormcode in the patch, just review the commits in PR. I was experimenting with how the devel message form determines if a message was sent successfully. See question in #24.Comment #30
dpiPatch will fail since I have not updated tests with new codes.
edit: codes, not return type
Comment #31
dpiComment #36
dpiPer #5
and #14
Updating report object to have only one recipient.
Comment #37
dpiTake a look if you like
https://github.com/dpi/smsframework/pull/51
Comment #38
almaudoh commentedOverall, this is a good refactoring. I made comments in the PR. I'll still check out the code for any nitpicks left.
One good thing about the new return value of
SmsProviderInterface::send ()is that it is possible to track messages sent together even after chunking since they are all returned together in one array. I think we could add a tracking number field that allows custom generated identifiers to be stored. I'll raise a separate issue for that.Comment #39
dpiFixed and pushed nitpicks, ive posted some replies if you can take a look at those.
Theres a question you may have missed in #24 during the barrage of testbot results.
Are you online now?
Comment #40
dpiWorking on unit tests.
Comment #41
dpiIncludes nit fixes and unit tests, stricter variable type handling
setCreditsUsedandsetCreditsBalance.SmsMessageResultprotected.getResultandsetResultmethods.Comment #46
dpiFixed some @covers annotations from the new unit tests.
Comment #47
dpiPushed:
Comment #48
dpiGoing all in on the meaning of status messages for result. Per #2789237: Update delivery report and message result objects #24
Renaming result::*status* to result::*error*. Current head has
getErrorMessagefor result too, but it also hasgetStatus.What do you think of:
result::getError() !== NULL)count(reports) > 0)We should really arrange a d.o documentation page for this ;) (edit: 22 nov 2016, created: https://www.drupal.org/node/2829641)
Comment #49
dpiComment #54
dpiUpdated devel form asserts
Comment #55
almaudoh commentedI actually thought I had commented on #24. Seems like I didn't post it.
I would look at maybe two or three SMS providers to get an idea of things. What I've seen typically is
result::getStatusis false (and count of reports == 0) if there is an error that makes it impossible to send to any recipient. But once the message can be dispatched, thenresult::getStatusis true (and count of reports == count of recipients), while individual recipient status is reflected in the reports.If we want to merge the "did this succeed or fail" function with the "why did this fail" function then maybe a NULL status could mean success (or a non-zero report count if we adhere to the contract mentioned above).
Comment #56
dpiI'm working with three providers so far ;), however...
Just to be clear its just informational, the *why* isnt important since we are not acting apon the success or failure.
I had imagined something like
$result->addTryAgain($recipient, 'some measure of time');to resolve some types of failures. At least when using the queue system.The table I have has the error
code == NULLas one of the variables to determine success. I think its reasonable to add the requirement of at least one report to be super sure about that. There would seem to be some kind of failure in some way if there are no reports?Comment #57
dpiI re-read your comment and see I can interpret it differently.
I think having setError instead of setStatus is better, gateways dont have to do anything on success. So we can easily determine if the whole transaction failed by checking if there is any error code. If it was binary/NULL, we have three states, where
NULL == unknown status?. It makes it a lot harder to determine what happened this way.Im not sure you can qualify *success* from this equation, since reports now have their own status codes. We can assume all reports were *processed*.
This is where my aforementioned "try again?" idea comes from, since we cant tell easily from error codes whether its a good idea to retry the message (eg: such as flooded) or just dump it (eg: bad recipient).
Other than generating log data, what can we potentially automate from status codes?
Comment #58
almaudoh commentedSo as we stand now, we read errors for results and read status for reports. That makes sense. This is a big change and a huge patch, but it's a good change and I think we should push it and maybe make improvement's in follow-up issues.
We can do this in a follow-up.
Status codes are really mostly for informational purposes for the user or administrator. Maybe also for statistics (I typically use statistics of delivery status to determine the effectiveness of a gateway)
The only other thing I can think about (in terms of automation) similar to what I answered in the other thread is to automatically select gateways for particular routes based on effectiveness. But that's way out of scope of this issue.
Comment #59
almaudoh commentedI'm ready to RTBC this once you post the latest patch for the testbot.
Comment #60
dpiUpdated. Should be fine.
Comment #65
dpioops, forgot about tests
Comment #67
dpi