I need to send a whatsapp message with a link in its content using twilio.
Here is my code:
Twilio.init(ACCOUNT_SID, AUTH_TOKEN);
Message message = Message.creator(
new PhoneNumber("whatsapp:" + phoneNumber),
new PhoneNumber("whatsapp:" + PHONE_FROM),
"Hello: http://www.google.com")
.create();
How can I send a link on the body message. Please help!!
Use this creator method from MessageCreator class.
/**
* Create a MessageCreator to execute create.
*
* #param to The phone number to receive the message
* #param from The phone number that initiated the message
* #param mediaUrl The media_url
* #return MessageCreator capable of executing the create
*/
public static MessageCreator creator(final com.twilio.type.PhoneNumber to,
final com.twilio.type.PhoneNumber from,
final List<URI> mediaUrl) {
return new MessageCreator(to, from, mediaUrl);
}
Also, checkout another question related to this problem.
Related
I am trying to build a Spring Boot Webservice for simple Hello world Alexa Skill.
I am getting Null pointer exception in run time on passing vocabBrawlSpeechlet aws speechlet API. Even if I pass vocabBrawlSpeechlet as new VocabBrawlSpeechlet() I am getting null pointer exception on using autowire inside vocabBrawlSpeechlet class.
Servlet class
package com.vocabBrawlAlexa;
#WebServlet("/hello")
public class HelloWorldServlet extends SpeechletServlet {
private static final Logger LOGGER = LogManager.getLogger(HelloWorldServlet.class.getName());
/**
*
*/
private static final long serialVersionUID = -8294485619021129263L;
private VocabBrawlSpeechlet vocabBrawlSpeechlet;
#Autowired
public HelloWorldServlet(VocabBrawlSpeechlet vocabBrawlSpeechlet) {
LOGGER.debug("Autowiring vocabBrawlSpeechlet");
this.vocabBrawlSpeechlet = vocabBrawlSpeechlet;
}
public HelloWorldServlet() {
LOGGER.debug(vocabBrawlSpeechlet);
this.setSpeechlet(vocabBrawlSpeechlet);
}
}
Speechlet class
package com.vocabBrawlAlexa.controller;
#Component
public class VocabBrawlSpeechlet implements SpeechletV2 {
static final Logger log = Logger.getLogger(VocabBrawlSpeechlet.class);
private IAlexaService alexaService;
/**
* Constructor.
*
* #param alexaService service.
*/
#Autowired
public VocabBrawlSpeechlet(IAlexaService alexaService) {
this.alexaService = alexaService;
}
public VocabBrawlSpeechlet() {
// TODO Auto-generated constructor stub
}
#Override
public void onSessionStarted(SpeechletRequestEnvelope<SessionStartedRequest> requestEnvelope) {
log.info("onSessionStarted " );
log.info("Request requestId "+requestEnvelope.getRequest().getRequestId()
+" session Id "+requestEnvelope.getSession().getSessionId()+
" user ID "+requestEnvelope.getSession().getUser().getUserId());
// any initialization logic goes here
}
#Override
public SpeechletResponse onLaunch(SpeechletRequestEnvelope<LaunchRequest> requestEnvelope) {
log.info("onLaunch");
log.info("Request requestId "+requestEnvelope.getRequest().getRequestId()
+" session Id "+requestEnvelope.getSession().getSessionId()+
" user ID "+requestEnvelope.getSession().getUser().getUserId());
return getWelcomeResponse();
}
#Override
public SpeechletResponse onIntent(SpeechletRequestEnvelope<IntentRequest> requestEnvelope) {
IntentRequest request = requestEnvelope.getRequest();
log.debug("reached Intent");
log.info("onIntent");
log.info("Request requestId "+requestEnvelope.getRequest().getRequestId()
+" session Id "+requestEnvelope.getSession().getSessionId()+
" user ID "+requestEnvelope.getSession().getUser().getUserId());
Intent intent = request.getIntent();
String intentName = (intent != null) ? intent.getName() : null;
if ("HelloWorldIntent".equals(intentName)) {
log.debug("HelloWorldIntent Intent");
log.debug(alexaService);
//IAlexaService alexa = new AlexaServiceImpl();
return alexaService.getHelloIntentResponse();
} else if ("AMAZON.HelpIntent".equals(intentName)) {
return getHelpResponse();
} else {
return getAskResponse("HelloWorld", "This is unsupported. Please try something else.");
}
}
#Override
public void onSessionEnded(SpeechletRequestEnvelope<SessionEndedRequest> requestEnvelope) {
log.info("onSessionEnded");
log.info("Request requestId "+requestEnvelope.getRequest().getRequestId()
+" session Id "+requestEnvelope.getSession().getSessionId()+
" user ID "+requestEnvelope.getSession().getUser().getUserId());
// any cleanup logic goes here
}
/**
* Creates and returns a {#code SpeechletResponse} with a welcome message.
*
* #return SpeechletResponse spoken and visual response for the given intent
*/
private SpeechletResponse getWelcomeResponse() {
String speechText = "Welcome to the Alexa Skills Kit, you can say hello";
return getAskResponse("HelloWorld", speechText);
}
/**
* Creates a {#code SpeechletResponse} for the hello intent.
*
* #return SpeechletResponse spoken and visual response for the given intent
*/
private SpeechletResponse getHelloResponse() {
log.debug("reached hello world");
String speechText = "Hello world";
// Create the Simple card content.
SimpleCard card = getSimpleCard("HelloWorld", speechText);
// Create the plain text output.
PlainTextOutputSpeech speech = getPlainTextOutputSpeech(speechText);
return SpeechletResponse.newTellResponse(speech, card);
}
/**
* Creates a {#code SpeechletResponse} for the help intent.
*
* #return SpeechletResponse spoken and visual response for the given intent
*/
private SpeechletResponse getHelpResponse() {
String speechText = "You can say hello to me!";
return getAskResponse("HelloWorld", speechText);
}
/**
* Helper method that creates a card object.
* #param title title of the card
* #param content body of the card
* #return SimpleCard the display card to be sent along with the voice response.
*/
private SimpleCard getSimpleCard(String title, String content) {
SimpleCard card = new SimpleCard();
card.setTitle(title);
card.setContent(content);
return card;
}
/**
* Helper method for retrieving an OutputSpeech object when given a string of TTS.
* #param speechText the text that should be spoken out to the user.
* #return an instance of SpeechOutput.
*/
private PlainTextOutputSpeech getPlainTextOutputSpeech(String speechText) {
PlainTextOutputSpeech speech = new PlainTextOutputSpeech();
speech.setText(speechText);
return speech;
}
/**
* Helper method that returns a reprompt object. This is used in Ask responses where you want
* the user to be able to respond to your speech.
* #param outputSpeech The OutputSpeech object that will be said once and repeated if necessary.
* #return Reprompt instance.
*/
private Reprompt getReprompt(OutputSpeech outputSpeech) {
Reprompt reprompt = new Reprompt();
reprompt.setOutputSpeech(outputSpeech);
return reprompt;
}
/**
* Helper method for retrieving an Ask response with a simple card and reprompt included.
* #param cardTitle Title of the card that you want displayed.
* #param speechText speech text that will be spoken to the user.
* #return the resulting card and speech text.
*/
private SpeechletResponse getAskResponse(String cardTitle, String speechText) {
SimpleCard card = getSimpleCard(cardTitle, speechText);
PlainTextOutputSpeech speech = getPlainTextOutputSpeech(speechText);
Reprompt reprompt = getReprompt(speech);
return SpeechletResponse.newAskResponse(speech, reprompt, card);
}
}
Application class
package com.vocabBrawlAlexa;
#SpringBootApplication
#ServletComponentScan
#ComponentScan("com.vocabBrawlAlexa")
public class VocabBrawlAlexaApplication {
private static final Logger LOGGER = LogManager.getLogger(VocabBrawlAlexaApplication.class.getName());
public static void main(String[] args) {
LOGGER.info("Info Message Logged !!!");
//setAmazonProperties();
LOGGER.info("Info Message Logged asdfsa !!!");
setAmazonProperties();
SpringApplication.run(VocabBrawlAlexaApplication.class, args);
}
/**
* Sets system properties which are picked up by the {#link SpeechletServlet}.
*/
private static void setAmazonProperties() {
// Disable signature checks for development
LOGGER.info("Info Message Logged setAmazonProperties !!!");
System.setProperty(Sdk.DISABLE_REQUEST_SIGNATURE_CHECK_SYSTEM_PROPERTY, "true");
// Allow all application ids for development
System.setProperty(Sdk.SUPPORTED_APPLICATION_IDS_SYSTEM_PROPERTY, "amzn1.ask.skill.1672b699-610a-42b6-83cb-0a4e7c9f5ccf");
// Disable timestamp verification for development
System.setProperty(Sdk.TIMESTAMP_TOLERANCE_SYSTEM_PROPERTY, "1500");
}
}
Update :
I have removed the default constructor as per the suggestion. PFB the changed servlet code
#WebServlet("/hello")
public class HelloWorldServlet extends SpeechletServlet {
private static final Logger LOGGER = LogManager.getLogger(HelloWorldServlet.class.getName());
/**
*
*/
private static final long serialVersionUID = -8294485619021129263L;
private VocabBrawlSpeechlet vocabBrawlSpeechlet;
#Autowired
public HelloWorldServlet(VocabBrawlSpeechlet vocabBrawlSpeechlet) {
LOGGER.debug("Autowiring vocabBrawlSpeechlet");
this.vocabBrawlSpeechlet = vocabBrawlSpeechlet;
this.setSpeechlet(this.vocabBrawlSpeechlet);
}
}
During the first hit, I got 500 exception after that I am getting 404
java.lang.InstantiationException: com.vocabBrawlAlexa.HelloWorldServlet
java.lang.Class.newInstance(Class.java:368)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:200)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:622)
java.lang.Thread.run(Thread.java:748)
I am using JLayer to stream online radio music so a simple code for this is here:(Where StreamPlayer is a special implementation of JLayer)
//Radio Station URL example is http://radio.flex.ru:8000/radionami
/**
* Plays the Given Online Stream
*
* #param url
* <b> The Specified url you want to connect </b>
* #throws IOException
* #throws JavaLayerException
*/
public void playRadioStream(URL spec) {
try {
// Connection
URLConnection urlConnection = spec.openConnection();
// Connecting
urlConnection.connect();
// Try to play it
StreamPlayer player = new StreamPlayer();
player.open((urlConnection.getInputStream()));
player.play();
} catch (StreamPlayerException | IOException e) {
e.printStackTrace();
}
}
The problem:
I can't figure out how to retrieve information from this connection like the song is playing now from this Radio Station or the name of Station etc...The help is really appreciated!!
Edit:
If you want you can use JLayer instead of StreamPlayer it will work ,although you have to run it on different Thread from the main app Thread.
Hello all i wrote an application grabbing photos from facebook. I did that successfully. Now i wrote a notification service using SNS in java. Basically sending out subscription for first time users who log into my application and also when a pictured has been deleted from the repository. My first problem is when i download the pics and user info from facebook, i want to check if its a new user or not. If a new user send out a subscription and if not(basically user exist in mongoDb dont send out email for subscription) but my code keeps sending out email to everyuser. And lastly when a user deletes a photo they get a notification but when i tested it i failed to get an email. Below is my code could someone tell me what im doing wrong.
public class EmailNotifications {
private static final String accessKey = "****************";
private static final String secretAccess ="***********************";
//Notification when user gets info from facebook app for first time.
public static void SignUP(String email, String Topic){
AmazonSNSClient snsClient = new AmazonSNSClient(new BasicAWSCredentials(accessKey, secretAccess));
snsClient.setRegion(Region.getRegion(Regions.US_WEST_1));
//create a Topic
CreateTopicRequest createTopicRequest = new CreateTopicRequest().withName(Topic);
CreateTopicResult createTopicResult = snsClient.createTopic(createTopicRequest);
//subscribes to a topic
SubscribeRequest subscribeRequest = new SubscribeRequest().withTopicArn(createTopicResult.getTopicArn())
.withProtocol("email").withEndpoint(email);
snsClient.subscribe(subscribeRequest);
}
//Notification when photo is deleted
public static void deletePic(String email, String topic, String message){
AmazonSNSClient snsClient = new AmazonSNSClient(new BasicAWSCredentials(accessKey,secretAccess));
snsClient.setRegion(Region.getRegion(Regions.US_WEST_1));
CreateTopicRequest create = new CreateTopicRequest(topic);
CreateTopicResult result = snsClient.createTopic(create);
System.out.println(result);
//String msg = "My text published to SNS topic with email endpoint";
PublishRequest publishRequest = new PublishRequest(result.getTopicArn(), message);
publishRequest.setSubject("Deleted Pic");
/*PublishResult pu= */snsClient.publish(publishRequest);
}
}
Below is my implementation of both delete and grabbing data for first assuming mongodb is empty:
Delete photo implementation:
#Override
//deletes photo from mongoDB... but doesn't send out an email stating phootid
public String deletePhoto(String id, String PhotoId){
String mssg="";
if(accountRepo.exists(id)){
UserAccounts userAccounts=accountRepo.findById(id);
UserPhotos photos = photoRepo.findByPhotoId(PhotoId);
mssg="The picture "+photos.getPhotoId()+" has been deleted from the application";
EmailNotifications.deletePic(userAccounts.getEmail(),topic,mssg);
photoRepo.delete(PhotoId);
return "Photo is deleted";
}
else
return "Photo does not exist";
}
Grabbing photo from face for the first time. The user should get only one notification max. But i keep getting several messages.
#Override
public UserAccounts create(FacebookClient facebookClient){
User me = facebookClient.fetchObject("me", User.class);
UserAccounts userAccounts = new UserAccounts();
userAccounts.setEmail(me.getEmail());
userAccounts.setGender(me.getGender());
userAccounts.setId(me.getId());
userAccounts.setName(me.getName());
accountRepo.save(userAccounts);
EmailNotifications.SignUP(me.getEmail(), topic);
return userAccounts;
}
Could some one assist me on this
Judging by your description and the code, it would guess the email you keep getting when you download for a user is the subscription confirmation email because all EmailNotifications.SignUp does is subscribe the email address.
I would guess that the reason you haven't getting any email when you delete a picture is because you haven't confirmed the subscription. In the subscription confirmation emails, there should be a link you can click on to confirm the subscription.
As for why you keep getting the email every time you download, I can't tell from your code, but in the create method you show there is not if block around calling SignUp to check if the user already existed, which I imagine is your problem.
As an aside, if your application is interacting with users and you want a good email experience, you would probably be better off using SES, which allows you to completely control the formatting and branding of your email.
I was trying to use http://www.androidbootstrap.com/ to bootstrap a new Android application. It creates a project with Otto, Dagger, Butterknife, Retrofit, and some other nifty stuff while also creating sample code on how to use it. It's really useful, as it sets up the annotation processing and everything in the Gradle build files for Android Studio to import it easily, it's really neat.
However, I'm at a loss with the login screen.
/**
* This method gets called when the
* methods gets invoked.
* This happens on a different process, so debugging it can be a beast.
*
* #param response
* #param account
* #param authTokenType
* #param options
* #return
* #throws NetworkErrorException
*/
#Override
public Bundle getAuthToken(final AccountAuthenticatorResponse response,
final Account account, final String authTokenType,
final Bundle options) throws NetworkErrorException {
Ln.d("Attempting to get authToken");
final String authToken = AccountManager.get(context).peekAuthToken(account, authTokenType);
final Bundle bundle = new Bundle();
bundle.putString(KEY_ACCOUNT_NAME, account.name);
bundle.putString(KEY_ACCOUNT_TYPE, Constants.Auth.BOOTSTRAP_ACCOUNT_TYPE);
bundle.putString(KEY_AUTHTOKEN, authToken);
return bundle;
}
#Override
public String getAuthTokenLabel(final String authTokenType) {
return authTokenType.equals(Constants.Auth.AUTHTOKEN_TYPE) ? authTokenType : null;
}
#Override
public Bundle hasFeatures(final AccountAuthenticatorResponse response, final Account account,
final String[] features) throws NetworkErrorException {
final Bundle result = new Bundle();
result.putBoolean(KEY_BOOLEAN_RESULT, false);
return result;
}
#Override
public Bundle updateCredentials(final AccountAuthenticatorResponse response,
final Account account, final String authTokenType,
final Bundle options) {
return null;
}
}
I cannot authenticate it and actually "log in".
So my questions are the following:
What is this authenticator authenticating against? The android device account, or Parse.com, or something completely different?
How exactly does this authenticator work? Is there a guide somewhere that explains how this should be done (note, on the AndroidBootstrap website, there isn't, and the video guide is outdated) if it weren't for the Bootstrap? To me this looks like a giant mess with random Services (like AccountAuthenticatorService), an AbstractAccountAuthenticator... and while I'm sure it's good for something, it looks needlessly overcomplicated, and I don't understand what is happening.
As written on https://github.com/AndroidBootstrap/android-bootstrap - the login credentials are
username: demo#androidbootstrap.com
password: android
It authenticates you against Parse.com as that is what it is set up against as a demo.
This is using an account authenticator which was added in Android v2.0, and adds the account to the Accounts in Android.
More information is available here:
http://udinic.wordpress.com/2013/04/24/write-your-own-android-authenticator/
http://www.jiahaoliuliu.com/2012/05/android-account-manager-part-i.html
http://www.c99.org/2010/01/23/writing-an-android-sync-provider-part-1/
Everything in the code seems fine. I do not understand why it is giving me this error.
Using Eclipse IDE (Juno), I've clicked "Run" and got the following message on the console:
Error: Could not find or load main class JavaFixHistoryMiner
This was an imported file, I also added an external library
/**
* Example of how to request and process historical rate data from the Java API
*
* #author rkichenama
*/
public class JavaFixHistoryMiner
implements IGenericMessageListener, IStatusMessageListener
{
private static final String server = "http://www.fxcorporate.com/Hosts.jsp";
private static final String TEST_CURRENCY = "EUR/USD";
private FXCMLoginProperties login;
private IGateway gateway;
private String currentRequest;
private boolean requestComplete;
private ArrayList<CollateralReport> accounts = new ArrayList<CollateralReport>();
private HashMap<UTCDate, MarketDataSnapshot> historicalRates = new HashMap<UTCDate, MarketDataSnapshot>();
private static PrintWriter output = new PrintWriter((OutputStream)System.out, true);
public PrintWriter getOutput() { return output; }
public void setOutput(PrintWriter newOutput) { output = newOutput; }
/**
* Creates a new JavaFixHistoryMiner with credentials with configuration file
*
* #param username
* #param password
* #param terminal - which terminal to login into, dependent on the type of account, case sensitive
* #param server - url, like 'http://www.fxcorporate.com/Hosts.jsp'
* #param file - a local file used to define configuration
*/
public JavaFixHistoryMiner(String username, String password, String terminal, String file)
{
// if file is not specified
if(file == null)
// create a local LoginProperty
this.login = new FXCMLoginProperties(username, password, terminal, server);
else
this.login = new FXCMLoginProperties(username, password, terminal, server, file);
}
/**
* Creates a new JavaFixHistoryMiner with credentials and no configuration file
*
* #param username
* #param password
* #param terminal - which terminal to login into, dependent on the type of account, case sensitive
* #param server - url, like 'http://www.fxcorporate.com/Hosts.jsp'
*/
public JavaFixHistoryMiner(String username, String password, String terminal)
{
// call the proper constructor
this(username, password, terminal, null);
}
public JavaFixHistoryMiner(String[] args)
{
// call the proper constructor
this(args[0], args[1], args[2], null);
}
/**
* Attempt to login with credentials supplied in constructor, assigning self as listeners
*/
public boolean login()
{
return this.login(this, this);
}
/**
* Attempt to login with credentials supplied in constructor
*
* #param genericMessageListener - the listener object for trading events
* #param statusMessageListener - the listener object for status events
*
* #return true if login successful, false if not
*/
public boolean login(IGenericMessageListener genericMessageListener, IStatusMessageListener statusMessageListener)
{
try
{
// if the gateway has not been defined
if(gateway == null)
// assign it to a new gateway created by the factory
gateway = GatewayFactory.createGateway();
// register the generic message listener with the gateway
gateway.registerGenericMessageListener(genericMessageListener);
// register the status message listener with the gateway
gateway.registerStatusMessageListener(statusMessageListener);
// if the gateway has not been connected
if(!gateway.isConnected())
{
// attempt to login with the local login properties
gateway.login(this.login);
}
else
{
// attempt to re-login to the api
gateway.relogin();
}
// set the state of the request to be incomplete
requestComplete = false;
// request the current trading session status
currentRequest = gateway.requestTradingSessionStatus();
// wait until the request is complete
while(!requestComplete) {}
// return that this process was successful
return true;
}
catch(Exception e) { e.printStackTrace(); }
// if any error occurred, then return that this process failed
return false;
}
/**
* Attempt to logout, assuming that the supplied listeners reference self
*/
public void logout()
{
this.logout(this, this);
}
/**
* Attempt to logout, removing the supplied listeners prior to disconnection
*
* #param genericMessageListener - the listener object for trading events
* #param statusMessageListener - the listener object for status events
*/
public void logout(IGenericMessageListener genericMessageListener, IStatusMessageListener statusMessageListener)
{
// attempt to logout of the api
gateway.logout();
// remove the generic message listener, stop listening to updates
gateway.removeGenericMessageListener(genericMessageListener);
// remove the status message listener, stop listening to status changes
gateway.removeStatusMessageListener(statusMessageListener);
}
/**
* Request a refresh of the collateral reports under the current login
*/
public void retrieveAccounts()
{
// if the gateway is null then attempt to login
if(gateway == null) this.login();
// set the state of the request to be incomplete
requestComplete = false;
// request the refresh of all collateral reports
currentRequest = gateway.requestAccounts();
// wait until all the reqports have been processed
while(!requestComplete) {}
}
/**
* Send a fully formed order to the API and wait for the response.
*
* #return the market order number of placed trade, NONE if the trade did not execute, null on error
*/
public String sendRequest(ITransportable request)
{
try
{
// set the completion status of the requst to false
requestComplete = false;
// send the request message to the api
currentRequest = gateway.sendMessage(request);
// wait until the api answers on this particular request
// while(!requestComplete) {}
// if there is a value to return, it will be passed by currentResult
return currentRequest;
}
catch(Exception e) { e.printStackTrace(); }
// if an error occured, return no result
return null;
}
/**
* Implementing IStatusMessageListener to capture and process messages sent back from API
*
* #param status - status message received by API
*/
#Override public void messageArrived(ISessionStatus status)
{
// check to the status code
if(status.getStatusCode() == ISessionStatus.STATUSCODE_ERROR ||
status.getStatusCode() == ISessionStatus.STATUSCODE_DISCONNECTING ||
status.getStatusCode() == ISessionStatus.STATUSCODE_CONNECTING ||
status.getStatusCode() == ISessionStatus.STATUSCODE_CONNECTED ||
status.getStatusCode() == ISessionStatus.STATUSCODE_CRITICAL_ERROR ||
status.getStatusCode() == ISessionStatus.STATUSCODE_EXPIRED ||
status.getStatusCode() == ISessionStatus.STATUSCODE_LOGGINGIN ||
status.getStatusCode() == ISessionStatus.STATUSCODE_LOGGEDIN ||
status.getStatusCode() == ISessionStatus.STATUSCODE_PROCESSING ||
status.getStatusCode() == ISessionStatus.STATUSCODE_DISCONNECTED)
{
// display status message
output.println("\t\t" + status.getStatusMessage());
}
}
/**
* Implementing IGenericMessageListener to capture and process messages sent back from API
*
* #param message - message received for processing by API
*/
#Override public void messageArrived(ITransportable message)
{
// decide which child function to send an cast instance of the message
try
{
// if it is an instance of CollateralReport, process the collateral report
if(message instanceof CollateralReport) messageArrived((CollateralReport)message);
// if it is an instance of MarketDataSnapshot, process the historical data
if(message instanceof MarketDataSnapshot) messageArrived((MarketDataSnapshot)message);
// if it is an instance of MarketDataRequestReject, process the historical data request error
if(message instanceof MarketDataRequestReject) messageArrived((MarketDataRequestReject)message);
// if the message is an instance of TradingSessionStatus, cast it and send to child function
else if(message instanceof TradingSessionStatus) messageArrived((TradingSessionStatus)message);
}
catch(Exception e) { e.printStackTrace(output); }
}
/**
* Separate function to handle collateral report requests
*
* #param cr - message interpreted as an instance of CollateralReport
*/
public void messageArrived(CollateralReport cr)
{
// if this report is the result of a direct request by a waiting process
if(currentRequest.equals(cr.getRequestID()) && !accounts.contains(cr))
{
// add the trading account to the account list
accounts.add(cr);
// set the state of the request to be completed only if this is the last collateral report
// requested
requestComplete = cr.isLastRptRequested();
}
}
/**
/**
* Separate function to handle the trading session status updates and pull the trading instruments
*
* #param tss - the message interpreted as a TradingSessionStatus instance
*/
public void messageArrived(TradingSessionStatus tss)
{
// check to see if there is a request from main application for a session update
if(currentRequest.equals(tss.getRequestID()))
{
// set that the request is complete for any waiting thread
requestComplete = true;
// attempt to set up the historical market data request
try
{
// create a new market data request
MarketDataRequest mdr = new MarketDataRequest();
// set the subscription type to ask for only a snapshot of the history
mdr.setSubscriptionRequestType(SubscriptionRequestTypeFactory.SNAPSHOT);
// request the response to be formated FXCM style
mdr.setResponseFormat(IFixDefs.MSGTYPE_FXCMRESPONSE);
// set the intervale of the data candles
mdr.setFXCMTimingInterval(FXCMTimingIntervalFactory.MIN15);
// set the type set for the data candles
mdr.setMDEntryTypeSet(MarketDataRequest.MDENTRYTYPESET_ALL);
// configure the start and end dates
Date now = new Date();
Calendar calendar = (Calendar)Calendar.getInstance().clone();
calendar.setTime(now);
calendar.add(Calendar.DAY_OF_MONTH, -1);
Date beforeNow = calendar.getTime();
// set the dates and times for the market data request
mdr.setFXCMStartDate(new UTCDate(beforeNow));
mdr.setFXCMStartTime(new UTCTimeOnly(beforeNow));
mdr.setFXCMEndDate(new UTCDate(now));
mdr.setFXCMEndTime(new UTCTimeOnly(now));
// set the instrument on which the we want the historical data
mdr.addRelatedSymbol(tss.getSecurity(TEST_CURRENCY));
// send the request
sendRequest(mdr);
}
catch(Exception e) { e.printStackTrace(); }
}
}
/**
* Separate function to handle the rejection of a market data historical snapshot
*
* #param mdrr - message interpreted as an instance of MarketDataRequestReject
*/
public void messageArrived(MarketDataRequestReject mdrr)
{
// display note consisting of the reason the request was rejected
output.println("Historical data rejected; " + mdrr.getMDReqRejReason());
// set the state of the request to be complete
requestComplete = true;
}
/**
* Separate function to handle the receipt of market data snapshots
*
* Current dealing rates are retrieved through the same class as historical requests. The difference
* is that historical requests are 'answers' to a specific request.
*
* #param mds
*/
public void messageArrived(MarketDataSnapshot mds)
{
// if the market data snapshot is part of the answer to a specific request
try
{
if(mds.getRequestID() != null && mds.getRequestID().equals(currentRequest))
{
// add that snapshot to the historicalRates table
synchronized(historicalRates) { historicalRates.put(mds.getDate(), mds); }
// set the request to be complete only if the continuous flaf is at the end
requestComplete = (mds.getFXCMContinuousFlag() == IFixDefs.FXCMCONTINUOUS_END);
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Display the historical rates captured
*/
public void displayHistory()
{
// give the table a header
output.println("Rate 15 minute candle History for " + TEST_CURRENCY);
// give the table column headings
output.println("Date\t Time\t\tOBid\tCBid\tHBid\tLBid");
// get the keys for the historicalRates table into a sorted list
SortedSet<UTCDate> candle = new TreeSet<UTCDate>(historicalRates.keySet());
// define a format for the dates
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss z");
// make the date formatter above convert from GMT to EST
sdf.setTimeZone(TimeZone.getTimeZone("EST"));
// go through the keys of the historicalRates table
for(int i = 0; i < candle.size(); i++)
{
// create a single instance of the snapshot
MarketDataSnapshot candleData;
synchronized(historicalRates) { candleData = historicalRates.get(candle.toArray()[i]); }
// convert the key to a Date
Date candleDate = ((UTCDate)candle.toArray()[i]).toDate();
// print out the historicalRate table data
output.println(
sdf.format(candleDate) + "\t" + // the date and time formatted and converted to EST
candleData.getBidOpen() + "\t" + // the open bid for the candle
candleData.getBidClose() + "\t" + // the close bid for the candle
candleData.getBidHigh() + "\t" + // the high bid for the candle
candleData.getBidLow()); // the low bid for the candle
}
// repeat the table column headings
output.println("Date\t Time\t\tOBid\tCBid\tHBid\tLBid");
}
public static void main(String[] args)
{
try
{
// create an instance of the JavaFixHistoryMiner
JavaFixHistoryMiner miner = new JavaFixHistoryMiner("rkichenama", "1311016", "Demo");
// login to the api
miner.login();
// retrieve the trader accounts to ensure login process is complete
miner.retrieveAccounts();
// display nore that the history display is delayed
// partially for theatrics, partially to ensure all the rates are collected
output.println("Displaying history in");
// wait ~ 2.5 seconds
for(int i = 5; i > 0; i--)
{
output.println(i + "...");
Thread.sleep(500);
}
// display the collected rates
miner.displayHistory();
// log out of the api
miner.logout();
}
catch (Exception e) { e.printStackTrace(); }
}
}