Using Multiple Twitter Accounts

First Time Poster so hopefully this is the correct place to ask.

I have a project which monitors a cottage and tweets the status.
I have several twitter tokens and want to post different things to different twitter accounts depend on what the message is.

I thought it would be a case of redefining the twitter account
Twitter twitter("TwitterToken1"); //General Weather tweets

So when I want to send to a different account I assumed I could just redefine

Twitter twitter("TwitterToken2"); //Emergency Tweets
Serial.println("connecting ...");
if (twitter.post(buffer)) {
// Specify &Serial to output received response to Serial.
// If no output is required, you can just omit the argument, e.g.
// int status = twitter.wait();
int status = twitter.wait(&Serial);
if (status == 200) {
Serial.println("OK.");

But this doesn't work it just uses the original token from the beginning of the program.
Is the token hard coded at runtime or am I missing something?

Rob

I'm surprised the compiler let you have two global variables both called 'twitter'.

Perhaps it would make more sense if you posted all of your code.

I finally found the time to look at this again and would like some advice on

I have several twitter tokens and would like to post different things from different accounts depending what is happening at my cottage.
Looking at the twitter.h it shows
Twitter(const char *user_and_passwd);
So I assume I can not redefine the twitter token as it's a const char?
(sorry i'm new to this)

But having played I can redefine the token if I use the demo code and just add the line before it send its twitter message

#include <SPI.h> // needed in Arduino 0019 or later
#include <Ethernet.h>
#include <Twitter.h>

// The includion of EthernetDNS is not needed in Arduino IDE 1.0 or later.
// Please uncomment below in Arduino IDE 0022 or earlier.
//#include <EthernetDNS.h>

// Ethernet Shield Settings
//byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// If you don't specify the IP address, DHCP is used(only in Arduino 1.0 or later).
//byte ip[] = { 192, 168, 1, 150 };
byte mac[] = { 0x00, 0x11, 0x22, 0x33, 0xFB, 0x11 }; // Use your MAC address
byte ip[] = { 192, 168, 1, 80 }; // no DHCP so we set our own IP address
byte subnet[] = { 255, 255, 255, 0 }; // subnet mask
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router

// Your Token to Tweet (get it from http://arduino-tweet.appspot.com/)
Twitter twitter("Insert your own token here"); // my first twitter token here

// Message to post
char msg[] = "Hello, World! I'm Arduino! @r4rob";

void setup()
{
delay(1000);
Ethernet.begin(mac, ip);
// or you can use DHCP for autoomatic IP address configuration.
// Ethernet.begin(mac);
Serial.begin(9600);

Serial.println("connecting ...");
Twitter twitter("Insert your own token here"); // my second twitter token here seems to work ok
if (twitter.post(msg)) {
// Specify &Serial to output received response to Serial.
// If no output is required, you can just omit the argument, e.g.
// int status = twitter.wait();
int status = twitter.wait(&Serial);
if (status == 200) {
Serial.println("OK.");
} else {
Serial.print("failed : code ");
Serial.println(status);
}
} else {
Serial.println("connection failed.");

}
}

void loop()
{
}

However as soon at I try and be clever and put the tokens inside some if statements it doesn't work
Also is there anyway to print the twitter token so I can play without actually posting

Here is my test code which returned "no token defined" from Google and also the value of account changes.
Sorry if this is basic stuff but i'm managed to make a simple weather station which works well
https://twitter.com/RiceLakeWeather
But I'm at the limit of my knowledge.

Here is my other test code

#include <SPI.h> // needed in Arduino 0019 or later
#include <Ethernet.h>
#include <Twitter.h>

// The includion of EthernetDNS is not needed in Arduino IDE 1.0 or later.
// Please uncomment below in Arduino IDE 0022 or earlier.
//#include <EthernetDNS.h>

// Ethernet Shield Settings
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// If you don't specify the IP address, DHCP is used(only in Arduino 1.0 or later).
byte ip[] = { 192, 168, 1, 177 };

// Your Token to Tweet (get it from http://arduino-tweet.appspot.com/)

Twitter twitter(""); // Empty Status token

int account ;

// Message to post
char msg[] = "Test message @r4rob ";

void setup()
{

delay(1000);
Ethernet.begin(mac, ip);
// or you can use DHCP for automatic IP address configuration.
// Ethernet.begin(mac);
Serial.begin(9600);

}

void loop()
{
account =0;
Serial.println("connecting ...");
Serial.print("Account=");
Serial.println(account);

if (account = 0) {
char msg[] = "This should tweet from first Account @r4rob ";
Twitter twitter("my first token"); // My 1st twitter account
Serial.print("Tweeting Using 0 =");
Serial.println(account);
};

if (account = 1) {
char msg[] = "This should tweet from second Account @r4rob ";
Twitter twitter("my second token"); // My 2nd twitter account
Serial.print("Tweeting Using1=");
Serial.println(account);
};

if (twitter.post(msg)) {
// Specify &Serial to output received response to Serial.
// If no output is required, you can just omit the argument, e.g.
// int status = twitter.wait();
int status = twitter.wait(&Serial);
if (status == 200) {
Serial.println("OK.");
} else {
Serial.print("failed : code ");
Serial.println(status);
}
} else {
Serial.println("connection failed.");
}
while(true);
}

The above code returns the following which confuses me as I don't understand how the value of account changes!

Account=0
Tweeting Using1=1
HTTP/1.0 403 Forbidden
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache
Vary: Accept-Encoding
Date: Thu, 18 Oct 2012 11:18:57 GMT
Server: Google Frontend

Error 403 - token is not specifiedfailed : code 403

Thanks to anyone who takes the time to post.

Rob

The twitter variable is an instance of the Twitter class, that is bound to a particular ID and password.

There is nothing stopping you from creating multiple instances of the Twitter class, is there?

Twitter twitOne(user1, pass1);
Twitter twitTwo(user2, pass2);

if(twitOne.post(messageForTwit1))
{
    int status = twitOne.wait(&Serial);
    if (status == 200)
    {
      Serial.println("OK.");
    }
    else
    {
      Serial.print("failed : code ");
      Serial.println(status);
    }
}
else
{
    Serial.println("connection failed.");
}

Send a different twit to twitTwo.

Paul

Thanks for the reply.

I don't know enough about the language to understand fully but i will go and have a play.

I thought I couldn't change variables inside a library as some of the variables would be local rather than global?

I assume the line Twitter::Twitter(const char *token) : token(token) is what i need to poke around with but I get confused as to what Twitter::Twitter means, does this mean it references the VAR called Twitter in the Libary called Twitter?

And does the *token have to be a const?

And is there anyway I can serial print the token for debuging purposes?
Sorry for all the questions

/*
Twitter.cpp - Arduino library to Post messages to Twitter using OAuth.
Copyright (c) NeoCat 2010-2011. All right reserved.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/

// ver1.2 - Use <string.h>
// ver1.3 - Support IDE 1.0

#include <string.h>
#include "Twitter.h"

#define LIB_DOMAIN "arduino-tweet.appspot.com"

#if defined(ARDUINO) && ARDUINO < 100
static uint8_t server[] = {0,0,0,0}; // IP address of LIB_DOMAIN
Twitter::Twitter(const char *token) : client(server, 80), token(token)
{
}
#else
Twitter::Twitter(const char *token) : token(token)
{
}
#endif

bool Twitter::post(const char *msg)
{
#if defined(ARDUINO) && ARDUINO < 100
DNSError err = EthernetDNS.resolveHostName(LIB_DOMAIN, server);
if (err != DNSSuccess) {
return false;
}
#endif
parseStatus = 0;
statusCode = 0;
#if defined(ARDUINO) && ARDUINO < 100
if (client.connect()) {
#else
if (client.connect(LIB_DOMAIN, 80)) {
#endif
client.println("POST http://" LIB_DOMAIN "/update HTTP/1.0");
client.print("Content-Length: ");
client.println(strlen(msg)+strlen(token)+14);
client.println();
client.print("token=");
client.print(token);
client.print("&status=");
client.println(msg);
} else {
return false;
}
return true;
}

bool Twitter::checkStatus(Print *debug)
{
if (!client.connected()) {
if (debug)
while(client.available())
debug->print((char)client.read());
client.flush();
client.stop();
return false;
}
if (!client.available())
return true;
char c = client.read();
if (debug)
debug->print(c);
switch(parseStatus) {
case 0:
if (c == ' ') parseStatus++; break; // skip "HTTP/1.1 "
case 1:
if (c >= '0' && c <= '9') {
statusCode *= 10;
statusCode += c - '0';
} else {
parseStatus++;
}
}
return true;
}

int Twitter::wait(Print *debug)
{
while (checkStatus(debug));
return statusCode;
}

I thought I couldn't change variables inside a library as some of the variables would be local rather than global?

You don't need to, or want to, change the library. As near as I can tell, there is nothing in it to restrict you to a single instance of the class.

The definition of instances occurs in your sketch, not in the library.

but I get confused as to what Twitter::Twitter means

Twitter::Twitter() is the constructor for the Twitter class. It is the code that gets executed when you create an instance, like so:

Twitter twitOne(user1, pass1);
Twitter twitTwo(user2, pass2);

The Twitter::Twitter() would have been called to create twitOne and again to create twitTwo().

And does the *token have to be a const?

Yes. It means that the library is not going to (be able to) change it.

And is there anyway I can serial print the token for debuging purposes?

Of course. Just add whatever Serial.print() statements you want. You'll need to make sure that HardwareSerial.h is included, directly or indirectly. (Arduino.h includes HardwareSerial.h)

One way to share code between multiple Twitter objects is to use a pointer to a Twitter object, like this:

#include <SPI.h> // needed in Arduino 0019 or later
#include <Ethernet.h>
#include <Twitter.h>

// The includion of EthernetDNS is not needed in Arduino IDE 1.0 or later.
// Please uncomment below in Arduino IDE 0022 or earlier.
//#include <EthernetDNS.h>


// Ethernet Shield Settings
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// If you don't specify the IP address, DHCP is used(only in Arduino 1.0 or later).
byte ip[] = { 
  192, 168, 1, 177 };

// Your Token to Tweet (get it from http://arduino-tweet.appspot.com/)

Twitter twitterWithTokenOne("my first token");
Twitter twitterWithTokenTwo("my second token");

void setup()
{


  delay(1000);
  Ethernet.begin(mac, ip);
  // or you can use DHCP for automatic IP address configuration.
  // Ethernet.begin(mac);
  Serial.begin(9600);


}

void loop()
{
  Twitter *twitter;
  char *msg;

  for (int account = 0; account < 2; account++) {
    Serial.println("connecting ...");
    Serial.print("Account=");
    Serial.println(account);

    switch (account) {
    case 0: 
      msg = "This should tweet from first Account @r4rob ";
      twitter = &twitterWithTokenOne;
      Serial.print("Tweeting Using 0 =");
      Serial.println(account);
      break;

    case 1:
      msg = "This should tweet from second Account @r4rob ";
      twitter =  &twitterWithTokenTwo;
      Serial.print("Tweeting Using 1 =");
      Serial.println(account);  
      break;
    }


    if (twitter->post(msg)) {
      // Specify &Serial to output received response to Serial.
      // If no output is required, you can just omit the argument, e.g.
      // int status = twitter.wait();
      int status = twitter->wait(&Serial);
      if (status == 200) {
        Serial.println("OK.");
      } 
      else {
        Serial.print("failed : code ");
        Serial.println(status);
      }
    }
  }
  while(true);   // Wait here forever
}